Пример #1
0
        private EmitResult EmitResourceAssembly(
            AssemblyName assemblyName,
            IEnumerable <ResourceDescriptor> resourceDescriptors,
            CSharpCompilationOptions compilationOptions,
            Stream assemblyStream)
        {
            const string assemblyCultureName = "System.Reflection.AssemblyCultureAttribute";

            var resources = resourceDescriptors
                            .Select(res => new ResourceDescription(res.Name, res.StreamFactory, isPublic: true));

            // Force dll for projects that have emitEntryPoint = true
            compilationOptions = compilationOptions.WithOutputKind(OutputKind.DynamicallyLinkedLibrary);

            var compilation = CSharpCompilation.Create(
                assemblyName.Name,
                references: CompilationContext.Compilation.References,
                options: compilationOptions);

            if (!string.IsNullOrEmpty(assemblyName.CultureName))
            {
                compilation = compilation.AddSyntaxTrees(new[]
                {
                    CSharpSyntaxTree.ParseText($"[assembly:{assemblyCultureName}(\"{assemblyName.CultureName}\")]")
                });
            }

            Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name);

            var sw = Stopwatch.StartNew();

            var emitResult = compilation.Emit(
                assemblyStream,
                manifestResources: resources);

            sw.Stop();

            Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds);

            return(emitResult);
        }
