示例#1
0
        public static PreProcessResult PreProcess(IActivityMonitor monitor, XElement e)
        {
            IReadOnlyList <ActivityMonitorSimpleCollector.Entry> errors = null;
            XElement result;

            using (monitor.CollectEntries(err => errors = err))
            {
                result = (XElement)RemoveRegionsAndResolveReusables(new Reusables(monitor, e)).Single();
            }
            return(new PreProcessResult(errors, result));
        }
示例#2
0
        bool GenerateSourceCodeFirstPass(IActivityMonitor monitor,
                                         ICSCodeGenerationContext codeGenContext,
                                         string?informationalVersion,
                                         List <MultiPassCodeGeneration> collector,
                                         IEnumerable <ICSCodeGenerator> aspectsGenerators)
        {
            Debug.Assert(EngineMap != null);
            Debug.Assert(codeGenContext.Assembly == _tempAssembly, "CodeGenerationContext mismatch.");
            try
            {
                Debug.Assert(_valueCollector != null);
                IReadOnlyList <ActivityMonitorSimpleCollector.Entry>?errorSummary = null;
                using (monitor.OpenInfo($"Generating source code (first pass) for: {codeGenContext.CurrentRun.ConfigurationGroup.Names}."))
                    using (monitor.CollectEntries(entries => errorSummary = entries))
                    {
                        using (monitor.OpenInfo("Registering direct properties as PostBuildProperties."))
                        {
                            foreach (MutableItem item in EngineMap.StObjs.OrderedStObjs)
                            {
                                item.RegisterRemainingDirectPropertiesAsPostBuildProperties(_valueCollector);
                            }
                        }

                        // Retrieves CK._g workspace.
                        var ws = _tempAssembly.Code;
                        // Gets the global name space and starts with the informational version (if any),
                        // and, once for all, basic namespaces that we always want available.
                        var global = ws.Global;

                        if (!string.IsNullOrWhiteSpace(informationalVersion))
                        {
                            global.BeforeNamespace.Append("[assembly:System.Reflection.AssemblyInformationalVersion(")
                            .AppendSourceString(informationalVersion)
                            .Append(")]")
                            .NewLine();
                        }

                        // Injects System.Reflection and setup assemblies into the
                        // workspace that will be used to generate source code.
                        ws.EnsureAssemblyReference(typeof(BindingFlags));
                        if (CKTypeResult.Assemblies.Count > 0)
                        {
                            ws.EnsureAssemblyReference(CKTypeResult.Assemblies);
                        }
                        else
                        {
                            ws.EnsureAssemblyReference(typeof(StObjContextRoot).Assembly);
                        }

                        // Injects, once for all, basic namespaces that we always want available into the global namespace.
                        global.GeneratedByComment().NewLine()
                        .EnsureUsing("CK.Core")
                        .EnsureUsing("System")
                        .EnsureUsing("System.Collections.Generic")
                        .EnsureUsing("System.Linq")
                        .EnsureUsing("System.Threading.Tasks")
                        .EnsureUsing("System.Text")
                        .EnsureUsing("System.Reflection");

                        global.Append("// We don't generate nullable enabled code and we disable all warnings.").NewLine()
                        .Append("#nullable disable").NewLine()
                        .Append("#pragma warning disable").NewLine();

                        // Generates the Signature attribute implementation.
                        var nsStObj = global.FindOrCreateNamespace("CK.StObj");
                        nsStObj
                        .Append("[AttributeUsage(AttributeTargets.Assembly)]").NewLine()
                        .Append(@"internal sealed class SignatureAttribute : Attribute")
                        .OpenBlock()
                        .Append("public SignatureAttribute( string s ) {}").NewLine()
                        .Append("public readonly static (SHA1Value Signature, IReadOnlyList<string> Names) V = ( SHA1Value.Parse( (string)typeof( SignatureAttribute ).Assembly.GetCustomAttributesData().First( a => a.AttributeType == typeof( SignatureAttribute ) ).ConstructorArguments[0].Value )").NewLine()
                        .Append(", ").AppendArray(EngineMap.Names).Append(" );")
                        .CloseBlock();

                        // Generates the StObjContextRoot implementation.
                        GenerateStObjContextRootSource(monitor, nsStObj, EngineMap.StObjs.OrderedStObjs);

                        // Calls all ICSCodeGenerator items.
                        foreach (var g in EngineMap.AllTypesAttributesCache.Values.SelectMany(attr => attr.GetAllCustomAttributes <ICSCodeGenerator>())
                                 .Concat(aspectsGenerators))
                        {
                            var second = MultiPassCodeGeneration.FirstPass(monitor, g, codeGenContext).SecondPass;
                            if (second != null)
                            {
                                collector.Add(second);
                            }
                        }

                        // Asks every ImplementableTypeInfo to generate their code.
                        // This step MUST always be done, even if CompileOption is None and GenerateSourceFiles is false
                        // since during this step, side effects MAY occur (this is typically the case of the first run where
                        // the "reality cache" is created).
                        foreach (var t in CKTypeResult.TypesToImplement)
                        {
                            t.RunFirstPass(monitor, codeGenContext, collector);
                        }
                    }
                if (errorSummary != null)
                {
                    using (monitor.OpenFatal($"{errorSummary.Count} error(s). Summary:"))
                    {
                        foreach (var e in errorSummary)
                        {
                            monitor.Trace($"{e.MaskedLevel} - {e.Text}");
                        }
                    }
                    return(false);
                }
                return(true);
            }
            catch (Exception ex)
            {
                monitor.Error("While generating final source code.", ex);
                return(false);
            }
        }