コード例 #1
0
        private static void Compile(CodeGenerationBuilder builder)
        {
            var compilerParameters = new CompilerParameters
            {
                GenerateExecutable = false,
                GenerateInMemory   = false,
                OutputAssembly     = CompositeGeneratedAssemblyPath,
                TempFiles          = new TempFileCollection(TempAssemblyFolderPath)
            };

            compilerParameters.ReferencedAssemblies.AddRangeIfNotContained(builder.AssemblyLocations.ToArray());
            compilerParameters.AddAssemblyLocationsFromBin();

            var codeCompileUnit = new CodeCompileUnit();

            codeCompileUnit.Namespaces.AddRange(builder.Namespaces.ToArray());

            for (var i = 0; i < NumberOfCompileRetries; i++)
            {
                var             compiler      = CSharpCodeProviderFactory.CreateCompiler();
                CompilerResults compileResult = compiler.CompileAssemblyFromDom(compilerParameters, codeCompileUnit);

                if (!compileResult.Errors.HasErrors)
                {
                    return;
                }

                if (i == NumberOfCompileRetries - 1)
                {
                    OutputSourceCodeOnError(compiler, codeCompileUnit);

                    var sb = new StringBuilder();
                    foreach (CompilerError compilerError in compileResult.Errors)
                    {
                        if (compilerError.IsWarning)
                        {
                            continue;
                        }

                        var entry = "Compile error: " + compilerError.ErrorNumber + "(" + compilerError.Line + ")" + ": " + compilerError.ErrorText.Replace("{", "{{").Replace("}", "}}");

                        Log.LogError(LogTitle, entry);

                        sb.AppendLine(entry);
                    }

                    throw new InvalidOperationException(sb.ToString());
                }
            }
        }
コード例 #2
0
        private static CompatibilityCheckResult CheckAgainstAppCode(DataTypeDescriptor dataTypeDescriptorToTest, bool includeDataTypeDescriptor)
        {
            var filesToCompile = GetAppCodeFiles().ToList();

            if (filesToCompile.Count == 0)
            {
                return(new CompatibilityCheckResult());
            }

            var csCompiler = CSharpCodeProviderFactory.CreateCompiler();

            var referencedAssemblies = new List <Assembly>();
            var codeTypeDeclarations = new Dictionary <string, List <CodeTypeDeclaration> >();

            foreach (var dataTypeDescriptor in DataMetaDataFacade.GeneratedTypeDataTypeDescriptors)
            {
                if (!includeDataTypeDescriptor && dataTypeDescriptor.DataTypeId == dataTypeDescriptorToTest.DataTypeId)
                {
                    continue;
                }

                var dataTypeDescriptorToUse = dataTypeDescriptor;

                if (includeDataTypeDescriptor && dataTypeDescriptor.DataTypeId == dataTypeDescriptorToTest.DataTypeId)
                {
                    dataTypeDescriptorToUse = dataTypeDescriptorToTest;
                }

                referencedAssemblies.AddRange(InterfaceCodeGenerator.GetReferencedAssemblies(dataTypeDescriptorToUse));

                var codeTypeDeclaration = InterfaceCodeGenerator.CreateCodeTypeDeclaration(dataTypeDescriptorToUse);
                if (!codeTypeDeclarations.TryGetValue(dataTypeDescriptorToUse.Namespace, out var declarations))
                {
                    declarations = new List <CodeTypeDeclaration>();

                    codeTypeDeclarations.Add(dataTypeDescriptorToUse.Namespace, declarations);
                }

                declarations.Add(codeTypeDeclaration);

                var tempFilePath = GetTempFileName(dataTypeDescriptorToUse);

                filesToCompile.Add(tempFilePath);

                using (var file = File.Create(tempFilePath))
                {
                    using (var sw = new StreamWriter(file))
                    {
                        var codeNamespace = new CodeNamespace(dataTypeDescriptorToUse.Namespace);

                        codeNamespace.Types.Add(codeTypeDeclaration);

                        csCompiler.GenerateCodeFromNamespace(codeNamespace, sw, new CodeGeneratorOptions());
                    }

                    var sb = new StringBuilder();
                    using (var sw = new StringWriter(sb))
                    {
                        csCompiler.GenerateCodeFromMember(codeTypeDeclaration, sw, new CodeGeneratorOptions());
                    }
                }
            }

            filesToCompile.Sort();

            var compilerParameters = new CompilerParameters
            {
                GenerateExecutable = false,
                GenerateInMemory   = true
            };

            compilerParameters.ReferencedAssemblies.AddRangeIfNotContained(referencedAssemblies.Select(f => f.Location).ToArray());
            compilerParameters.ReferencedAssemblies.AddRangeIfNotContained(CodeGenerationManager.CompiledAssemblies.Select(f => f.Location).ToArray());

            compilerParameters.AddLoadedAssemblies(false);
            compilerParameters.AddAssemblyLocationsFromBin();
            compilerParameters.AddCommonAssemblies();
            compilerParameters.RemoveGeneratedAssemblies();

            var codeCompileUnit = new CodeCompileUnit();

            foreach (var kvp in codeTypeDeclarations)
            {
                var codeNamespace = new CodeNamespace(kvp.Key);

                codeNamespace.Types.AddRange(kvp.Value.ToArray());
                codeCompileUnit.Namespaces.Add(codeNamespace);
            }

            var compiler      = CSharpCodeProviderFactory.CreateCompiler();
            var compileResult = compiler.CompileAssemblyFromFile(compilerParameters, filesToCompile.ToArray());

            if (!compileResult.Errors.HasErrors)
            {
                return(new CompatibilityCheckResult());
            }

            // Checking for a missing assembly error, if it is present, that means that App_Code check isn't applicable due to circular reference
            foreach (CompilerError error in compileResult.Errors)
            {
                if (error.ErrorNumber == "CS0012" && error.ErrorText.Contains("Composite.Generated"))
                {
                    return(new CompatibilityCheckResult());
                }
            }

            return(new CompatibilityCheckResult(compileResult));
        }