Пример #2
0
        public HostBuildData Create(HostBuildOptions options)
        {
            var parseOptions = new CSharpParseOptions(languageVersion: LanguageVersion.CSharp6, documentationMode: DocumentationMode.Parse);
            var compilationOptions = new CSharpCompilationOptions(
                OutputKind.ConsoleApplication,
                xmlReferenceResolver: new XmlFileResolver(options.ProjectDirectory),
                sourceReferenceResolver: new SourceFileResolver(ImmutableArray<string>.Empty, options.ProjectDirectory),
                metadataReferenceResolver: new AssemblyReferenceResolver(
                    new MetadataFileReferenceResolver(ImmutableArray<string>.Empty, options.ProjectDirectory),
                    MetadataFileReferenceProvider.Default),
                strongNameProvider: new DesktopStrongNameProvider(ImmutableArray.Create(options.ProjectDirectory, options.OutputDirectory)),
                assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default);
            var warnings = new List<KeyValuePair<string, ReportDiagnostic>>(options.Warnings);

            if (options.OutputKind.HasValue)
            {
                var kind = options.OutputKind.Value;
                compilationOptions = compilationOptions.WithOutputKind(kind);
                if (compilationOptions.Platform == Platform.AnyCpu32BitPreferred &&
                    (kind == OutputKind.DynamicallyLinkedLibrary || kind == OutputKind.NetModule || kind == OutputKind.WindowsRuntimeMetadata))
                {
                    compilationOptions = compilationOptions.WithPlatform(Platform.AnyCpu);
                }
            }

            if (!string.IsNullOrEmpty(options.DefineConstants))
            {
                IEnumerable<Diagnostic> diagnostics;
                parseOptions = parseOptions.WithPreprocessorSymbols(CSharpCommandLineParser.ParseConditionalCompilationSymbols(options.DefineConstants, out diagnostics));
            }

            if (options.DocumentationFile != null)
            {
                parseOptions = parseOptions.WithDocumentationMode(!string.IsNullOrEmpty(options.DocumentationFile) ? DocumentationMode.Diagnose : DocumentationMode.Parse);
            }

            if (options.LanguageVersion != null)
            {
                var languageVersion = CompilationOptionsConversion.GetLanguageVersion(options.LanguageVersion);
                if (languageVersion.HasValue)
                {
                    parseOptions = parseOptions.WithLanguageVersion(languageVersion.Value);
                }
            }

            if (!string.IsNullOrEmpty(options.PlatformWith32BitPreference))
            {
                Platform platform;
                if (Enum.TryParse<Platform>(options.PlatformWith32BitPreference, true, out platform))
                {
                    if (platform == Platform.AnyCpu &&
                        compilationOptions.OutputKind != OutputKind.DynamicallyLinkedLibrary &&
                        compilationOptions.OutputKind != OutputKind.NetModule &&
                        compilationOptions.OutputKind != OutputKind.WindowsRuntimeMetadata)
                    {
                        platform = Platform.AnyCpu32BitPreferred;
                    }

                    compilationOptions = compilationOptions.WithPlatform(platform);
                }
            }

            if (options.AllowUnsafeBlocks.HasValue)
            {
                compilationOptions = compilationOptions.WithAllowUnsafe(options.AllowUnsafeBlocks.Value);
            }

            if (options.CheckForOverflowUnderflow.HasValue)
            {
                compilationOptions = compilationOptions.WithOverflowChecks(options.CheckForOverflowUnderflow.Value);
            }

            if (options.DelaySign != null)
            {
                bool delaySignExplicitlySet = options.DelaySign.Item1;
                bool delaySign = options.DelaySign.Item2;
                compilationOptions = compilationOptions.WithDelaySign(delaySignExplicitlySet ? delaySign : (bool?)null);
            }

            if (!string.IsNullOrEmpty(options.ApplicationConfiguration))
            {
                var appConfigPath = FileUtilities.ResolveRelativePath(options.ApplicationConfiguration, options.ProjectDirectory);
                try
                {
                    using (var appConfigStream = PortableShim.FileStream.Create(appConfigPath, PortableShim.FileMode.Open, PortableShim.FileAccess.Read))
                    {
                        compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream));
                    }
                }
                catch (Exception)
                {
                }
            }

            if (!string.IsNullOrEmpty(options.KeyContainer))
            {
                compilationOptions = compilationOptions.WithCryptoKeyContainer(options.KeyContainer);
            }

            if (!string.IsNullOrEmpty(options.KeyFile))
            {
                var fullPath = FileUtilities.ResolveRelativePath(options.KeyFile, options.ProjectDirectory);
                compilationOptions = compilationOptions.WithCryptoKeyFile(fullPath);
            }

            if (!string.IsNullOrEmpty(options.MainEntryPoint))
            {
                compilationOptions = compilationOptions.WithMainTypeName(options.MainEntryPoint);
            }

            if (!string.IsNullOrEmpty(options.ModuleAssemblyName))
            {
                compilationOptions = compilationOptions.WithModuleName(options.ModuleAssemblyName);
            }

            if (options.Optimize.HasValue)
            {
                compilationOptions = compilationOptions.WithOptimizationLevel(options.Optimize.Value ? OptimizationLevel.Release : OptimizationLevel.Debug);
            }

            if (!string.IsNullOrEmpty(options.Platform))
            {
                Platform plat;
                if (Enum.TryParse<Platform>(options.Platform, ignoreCase: true, result: out plat))
                {
                    compilationOptions = compilationOptions.WithPlatform(plat);
                }
            }

            // Get options from the ruleset file, if any.
            if (!string.IsNullOrEmpty(options.RuleSetFile))
            {
                var fullPath = FileUtilities.ResolveRelativePath(options.RuleSetFile, options.ProjectDirectory);

                Dictionary<string, ReportDiagnostic> specificDiagnosticOptions;
                var generalDiagnosticOption = RuleSet.GetDiagnosticOptionsFromRulesetFile(fullPath, out specificDiagnosticOptions);
                compilationOptions = compilationOptions.WithGeneralDiagnosticOption(generalDiagnosticOption);
                warnings.AddRange(specificDiagnosticOptions);
            }

            if (options.WarningsAsErrors.HasValue)
            {
                compilationOptions = compilationOptions.WithGeneralDiagnosticOption(options.WarningsAsErrors.Value ? ReportDiagnostic.Error : ReportDiagnostic.Default);
            }

            if (options.WarningLevel.HasValue)
            {
                compilationOptions = compilationOptions.WithWarningLevel(options.WarningLevel.Value);
            }

            compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(warnings);
            return new HostBuildData(
                parseOptions,
                compilationOptions);
        }
Пример #3
0
        private static (string outputFile, CSharpCompilationOptions compilationOptions, CSharpParseOptions parseOptions) ParseArguments(IEnumerable <string> args)
        {
            var arguments = new Dictionary <string, string>();

            var compilationOptions = new CSharpCompilationOptions(OutputKind.ConsoleApplication);

            compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);
            string outputFile = "";

            var specificDiagnosticOptions = new Dictionary <string, ReportDiagnostic>()
            {
                // Ensure that specific warnings about assembly references are always suppressed.
                { "CS1701", ReportDiagnostic.Suppress },
                { "CS1702", ReportDiagnostic.Suppress },
                { "CS1705", ReportDiagnostic.Suppress }
            };

            compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(specificDiagnosticOptions);

            var parseOptions = new CSharpParseOptions();

            foreach (var arg in args)
            {
                var argParts = arg.Split(':');

                var argument = argParts[0].Replace("+", "").Replace("/", "");
                var value    = "";

                if (argParts.Count() > 1)
                {
                    value = argParts[1];
                }

                switch (argument)
                {
                case "target":
                    compilationOptions = compilationOptions.WithOutputKind(ParseTarget(value));
                    break;

                case "unsafe":
                    compilationOptions = compilationOptions.WithAllowUnsafe(true);
                    break;

                case "nowarn":
                    var warnings = value.Split(',');

                    if (warnings.Count() > 0)
                    {
                        compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(warnings.Select(s => new KeyValuePair <string, ReportDiagnostic>(!s.StartsWith("CS") ? $"CS{s}" : s, ReportDiagnostic.Suppress)));
                    }
                    break;

                case "define":
                    var defines = value.Split(';');

                    if (defines.Count() > 0)
                    {
                        parseOptions = parseOptions.WithPreprocessorSymbols(defines);
                    }
                    break;

                case "optimize":
                    compilationOptions = compilationOptions.WithOptimizationLevel(OptimizationLevel.Release);
                    break;

                case "platform":
                    compilationOptions = compilationOptions.WithPlatform(ParsePlatform(value));
                    break;

                case "out":
                    outputFile = value;
                    break;
                }
            }

            return(outputFile, compilationOptions, parseOptions);
        }
Пример #4
0
        public LuaSyntaxGenerator(IEnumerable <SyntaxTree> syntaxTrees, IEnumerable <MetadataReference> references, CSharpCompilationOptions options, IEnumerable <string> metas, SettingInfo setting, string[] attributes)
        {
            CSharpCompilation compilation = CSharpCompilation.Create("_", syntaxTrees, references, options.WithOutputKind(OutputKind.DynamicallyLinkedLibrary));

            using (MemoryStream ms = new MemoryStream()) {
                EmitResult result = compilation.Emit(ms);
                if (!result.Success)
                {
                    var    errors  = result.Diagnostics.Where(i => i.Severity == DiagnosticSeverity.Error);
                    string message = string.Join("\n", errors);
                    throw new CompilationErrorException(message);
                }
            }
            compilation_    = compilation;
            XmlMetaProvider = new XmlMetaProvider(metas);
            Setting         = setting;
            if (attributes != null)
            {
                if (attributes.Length == 0)
                {
                    isExportAttributesAll_ = true;
                }
                else
                {
                    exportAttributes_ = new HashSet <string>(attributes);
                }
            }
            DoPretreatment();
        }
Пример #5
0
        private EmitResult EmitResourceAssembly(
            AssemblyName assemblyName,
            IEnumerable<ResourceDescriptor> resourceDescriptors,
            CSharpCompilationOptions compilationOptions,
            Stream assemblyStream)
        {
            const string assemblyCultureName = "System.Reflection.AssemblyCultureAttribute";

            var resources = resourceDescriptors
                .Select(res => new ResourceDescription(res.Name, res.StreamFactory, isPublic: true));

            // Force dll for projects that have emitEntryPoint = true
            compilationOptions = compilationOptions.WithOutputKind(OutputKind.DynamicallyLinkedLibrary);

            var compilation = CSharpCompilation.Create(
                assemblyName.Name,
                references: CompilationContext.Compilation.References,
                options: compilationOptions);

            if (!string.IsNullOrEmpty(assemblyName.CultureName))
            {
                compilation = compilation.AddSyntaxTrees(new[]
                    {
                        CSharpSyntaxTree.ParseText($"[assembly:{assemblyCultureName}(\"{assemblyName.CultureName}\")]")
                    });
            }

            Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name);

            var sw = Stopwatch.StartNew();

            var emitResult = compilation.Emit(
                    assemblyStream,
                    manifestResources: resources);

            sw.Stop();

            Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds);

            return emitResult;
        }