コード例 #3
0
        /// <summary>
        /// This method will compile the type defined in <paramref name="codeGenerationBuilder"/>
        /// and return the result types. These types exists in a temp assembly, that will be
        /// deleted when the app domain is terminated.
        /// </summary>
        /// <param name="codeGenerationBuilder"></param>
        /// <param name="verbose"></param>
        /// <returns></returns>
        public static IEnumerable <Type> CompileRuntimeTempTypes(CodeGenerationBuilder codeGenerationBuilder, bool verbose = true)
        {
            var t1 = Environment.TickCount;

            _compositeGeneratedCompiled = false; // When compiling a new type, Composite.Generated.dll should always be recompiled

            var compilerParameters = new CompilerParameters
            {
                GenerateExecutable = false,
                GenerateInMemory   = false,
                OutputAssembly     = Path.Combine(TempAssemblyFolderPath, Guid.NewGuid() + ".dll")
            };

            compilerParameters.ReferencedAssemblies.AddRangeIfNotContained(codeGenerationBuilder.AssemblyLocations.ToArray());
            compilerParameters.ReferencedAssemblies.AddRangeIfNotContained(_compiledAssemblies.Select(f => f.Location).ToArray());
            compilerParameters.AddAssemblyLocationsFromBin();

            var codeCompileUnit = new CodeCompileUnit();

            codeCompileUnit.Namespaces.AddRange(codeGenerationBuilder.Namespaces.ToArray());

            var compiler      = CSharpCodeProviderFactory.CreateCompiler();
            var compileResult = compiler.CompileAssemblyFromDom(compilerParameters, codeCompileUnit);

            if (!compileResult.Errors.HasErrors)
            {
                var resultAssembly = compileResult.CompiledAssembly;

                AddCompiledAssembly(resultAssembly);

                var resultTypes = resultAssembly.GetTypes();

                var t2 = Environment.TickCount;

                Log.LogVerbose(LogTitle, $"Compile '{codeGenerationBuilder.DebugLabel}' in {t2 - t1}ms");
                Log.LogVerbose(LogTitle, $"Types from : {compilerParameters.OutputAssembly}");

                foreach (var resultType in resultTypes)
                {
                    _compiledTypesByFullName[resultType.FullName] = resultType;
                }

                return(resultTypes);
            }

            OutputSourceCodeOnError(compiler, codeCompileUnit);

            var failedAssemblyLoads = LoadAssembliesToMemory(compilerParameters.ReferencedAssemblies);

            var sb = new StringBuilder();

            failedAssemblyLoads.ForEach(asm => sb.AppendFormat("Failed to load dll: '{0}' : {1}", asm.First, asm.Second).AppendLine());

            sb.AppendLine("Failed building: " + codeGenerationBuilder.DebugLabel);
            foreach (CompilerError compilerError in compileResult.Errors)
            {
                if (compilerError.IsWarning)
                {
                    continue;
                }

                var entry = "Compile error: " + compilerError.ErrorNumber + "(" + compilerError.Line + ")" + ": " + compilerError.ErrorText.Replace("{", "{{").Replace("}", "}}");

                if (verbose)
                {
                    Log.LogError(LogTitle, entry);
                }

                sb.AppendLine(entry);
            }

            throw new InvalidOperationException(sb.ToString());
        }