Пример #6
0
        /// <inheritdoc />
        protected override void Initialize(CSharpCompilation oldCompilation, CancellationToken _)
        {
            OptimizationLevel      compilationConfiguration = oldCompilation.Options.OptimizationLevel;
            DebugCometaryAttribute attribute = Attribute;

            if (compilationConfiguration == OptimizationLevel.Debug && !attribute.RunInDebug)
            {
                return;
            }
            if (compilationConfiguration == OptimizationLevel.Release && !attribute.RunInRelease)
            {
                return;
            }

            string typeName = attribute.MainClassName ?? DebugCometaryAttribute.DefaultMainClassName;

            if (Assembly.GetEntryAssembly().GetType(typeName) != null)
            {
                return;
            }

            CSharpCompilation EditCompilation(CSharpCompilation compilation, CancellationToken cancellationToken)
            {
                CSharpCompilationOptions options    = compilation.Options;
                CSharpCompilationOptions newOptions = options
                                                      .WithOutputKind(OutputKind.ConsoleApplication)
                                                      .WithMainTypeName(typeName);

                // - Make the compilation an application, allowing its execution.
                // - Redirect the entry point to the automatically generated class.
                compilation = compilation.WithOptions(newOptions);

                // Create the entry point:
                string errorFile = Path.GetTempFileName();

                CSharpSyntaxTree      generatedSyntaxTree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText(GetSourceText(attribute.DisplayEndOfCompilationMessage, errorFile), cancellationToken: cancellationToken);
                CompilationUnitSyntax generatedRoot       = generatedSyntaxTree.GetCompilationUnitRoot(cancellationToken);

                ClassDeclarationSyntax classSyntax         = (ClassDeclarationSyntax)generatedRoot.Members.Last();
                ClassDeclarationSyntax originalClassSyntax = classSyntax;

                // Edit the generated syntax's name, if needed.
                if (typeName != DebugCometaryAttribute.DefaultMainClassName)
                {
                    classSyntax = classSyntax.WithIdentifier(F.Identifier(typeName));
                }

                // Change the filename and arguments.
                SyntaxList <MemberDeclarationSyntax> members = classSyntax.Members;

                FieldDeclarationSyntax WithValue(FieldDeclarationSyntax node, string value)
                {
                    VariableDeclaratorSyntax variableSyntax = node.Declaration.Variables[0];
                    LiteralExpressionSyntax  valueSyntax    = F.LiteralExpression(
                        SyntaxKind.StringLiteralExpression,
                        F.Literal(value)
                        );

                    return(node.WithDeclaration(
                               node.Declaration.WithVariables(node.Declaration.Variables.Replace(
                                                                  variableSyntax, variableSyntax.WithInitializer(F.EqualsValueClause(valueSyntax))
                                                                  ))
                               ));
                }

                FieldDeclarationSyntax WithBoolean(FieldDeclarationSyntax node, bool value)
                {
                    VariableDeclaratorSyntax variableSyntax = node.Declaration.Variables[0];
                    LiteralExpressionSyntax  valueSyntax    = F.LiteralExpression(value ? SyntaxKind.TrueLiteralExpression : SyntaxKind.FalseLiteralExpression);

                    return(node.WithDeclaration(
                               node.Declaration.WithVariables(node.Declaration.Variables.Replace(
                                                                  variableSyntax, variableSyntax.WithInitializer(F.EqualsValueClause(valueSyntax))
                                                                  ))
                               ));
                }

                for (int i = 0; i < members.Count; i++)
                {
                    FieldDeclarationSyntax field = members[i] as FieldDeclarationSyntax;

                    if (field == null)
                    {
                        continue;
                    }

                    string fieldName = field.Declaration.Variables[0].Identifier.Text;

                    switch (fieldName)
                    {
                    case "References":
                        field = WithValue(field, string.Join(";", compilation.References.OfType <PortableExecutableReference>().Select(x => x.FilePath)));
                        break;

                    case "Files":
                        field = WithValue(field, string.Join(";", compilation.SyntaxTrees.Select(x => x.FilePath)));
                        break;

                    case "AssemblyName":
                        field = WithValue(field, compilation.AssemblyName);
                        break;

                    case "ErrorFile":
                        field = WithValue(field, errorFile);
                        break;

                    case "Written":
                        field = WithBoolean(field, OutputAllTreesAttribute.Instance != null);
                        break;

                    case "BreakAtEnd":
                        field = WithBoolean(field, attribute.DisplayEndOfCompilationMessage);
                        break;

                    case "BreakAtStart":
                        field = WithBoolean(field, attribute.BreakDuringStart);
                        break;

                    default:
                        continue;
                    }

                    members = members.Replace(members[i], field);
                }

                // Return the modified compilation.
                return(compilation.AddSyntaxTrees(
                           generatedSyntaxTree
                           .WithCometaryOptions(this)
                           .WithRoot(
                               generatedRoot.WithMembers(generatedRoot.Members.Replace(originalClassSyntax, classSyntax.WithMembers(members))
                                                         )
                               )
                           ));
            }

            CompilationPipeline += EditCompilation;
        }