public static CSharpCompilationOptions CreateCompilationOptions(this ProjectFileInfo projectFileInfo, CSharpCompilationOptions existingCompilationOptions)
        {
            var compilationOptions = existingCompilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default)
                                     .WithSpecificDiagnosticOptions(projectFileInfo.GetDiagnosticOptions())
                                     .WithOverflowChecks(projectFileInfo.CheckForOverflowUnderflow);

            if (projectFileInfo.AllowUnsafeCode != compilationOptions.AllowUnsafe)
            {
                compilationOptions = compilationOptions.WithAllowUnsafe(projectFileInfo.AllowUnsafeCode);
            }

            compilationOptions = projectFileInfo.TreatWarningsAsErrors ?
                                 compilationOptions.WithGeneralDiagnosticOption(ReportDiagnostic.Error) : compilationOptions.WithGeneralDiagnosticOption(ReportDiagnostic.Default);

            if (projectFileInfo.NullableContextOptions != compilationOptions.NullableContextOptions)
            {
                compilationOptions = compilationOptions.WithNullableContextOptions(projectFileInfo.NullableContextOptions);
            }

            if (projectFileInfo.SignAssembly && !string.IsNullOrEmpty(projectFileInfo.AssemblyOriginatorKeyFile))
            {
                var keyFile = Path.Combine(projectFileInfo.Directory, projectFileInfo.AssemblyOriginatorKeyFile);
                compilationOptions = compilationOptions.WithStrongNameProvider(new DesktopStrongNameProvider())
                                     .WithCryptoKeyFile(keyFile);
            }

            if (!string.IsNullOrWhiteSpace(projectFileInfo.DocumentationFile))
            {
                compilationOptions = compilationOptions.WithXmlReferenceResolver(XmlFileResolver.Default);
            }

            return(compilationOptions);
        }
        public CSharpCompilation Create()
        {
            var paths = AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES").ToString().Split(';');

            var references = _assemblies
                             .Select(x => x.Location)
                             .Concat(paths)
                             .Distinct()
                             .Select(x => MetadataReference.CreateFromFile(x))
                             .ToArray();

            var options = new CSharpCompilationOptions
                          (
                outputKind: OutputKind.DynamicallyLinkedLibrary,
                platform: Platform.AnyCpu,
                optimizationLevel: OptimizationLevel.Release,
                allowUnsafe: false
                          );

            options = options.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

            var compilation = CSharpCompilation.Create
                              (
                assemblyName: Guid.NewGuid().ToString(),
                options: options,
                references: references,
                syntaxTrees: new SyntaxTree[] { }
                              );

            return(compilation);
        }
Exemple #3
0
        public static CSharpCompilationOptions CreateCompilationOptions(this ProjectFileInfo projectFileInfo)
        {
            var result = new CSharpCompilationOptions(projectFileInfo.OutputKind);

            result = result.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

            if (projectFileInfo.AllowUnsafeCode)
            {
                result = result.WithAllowUnsafe(true);
            }

            result = result.WithSpecificDiagnosticOptions(CompilationOptionsHelper.GetDefaultSuppressedDiagnosticOptions(projectFileInfo.SuppressedDiagnosticIds));

            if (projectFileInfo.SignAssembly && !string.IsNullOrEmpty(projectFileInfo.AssemblyOriginatorKeyFile))
            {
                var keyFile = Path.Combine(projectFileInfo.Directory, projectFileInfo.AssemblyOriginatorKeyFile);
                result = result.WithStrongNameProvider(new DesktopStrongNameProvider())
                         .WithCryptoKeyFile(keyFile);
            }

            if (!string.IsNullOrWhiteSpace(projectFileInfo.DocumentationFile))
            {
                result = result.WithXmlReferenceResolver(XmlFileResolver.Default);
            }

            return(result);
        }
Exemple #4
0
        private CSharpCompilationOptions CreateDefaultCompilationOptions()
        {
            var options = new CSharpCompilationOptions
                          (
                outputKind: OutputKind.DynamicallyLinkedLibrary,
                platform: Platform.AnyCpu,
                optimizationLevel: OptimizationLevel.Release,
                allowUnsafe: false
                          );

            options = options.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

            return(options);
        }
Exemple #5
0
        CSharpCompilation IResolveReference.GetReferenceResolvedCompilation(CodeGenConfig2 config)
        {
            string path         = Path.GetDirectoryName(config.Project);
            string projFilePath = config.Project;
            string name         = Path.GetFileNameWithoutExtension(projFilePath);

            CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

            compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

            CSharpCompilation compilation = CSharpCompilation.Create(name);

            compilation = compilation.WithOptions(compilationOptions);

            return(compilation);
        }
Exemple #6
0
        public async Task <Assembly> Compile(string code)
        {
            await Init();

            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code, new CSharpParseOptions(LanguageVersion.Latest));

            foreach (var diagnostic in syntaxTree.GetDiagnostics())
            {
                CompileLog.Add(diagnostic.ToString());
            }

            if (syntaxTree.GetDiagnostics().Any(i => i.Severity == DiagnosticSeverity.Error))
            {
                CompileLog.Add("Parse SyntaxTree Error!");
                return(null);
            }

            CompileLog.Add("Parse SyntaxTree Success");

            //https://stackoverflow.com/questions/35711461/how-to-get-roslyn-to-compile-when-referenced-assemblies-have-references-to-both
            var op = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

            op = op.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);
            CSharpCompilation compilation = CSharpCompilation.Create("WasmRoslyn.Demo", new[] { syntaxTree },
                                                                     references, op);

            using (MemoryStream stream = new MemoryStream())
            {
                EmitResult result = compilation.Emit(stream);

                foreach (var diagnostic in result.Diagnostics)
                {
                    CompileLog.Add(diagnostic.ToString());
                }

                if (!result.Success)
                {
                    CompileLog.Add("Compilation error");
                    return(null);
                }

                CompileLog.Add("Compilation success!");
                Assembly assemby = AppDomain.CurrentDomain.Load(stream.ToArray());
                return(assemby);
            }
        }
Exemple #7
0
        private static CSharpCompilationOptions CreateCompilationOptions(ProjectFileInfo projectFileInfo)
        {
            var result = new CSharpCompilationOptions(projectFileInfo.OutputKind);

            result = result.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

            if (projectFileInfo.AllowUnsafeCode)
            {
                result = result.WithAllowUnsafe(true);
            }

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

            if (projectFileInfo.SuppressedDiagnosticIds.Any())
            {
                foreach (var id in projectFileInfo.SuppressedDiagnosticIds)
                {
                    if (!specificDiagnosticOptions.ContainsKey(id))
                    {
                        specificDiagnosticOptions.Add(id, ReportDiagnostic.Suppress);
                    }
                }
            }

            result = result.WithSpecificDiagnosticOptions(specificDiagnosticOptions);

            if (projectFileInfo.SignAssembly && !string.IsNullOrEmpty(projectFileInfo.AssemblyOriginatorKeyFile))
            {
                var keyFile = Path.Combine(projectFileInfo.Directory, projectFileInfo.AssemblyOriginatorKeyFile);
                result = result.WithStrongNameProvider(new DesktopStrongNameProvider())
                         .WithCryptoKeyFile(keyFile);
            }

            if (!string.IsNullOrWhiteSpace(projectFileInfo.DocumentationFile))
            {
                result = result.WithXmlReferenceResolver(XmlFileResolver.Default);
            }

            return(result);
        }
        public static CSharpCompilationOptions CreateCompilationOptions(this ProjectFileInfo projectFileInfo)
        {
            var compilationOptions = new CSharpCompilationOptions(projectFileInfo.OutputKind);

            compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

            if (projectFileInfo.AllowUnsafeCode)
            {
                compilationOptions = compilationOptions.WithAllowUnsafe(true).WithGeneralDiagnosticOption(ReportDiagnostic.Error);
            }

            if (projectFileInfo.TreatWarningsAsErrors)
            {
                compilationOptions = compilationOptions.WithGeneralDiagnosticOption(ReportDiagnostic.Error);
            }

            if (projectFileInfo.NullableContextOptions != compilationOptions.NullableContextOptions)
            {
                compilationOptions = compilationOptions.WithNullableContextOptions(projectFileInfo.NullableContextOptions);
            }

            compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(CompilationOptionsHelper.GetDefaultSuppressedDiagnosticOptions(projectFileInfo.SuppressedDiagnosticIds));

            if (projectFileInfo.SignAssembly && !string.IsNullOrEmpty(projectFileInfo.AssemblyOriginatorKeyFile))
            {
                var keyFile = Path.Combine(projectFileInfo.Directory, projectFileInfo.AssemblyOriginatorKeyFile);
                compilationOptions = compilationOptions.WithStrongNameProvider(new DesktopStrongNameProvider())
                                     .WithCryptoKeyFile(keyFile);
            }

            if (!string.IsNullOrWhiteSpace(projectFileInfo.DocumentationFile))
            {
                compilationOptions = compilationOptions.WithXmlReferenceResolver(XmlFileResolver.Default);
            }

            return(compilationOptions);
        }
Exemple #9
0
        public void Initalize(IConfiguration configuration)
        {
            _options = new MSBuildOptions();
            OptionsServices.ReadProperties(_options, configuration);

            var solutionFilePath = _env.SolutionFilePath;

            if (string.IsNullOrEmpty(solutionFilePath))
            {
                var solutions = Directory.GetFiles(_env.Path, "*.sln");
                var result    = SolutionPicker.ChooseSolution(_env.Path, solutions);

                if (result.Message != null)
                {
                    _logger.LogInformation(result.Message);
                }

                if (result.Solution == null)
                {
                    return;
                }

                solutionFilePath = result.Solution;
            }

            SolutionFile solutionFile = null;

            _context.SolutionPath = solutionFilePath;

            using (var stream = File.OpenRead(solutionFilePath))
            {
                using (var reader = new StreamReader(stream))
                {
                    solutionFile = SolutionFile.Parse(reader);
                }
            }
            _logger.LogInformation($"Detecting projects in '{solutionFilePath}'.");

            foreach (var block in solutionFile.ProjectBlocks)
            {
                if (!_supportsProjectTypes.Contains(block.ProjectTypeGuid))
                {
                    if (UnityTypeGuid(block.ProjectName) != block.ProjectTypeGuid)
                    {
                        _logger.LogWarning("Skipped unsupported project type '{0}'", block.ProjectPath);
                        continue;
                    }
                }

                if (_context.ProjectGuidToWorkspaceMapping.ContainsKey(block.ProjectGuid))
                {
                    continue;
                }

                var projectFilePath = Path.GetFullPath(Path.GetFullPath(Path.Combine(_env.Path, block.ProjectPath.Replace('\\', Path.DirectorySeparatorChar))));

                _logger.LogInformation($"Loading project from '{projectFilePath}'.");

                var projectFileInfo = CreateProject(projectFilePath);

                if (projectFileInfo == null)
                {
                    continue;
                }

                var compilationOptions = new CSharpCompilationOptions(projectFileInfo.OutputKind);
#if DNX451
                compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);
#endif

                if (projectFileInfo.AllowUnsafe)
                {
                    compilationOptions = compilationOptions.WithAllowUnsafe(true);
                }

                var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(projectFileInfo.Name),
                                                     VersionStamp.Create(),
                                                     projectFileInfo.Name,
                                                     projectFileInfo.AssemblyName,
                                                     LanguageNames.CSharp,
                                                     projectFileInfo.ProjectFilePath,
                                                     compilationOptions: compilationOptions);

                _workspace.AddProject(projectInfo);

                projectFileInfo.WorkspaceId = projectInfo.Id;

                _context.Projects[projectFileInfo.ProjectFilePath]        = projectFileInfo;
                _context.ProjectGuidToWorkspaceMapping[block.ProjectGuid] = projectInfo.Id;

                _watcher.Watch(projectFilePath, OnProjectChanged);
            }

            foreach (var projectFileInfo in _context.Projects.Values)
            {
                UpdateProject(projectFileInfo);
            }
        }
        public void Initalize(IConfiguration configuration)
        {
            _options = new MSBuildOptions();
            OptionsServices.ReadProperties(_options, configuration);

            var solutionFilePath = _env.SolutionFilePath;

            if (string.IsNullOrEmpty(solutionFilePath))
            {
                var solutions = Directory.GetFiles(_env.Path, "*.sln");
                var result = SolutionPicker.ChooseSolution(_env.Path, solutions);

                if (result.Message != null)
                {
                    _logger.LogInformation(result.Message);
                }

                if (result.Solution == null)
                {
                    return;
                }

                solutionFilePath = result.Solution;
            }

            SolutionFile solutionFile = null;

            _context.SolutionPath = solutionFilePath;

            using (var stream = File.OpenRead(solutionFilePath))
            {
                using (var reader = new StreamReader(stream))
                {
                    solutionFile = SolutionFile.Parse(reader);
                }
            }
            _logger.LogInformation($"Detecting projects in '{solutionFilePath}'.");

            foreach (var block in solutionFile.ProjectBlocks)
            {
                if (!_supportsProjectTypes.Contains(block.ProjectTypeGuid))
                {
                    if (UnityTypeGuid(block.ProjectName) != block.ProjectTypeGuid)
                    {
                        _logger.LogWarning("Skipped unsupported project type '{0}'", block.ProjectPath);
                        continue;
                    }
                }

                if (_context.ProjectGuidToWorkspaceMapping.ContainsKey(block.ProjectGuid))
                {
                    continue;
                }

                var projectFilePath = Path.GetFullPath(Path.GetFullPath(Path.Combine(_env.Path, block.ProjectPath.Replace('\\', Path.DirectorySeparatorChar))));

                _logger.LogInformation($"Loading project from '{projectFilePath}'.");

                var projectFileInfo = CreateProject(projectFilePath);

                if (projectFileInfo == null)
                {
                    continue;
                }

                var compilationOptions = new CSharpCompilationOptions(projectFileInfo.OutputKind);
#if DNX451
                compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);
#endif

                if (projectFileInfo.AllowUnsafe)
                {
                    compilationOptions = compilationOptions.WithAllowUnsafe(true);
                }

                var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(projectFileInfo.Name),
                                                     VersionStamp.Create(),
                                                     projectFileInfo.Name,
                                                     projectFileInfo.AssemblyName,
                                                     LanguageNames.CSharp,
                                                     projectFileInfo.ProjectFilePath,
                                                     compilationOptions: compilationOptions);

                _workspace.AddProject(projectInfo);

                projectFileInfo.WorkspaceId = projectInfo.Id;

                _context.Projects[projectFileInfo.ProjectFilePath] = projectFileInfo;
                _context.ProjectGuidToWorkspaceMapping[block.ProjectGuid] = projectInfo.Id;

                _watcher.Watch(projectFilePath, OnProjectChanged);
            }

            foreach (var projectFileInfo in _context.Projects.Values)
            {
                UpdateProject(projectFileInfo);
            }

        }
Exemple #11
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);
        }
Exemple #12
0
        /// <summary>
        /// This method attempts to load the build script at the given location,
        /// compile return the exported AbstractBuildTask from it. The script
        /// file must inherit from AbstractBuildTask.
        /// </summary>
        /// <param name="taskScriptPath">
        /// The path to the build script to run.
        /// </param>
        /// <returns>
        /// In the event of successful discovery, read and compilation of the
        /// script at the given path, a list of all exported AbstractBuildTasks
        /// from the compiled assembly is returned.
        /// </returns>
        private static List <AbstractBuildTask> LoadTaskFromScript(string taskScriptPath)
        {
            WriteTitleToConsole("Loading & Parsing Build Script");

            // Exhaustively verify that the file exists, is readable and is not
            // an empty file.
            Debug.Assert(!string.IsNullOrEmpty(taskScriptPath) && !string.IsNullOrWhiteSpace(taskScriptPath), "Build task script path is null, empty or whitespace.");

            if (string.IsNullOrEmpty(taskScriptPath) || string.IsNullOrWhiteSpace(taskScriptPath))
            {
                throw new ArgumentException("Build task script path is null, empty or whitespace.", nameof(taskScriptPath));
            }

            Debug.Assert(File.Exists(taskScriptPath), "Build task script path points to non-existent file.");

            if (!File.Exists(taskScriptPath))
            {
                throw new ArgumentException("Build task script path points to non-existent file.");
            }

            Console.WriteLine(string.Format("Reading all text from file {0}", taskScriptPath));

            var scriptContents = File.ReadAllText(taskScriptPath);

            Debug.Assert(!string.IsNullOrEmpty(scriptContents) && !string.IsNullOrWhiteSpace(scriptContents), "Build task script contents are null, empty or whitespace.");

            if (string.IsNullOrEmpty(scriptContents) || string.IsNullOrWhiteSpace(scriptContents))
            {
                throw new ArgumentException("Build task script contents are null, empty or whitespace.", nameof(taskScriptPath));
            }

            // Setup syntax parse options for C#.
            CSharpParseOptions parseOptions = CSharpParseOptions.Default;

            parseOptions = parseOptions.WithLanguageVersion(LanguageVersion.CSharp6);
            parseOptions = parseOptions.WithDocumentationMode(DocumentationMode.None);
            parseOptions = parseOptions.WithKind(SourceCodeKind.Regular);

            // Parse text into syntax tree.
            SyntaxTree jobSyntaxTree = CSharpSyntaxTree.ParseText(scriptContents, parseOptions);

            // Generate a random file name for the assembly we're about to produce.
            string generatedAssemblyName = Path.GetRandomFileName();

            // Get the directory of a core assembly. We need this directory to
            // build out our platform specific reference to mscorlib. mscorlib
            // and the private mscorlib must be supplied as references for
            // compilation to succeed. Of these two assemblies, only the private
            // mscorlib is discovered via enumerataing assemblies referenced by
            // this executing binary.
            var dd      = typeof(Enumerable).GetTypeInfo().Assembly.Location;
            var coreDir = Directory.GetParent(dd);

            HashSet <string> allRefs = new HashSet <string>();

            List <MetadataReference> references = new List <MetadataReference>
            {
                // Here we get the path to the mscorlib and private mscorlib
                // libraries that are required for compilation to succeed.
                MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "mscorlib.dll"),
                MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location)
            };

            // Enumerate all assemblies referenced by this executing assembly
            // and provide them as references to the build script we're about to
            // compile.
            var referencedAssemblies = RecursivelyGetReferencedAssemblies(Assembly.GetEntryAssembly());

            foreach (var referencedAssembly in referencedAssemblies)
            {
                var mref = MetadataReference.CreateFromFile(referencedAssembly.Location);

                if (referencedAssembly.FullName.Contains("System.Runtime.Extension"))
                {
                    // Have to do this to avoid collisions with duplicate type
                    // definitions between private mscorlib and this assembly.
                    // XXX TODO - Needs to be solved in a better way?
                    mref = mref.WithAliases(new List <string>(new[] { "CorPrivate" }));
                }

                if (!allRefs.Contains(mref.Display))
                {
                    references.Add(mref);
                    allRefs.Add(mref.Display);
                }

                /* For debugging, to try to list explicit platform compat. Flaky.
                 * try
                 * {
                 *  var customAttributes = loadedAssembly.GetCustomAttributes();
                 *  var attribute = customAttributes.OfType<TargetFrameworkAttribute>().First();
                 *
                 *  Console.WriteLine(attribute.FrameworkName);
                 *  Console.WriteLine(attribute.FrameworkDisplayName);
                 * }
                 * catch{}
                 */
            }

            // Initialize compilation arguments for the build script we're about
            // to compile.
            var op = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

            op = op.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);
            op = op.WithGeneralDiagnosticOption(ReportDiagnostic.Warn);

            // Initialize the compilation with our options, references and the
            // already parsed syntax tree of the build script.
            CSharpCompilation compilation = CSharpCompilation.Create(
                generatedAssemblyName,
                syntaxTrees: new[] { jobSyntaxTree },
                references: references,
                options: op);

            // Compile and emit new assembly into memory.
            var        ms     = new MemoryStream();
            EmitResult result = compilation.Emit(ms);

            if (result.Success)
            {
                // Store the in-memory assembly until this program exits.
                GeneratedAssemblies.Add(ms);

                // Get an Assembly structure from the data in memory.
                ms.Seek(0, SeekOrigin.Begin);
                AssemblyLoadContext loadCtx  = AssemblyLoadContext.Default;
                Assembly            assembly = loadCtx.LoadFromStream(ms);

                // Enumerate types exported from the assembly. Presently not used.
                var exportedTypes = assembly.ExportedTypes;
                foreach (var xp in exportedTypes)
                {
                    Console.WriteLine(string.Format("Build script exports type: {0}", xp.Name));
                }

                // Filter exported types so we only pull types extending from AbstractBuildTask.
                var filteredExports = exportedTypes.Where(x => x.Name != typeof(AbstractBuildTask).Name);
                Console.WriteLine(string.Format("Number of exported build objects: {0}", filteredExports.Count()));

                // Ensure that we have at least one exported build task.
                Debug.Assert(filteredExports.Count() > 0, "Script either does not export any AbstractBuildTask objects. Build scripts should export one or more AbstractBuildTask objects.");
                if (filteredExports.Count() <= 0)
                {
                    throw new ArgumentException("Script either does not export any AbstractBuildTask objects. Build scripts should export one or more AbstractBuildTask objects.", nameof(taskScriptPath));
                }

                var filteredExportsList             = filteredExports.ToList();
                List <AbstractBuildTask> buildTasks = new List <AbstractBuildTask>();

                foreach (var entry in filteredExportsList)
                {
                    AbstractBuildTask typedExport = (AbstractBuildTask)Activator.CreateInstance(entry, new[] { taskScriptPath.ConvertToHostOsPath() });
                    buildTasks.Add(typedExport);
                }

                return(buildTasks);
            }
            else
            {
                ms.Dispose();

                Console.WriteLine(string.Format("Failed to compile build script: {0}.", taskScriptPath));

                IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
                                                                             diagnostic.IsWarningAsError ||
                                                                             diagnostic.Severity == DiagnosticSeverity.Error);

                foreach (Diagnostic diagnostic in failures)
                {
                    Console.Error.WriteLine("{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
                }

                CleanExit(ExitCodes.ScriptCompilationFailure);
            }

            Console.WriteLine("null");

            return(null);
        }
        public static ExitCode Process(string srcFile, string outputDir, string rootNs, IList <string> macros, IList <string> undefMacros, IDictionary <string, string> _refByNames, IDictionary <string, string> _refByPaths, string systemDllPath, bool outputResult, bool parallel)
        {
            if (string.IsNullOrEmpty(outputDir))
            {
                outputDir = "../rewrite";
            }

            List <string> preprocessors = new List <string>(macros);

            preprocessors.Add("__LUA__");

            string exepath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
            string path    = Path.GetDirectoryName(srcFile);
            string name    = Path.GetFileNameWithoutExtension(srcFile);
            string ext     = Path.GetExtension(srcFile);

            string logDir = Path.Combine(path, "log");

            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }
            if (!Path.IsPathRooted(outputDir))
            {
                outputDir = Path.Combine(path, outputDir);
                outputDir = Path.GetFullPath(outputDir);
            }
            if (!Directory.Exists(outputDir))
            {
                Directory.CreateDirectory(outputDir);
            }

            List <string> files = new List <string>();
            Dictionary <string, string> refByNames = new Dictionary <string, string>(_refByNames);
            Dictionary <string, string> refByPaths = new Dictionary <string, string>(_refByPaths);

            if (ext == ".csproj")
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(srcFile);
                var nodes = SelectNodes(xmlDoc, "ItemGroup", "Reference");
                foreach (XmlElement node in nodes)
                {
                    var aliasesNode = SelectSingleNode(node, "Aliases");
                    var pathNode    = SelectSingleNode(node, "HintPath");
                    if (null != pathNode && !refByPaths.ContainsKey(pathNode.InnerText))
                    {
                        if (null != aliasesNode)
                        {
                            refByPaths.Add(pathNode.InnerText, aliasesNode.InnerText);
                        }
                        else
                        {
                            refByPaths.Add(pathNode.InnerText, "global");
                        }
                    }
                    else
                    {
                        string val = node.GetAttribute("Include");
                        if (!string.IsNullOrEmpty(val) && !refByNames.ContainsKey(val))
                        {
                            if (null != aliasesNode)
                            {
                                refByNames.Add(val, aliasesNode.InnerText);
                            }
                            else
                            {
                                refByNames.Add(val, "global");
                            }
                        }
                    }
                }
                string prjOutputDir = "bin/Debug/";
                nodes = SelectNodes(xmlDoc, "PropertyGroup");
                foreach (XmlElement node in nodes)
                {
                    string condition = node.GetAttribute("Condition");
                    var    defNode   = SelectSingleNode(node, "DefineConstants");
                    var    pathNode  = SelectSingleNode(node, "OutputPath");
                    if (null != defNode && null != pathNode)
                    {
                        string text = defNode.InnerText.Trim();
                        if (condition.IndexOf("Debug") > 0 || condition.IndexOf("Release") < 0 && (text == "DEBUG" || text.IndexOf(";DEBUG;") > 0 || text.StartsWith("DEBUG;") || text.EndsWith(";DEBUG")))
                        {
                            preprocessors.AddRange(text.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
                            prjOutputDir = pathNode.InnerText.Trim();
                            break;
                        }
                    }
                }
                nodes = SelectNodes(xmlDoc, "ItemGroup", "ProjectReference");
                foreach (XmlElement node in nodes)
                {
                    string val      = node.GetAttribute("Include");
                    string prjFile  = Path.Combine(path, val.Trim());
                    var    nameNode = SelectSingleNode(node, "Name");
                    if (null != prjFile && null != nameNode)
                    {
                        string prjName       = nameNode.InnerText.Trim();
                        string prjOutputFile = ParseProjectOutputFile(prjFile, prjName);
                        string fileName      = Path.Combine(prjOutputDir, prjOutputFile);
                        if (!refByPaths.ContainsKey(fileName))
                        {
                            refByPaths.Add(fileName, "global");
                        }
                    }
                }
                nodes = SelectNodes(xmlDoc, "ItemGroup", "Compile");
                foreach (XmlElement node in nodes)
                {
                    string val = node.GetAttribute("Include");
                    if (!string.IsNullOrEmpty(val) && val.EndsWith(".cs") && !files.Contains(val))
                    {
                        files.Add(val);
                    }
                }
            }
            else
            {
                files.Add(srcFile);
            }

            foreach (string m in undefMacros)
            {
                preprocessors.Remove(m);
            }

            bool haveError = false;
            Dictionary <string, SyntaxTree> trees = new Dictionary <string, SyntaxTree>();

            using (StreamWriter sw = new StreamWriter(Path.Combine(logDir, "SyntaxError.log"))) {
                using (StreamWriter sw2 = new StreamWriter(Path.Combine(logDir, "SyntaxWarning.log"))) {
                    Action <string> handler = (file) => {
                        string             filePath = Path.Combine(path, file);
                        string             fileName = Path.GetFileNameWithoutExtension(filePath);
                        CSharpParseOptions options  = new CSharpParseOptions();
                        options = options.WithPreprocessorSymbols(preprocessors);
                        options = options.WithFeatures(new Dictionary <string, string> {
                            { "IOperation", "true" }
                        });
                        SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(filePath), options, filePath);
                        lock (trees) {
                            trees.Add(file, tree);
                        }

                        var  diags        = tree.GetDiagnostics();
                        bool firstError   = true;
                        bool firstWarning = true;
                        foreach (var diag in diags)
                        {
                            if (diag.Severity == DiagnosticSeverity.Error)
                            {
                                if (firstError)
                                {
                                    LockWriteLine(sw, "============<<<Syntax Error:{0}>>>============", fileName);
                                    firstError = false;
                                }
                                string msg = diag.ToString();
                                LockWriteLine(sw, "{0}", msg);
                                haveError = true;
                            }
                            else
                            {
                                if (firstWarning)
                                {
                                    LockWriteLine(sw2, "============<<<Syntax Warning:{0}>>>============", fileName);
                                    firstWarning = false;
                                }
                                string msg = diag.ToString();
                                LockWriteLine(sw2, "{0}", msg);
                            }
                        }
                    };
                    if (parallel)
                    {
                        Parallel.ForEach(files, handler);
                    }
                    else
                    {
                        foreach (var file in files)
                        {
                            handler(file);
                        }
                    }
                    sw2.Close();
                }
                sw.Close();
            }
            if (haveError)
            {
                Console.WriteLine("{0}", File.ReadAllText(Path.Combine(logDir, "SyntaxError.log")));
                return(ExitCode.SyntaxError);
            }

            //确保常用的Assembly被引用
            if (!refByNames.ContainsKey("mscorlib"))
            {
                refByNames.Add("mscorlib", "global");
            }
            if (!refByNames.ContainsKey("System"))
            {
                refByNames.Add("System", "global");
            }
            if (!refByNames.ContainsKey("System.Core"))
            {
                refByNames.Add("System.Core", "global");
            }
            List <MetadataReference> refs = new List <MetadataReference>();

            if (string.IsNullOrEmpty(systemDllPath))
            {
                if (ext == ".cs")
                {
                    refs.Add(MetadataReference.CreateFromFile(typeof(Queue <>).Assembly.Location));
                    refs.Add(MetadataReference.CreateFromFile(typeof(HashSet <>).Assembly.Location));
                }
                foreach (var pair in refByNames)
                {
#pragma warning disable 618
                    Assembly assembly = Assembly.LoadWithPartialName(pair.Key);
#pragma warning restore 618
                    if (null != assembly)
                    {
                        var arr = System.Collections.Immutable.ImmutableArray.Create(pair.Value);
                        refs.Add(MetadataReference.CreateFromFile(assembly.Location, new MetadataReferenceProperties(MetadataImageKind.Assembly, arr)));
                    }
                }
            }
            else
            {
                foreach (var pair in refByNames)
                {
                    string file = Path.Combine(systemDllPath, pair.Key) + ".dll";
                    var    arr  = System.Collections.Immutable.ImmutableArray.Create(pair.Value);
                    refs.Add(MetadataReference.CreateFromFile(file, new MetadataReferenceProperties(MetadataImageKind.Assembly, arr)));
                }
            }

            foreach (var pair in refByPaths)
            {
                string fullPath = Path.Combine(path, pair.Key);
                var    arr      = System.Collections.Immutable.ImmutableArray.Create(pair.Value);
                refs.Add(MetadataReference.CreateFromFile(fullPath, new MetadataReferenceProperties(MetadataImageKind.Assembly, arr)));
            }

            bool                     haveSemanticError = false;
            StringBuilder            errorBuilder      = new StringBuilder();
            StringBuilder            sb = new StringBuilder();
            CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
            compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);
            CSharpCompilation compilation = CSharpCompilation.Create(name);
            compilation = compilation.WithOptions(compilationOptions);
            compilation = compilation.AddReferences(refs.ToArray());
            compilation = compilation.AddSyntaxTrees(trees.Values);

            SymbolTable.Instance.Init(compilation, rootNs, exepath);

            using (StreamWriter sw = new StreamWriter(Path.Combine(logDir, "SemanticError.log"))) {
                using (StreamWriter sw2 = new StreamWriter(Path.Combine(logDir, "SemanticWarning.log"))) {
                    foreach (var pair in trees)
                    {
                        var fileName = Path.Combine(path, pair.Key);
                        var filePath = Path.Combine(outputDir, pair.Key);
                        var dir      = Path.GetDirectoryName(filePath);
                        if (!Directory.Exists(dir))
                        {
                            Directory.CreateDirectory(dir);
                        }
                        SyntaxTree tree  = pair.Value;
                        var        model = compilation.GetSemanticModel(tree, true);

                        var  diags        = model.GetDiagnostics();
                        bool firstError   = true;
                        bool firstWarning = true;
                        foreach (var diag in diags)
                        {
                            if (diag.Severity == DiagnosticSeverity.Error)
                            {
                                if (firstError)
                                {
                                    LockWriteLine(sw, "============<<<Semantic Error:{0}>>>============", fileName);
                                    firstError = false;
                                }
                                string msg = diag.ToString();
                                LockWriteLine(sw, "{0}", msg);
                                haveSemanticError = true;
                            }
                            else
                            {
                                if (firstWarning)
                                {
                                    LockWriteLine(sw2, "============<<<Semantic Warning:{0}>>>============", fileName);
                                    firstWarning = false;
                                }
                                string msg = diag.ToString();
                                LockWriteLine(sw2, "{0}", msg);
                            }
                        }

                        Logger.Instance.ClearLog();
                        Cs2LuaRewriter rewriter = new Cs2LuaRewriter(rootNs, model);
                        var            newRoot  = rewriter.Visit(tree.GetRoot()) as CSharpSyntaxNode;
                        string         txt      = newRoot.ToFullString();
                        sb.AppendLine(txt);
                        File.WriteAllText(filePath, txt);

                        if (Logger.Instance.HaveError)
                        {
                            errorBuilder.AppendLine(Logger.Instance.ErrorLog);
                        }
                    }
                }
            }

            File.WriteAllText(Path.Combine(logDir, "Cs2LuaError.log"), errorBuilder.ToString());
            using (var sw = new StreamWriter(Path.Combine(logDir, "IllegalGenericOrExtensions.txt"))) {
                sw.WriteLine("IllegalGenericTypes:");
                foreach (var type in SymbolTable.Instance.IllegalGenericTypes)
                {
                    sw.WriteLine("\t{0}", type);
                }
                sw.WriteLine("IllegalGenericMethods:");
                foreach (var method in SymbolTable.Instance.IllegalGenericMethods)
                {
                    sw.WriteLine("\t{0}", method);
                }
                sw.WriteLine("IllegalParameterGenericTypes:");
                foreach (var type in SymbolTable.Instance.IllegalParameterGenericTypes)
                {
                    sw.WriteLine("\t{0}", type);
                }
                sw.WriteLine("IllegalExtensions:");
                foreach (var type in SymbolTable.Instance.IllegalExtensions)
                {
                    sw.WriteLine("\t{0}", type);
                }
                sw.WriteLine("IllegalConvertions:");
                foreach (var pair in SymbolTable.Instance.IllegalConvertions)
                {
                    foreach (var type in pair.Value)
                    {
                        sw.WriteLine("\t{0}=>{1}", pair.Key, type);
                    }
                }
                sw.WriteLine();
                sw.WriteLine("AccessMemberOfIllegalGenericTypes:");
                foreach (var type in SymbolTable.Instance.AccessMemberOfIllegalGenericTypes)
                {
                    sw.WriteLine("\t{0}", type);
                }
            }
            if (outputResult)
            {
                Console.Write(sb.ToString());
            }
            if (haveSemanticError)
            {
                return(ExitCode.SemanticError);
            }
            return(ExitCode.Success);
        }
Exemple #14
0
        CSharpCompilation IResolveReference.GetReferenceResolvedCompilation(CodeGenConfig config)
        {
            string path         = Path.GetDirectoryName(config.Project);
            string projFilePath = config.Project;
            string name         = Path.GetFileNameWithoutExtension(projFilePath);

            string systemDllPath = config.SystemDllPath;

            List <string> preprocessors = new List <string>();

            preprocessors.Add("__LUA__");

            //存储引用refs
            List <MetadataReference> refs = new List <MetadataReference>();

            List <string> files = new List <string>();
            Dictionary <string, string> refByNames = new Dictionary <string, string>();
            Dictionary <string, string> refByPaths = new Dictionary <string, string>();

            //从csproj文件中解析XML获取引用
            if (projFilePath.EndsWith(".csproj"))
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(projFilePath);

                //查找ItemGroup下的Reference节点
                var nodes = SelectNodes(xmlDoc, "ItemGroup", "Reference");
                foreach (XmlElement node in nodes)
                {
                    var aliasesNode = SelectSingleNode(node, "Aliases");
                    var pathNode    = SelectSingleNode(node, "HintPath");
                    if (null != pathNode && !refByPaths.ContainsKey(pathNode.InnerText))
                    {
                        if (null != aliasesNode)
                        {
                            refByPaths.Add(pathNode.InnerText, aliasesNode.InnerText);
                        }
                        else
                        {
                            refByPaths.Add(pathNode.InnerText, "global");
                        }
                    }
                    else
                    {
                        string val = node.GetAttribute("Include");
                        if (!string.IsNullOrEmpty(val) && !refByNames.ContainsKey(val))
                        {
                            if (null != aliasesNode)
                            {
                                refByNames.Add(val, aliasesNode.InnerText);
                            }
                            else
                            {
                                refByNames.Add(val, "global");
                            }
                        }
                    }
                }

                string prjOutputDir = "bin/Debug/";
                nodes = SelectNodes(xmlDoc, "PropertyGroup");
                foreach (XmlElement node in nodes)
                {
                    string condition = node.GetAttribute("Condition");
                    var    defNode   = SelectSingleNode(node, "DefineConstants");
                    var    pathNode  = SelectSingleNode(node, "OutputPath");
                    if (null != defNode && null != pathNode)
                    {
                        string text = defNode.InnerText.Trim();
                        if (condition.IndexOf("Debug") > 0 || condition.IndexOf("Release") < 0 && (text == "DEBUG" || text.IndexOf(";DEBUG;") > 0 || text.StartsWith("DEBUG;") || text.EndsWith(";DEBUG")))
                        {
                            preprocessors.AddRange(text.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
                            prjOutputDir = pathNode.InnerText.Trim();
                            break;
                        }
                    }
                }

                //查找ItemGroup下的ProjectReference节点
                nodes = SelectNodes(xmlDoc, "ItemGroup", "ProjectReference");
                foreach (XmlElement node in nodes)
                {
                    string val      = node.GetAttribute("Include");
                    string prjFile  = Path.Combine(path, val.Trim());
                    var    nameNode = SelectSingleNode(node, "Name");
                    if (null != prjFile && null != nameNode)
                    {
                        string prjName       = nameNode.InnerText.Trim();
                        string prjOutputFile = ParseProjectOutputFile(prjFile, prjName);
                        string fileName      = Path.Combine(prjOutputDir, prjOutputFile);
                        if (!refByPaths.ContainsKey(fileName))
                        {
                            refByPaths.Add(fileName, "global");
                        }
                    }
                }
                nodes = SelectNodes(xmlDoc, "ItemGroup", "Compile");
                foreach (XmlElement node in nodes)
                {
                    string val = node.GetAttribute("Include");
                    if (!string.IsNullOrEmpty(val) && val.EndsWith(".cs") && !files.Contains(val))
                    {
                        files.Add(val);
                    }
                }

                //确保常用的Assembly被引用
                if (!refByNames.ContainsKey("mscorlib"))
                {
                    refByNames.Add("mscorlib", "global");
                }
                if (!refByNames.ContainsKey("System"))
                {
                    refByNames.Add("System", "global");
                }
                if (!refByNames.ContainsKey("System.Core"))
                {
                    refByNames.Add("System.Core", "global");
                }

                if (string.IsNullOrEmpty(systemDllPath))//默认
                {
                    //用反射添加具体的类名引用
                    foreach (var pair in refByNames)
                    {
#pragma warning disable 618
                        Assembly assembly = Assembly.LoadWithPartialName(pair.Key);
#pragma warning restore 618
                        if (null != assembly)
                        {
                            var arr = System.Collections.Immutable.ImmutableArray.Create(pair.Value);
                            Console.WriteLine(pair.Key);
                            refs.Add(MetadataReference.CreateFromFile(assembly.Location, new MetadataReferenceProperties(MetadataImageKind.Assembly, arr)));
                        }
                    }
                }
                //需配置SystemDLLPath
                else
                {
                    foreach (var pair in refByNames)
                    {
                        string file = Path.Combine(systemDllPath, pair.Key) + ".dll";
                        var    arr  = System.Collections.Immutable.ImmutableArray.Create(pair.Value);
                        refs.Add(MetadataReference.CreateFromFile(file, new MetadataReferenceProperties(MetadataImageKind.Assembly, arr)));
                    }
                }

                //从文件路径添加DLL引用
                foreach (var pair in refByPaths)
                {
                    string fullPath = Path.Combine(path, pair.Key);
                    var    arr      = System.Collections.Immutable.ImmutableArray.Create(pair.Value);
                    Console.WriteLine(fullPath);


                    if (!File.Exists(fullPath))
                    {
                        Console.WriteLine(fullPath + "is not exsit!");
                        continue;
                    }

                    refs.Add(MetadataReference.CreateFromFile(fullPath, new MetadataReferenceProperties(MetadataImageKind.Assembly, arr)));
                }

                //手动构造Complation对象
                CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
                compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);
                CSharpCompilation compilation = CSharpCompilation.Create(name);
                compilation = compilation.WithOptions(compilationOptions);

                //手动添加Reference
                compilation = compilation.AddReferences(refs.ToArray());

                //手动添加SyntaxTree
                foreach (string itemFile in files)
                {
                    string filePath = Path.Combine(path, itemFile);
                    string fileName = Path.GetFileNameWithoutExtension(filePath);

                    if (!File.Exists(filePath))
                    {
                        Console.WriteLine(filePath + "is not exsit!");
                        continue;
                    }

                    CSharpParseOptions options = new CSharpParseOptions();
                    options = options.WithPreprocessorSymbols(preprocessors);
                    options = options.WithFeatures(new Dictionary <string, string> {
                        { "IOperation", "true" }
                    });
                    SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(filePath), options, filePath);
                    compilation = compilation.AddSyntaxTrees(tree);
                }
                return(compilation);
            }
            return(null);
        }
        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);
        }
        public void Initalize(IConfiguration configuration)
        {
            _options = new MSBuildOptions();
            ConfigurationBinder.Bind(configuration, _options);

            if (_options.WaitForDebugger)
            {
                Console.WriteLine($"Attach to process {System.Diagnostics.Process.GetCurrentProcess().Id}");
                while (!System.Diagnostics.Debugger.IsAttached)
                {
                    System.Threading.Thread.Sleep(100);
                }
            }

            var solutionFilePath = _env.SolutionFilePath;

            if (string.IsNullOrEmpty(solutionFilePath))
            {
                var solutions = Directory.GetFiles(_env.Path, "*.sln");
                var result    = SolutionPicker.ChooseSolution(_env.Path, solutions);

                if (result.Message != null)
                {
                    _logger.LogInformation(result.Message);
                }

                if (result.Solution == null)
                {
                    return;
                }

                solutionFilePath = result.Solution;
            }

            SolutionFile solutionFile = null;

            _context.SolutionPath = solutionFilePath;

            using (var stream = File.OpenRead(solutionFilePath))
            {
                using (var reader = new StreamReader(stream))
                {
                    solutionFile = SolutionFile.Parse(reader);
                }
            }
            _logger.LogInformation($"Detecting projects in '{solutionFilePath}'.");

            foreach (var block in solutionFile.ProjectBlocks)
            {
                if (!_supportsProjectTypes.Contains(block.ProjectTypeGuid))
                {
                    if (UnityTypeGuid(block.ProjectName) != block.ProjectTypeGuid)
                    {
                        _logger.LogWarning("Skipped unsupported project type '{0}'", block.ProjectPath);
                        continue;
                    }
                }

                if (_context.ProjectGuidToWorkspaceMapping.ContainsKey(block.ProjectGuid))
                {
                    continue;
                }

                var projectFilePath = Path.GetFullPath(Path.GetFullPath(Path.Combine(_env.Path, block.ProjectPath.Replace('\\', Path.DirectorySeparatorChar))));

                _logger.LogInformation($"Loading project from '{projectFilePath}'.");

                var projectFileInfo = CreateProject(projectFilePath);

                if (projectFileInfo == null)
                {
                    continue;
                }

                var compilationOptions = new CSharpCompilationOptions(projectFileInfo.OutputKind);
                compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

                if (projectFileInfo.AllowUnsafe)
                {
                    compilationOptions = compilationOptions.WithAllowUnsafe(true);
                }

                if (projectFileInfo.SignAssembly && !string.IsNullOrEmpty(projectFileInfo.AssemblyOriginatorKeyFile))
                {
                    var keyFile = Path.Combine(projectFileInfo.ProjectDirectory, projectFileInfo.AssemblyOriginatorKeyFile);
                    compilationOptions = compilationOptions.WithStrongNameProvider(new DesktopStrongNameProvider())
                                         .WithCryptoKeyFile(keyFile);
                }

                if (projectFileInfo.GenerateXmlDocumentation)
                {
                    compilationOptions = compilationOptions.WithXmlReferenceResolver(XmlFileResolver.Default);
                }

                var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(projectFileInfo.Name),
                                                     VersionStamp.Create(),
                                                     projectFileInfo.Name,
                                                     projectFileInfo.AssemblyName,
                                                     LanguageNames.CSharp,
                                                     projectFileInfo.ProjectFilePath,
                                                     compilationOptions: compilationOptions);

                _workspace.AddProject(projectInfo);

                projectFileInfo.WorkspaceId = projectInfo.Id;

                _context.Projects[projectFileInfo.ProjectFilePath]        = projectFileInfo;
                _context.ProjectGuidToWorkspaceMapping[block.ProjectGuid] = projectInfo.Id;

                _watcher.Watch(projectFilePath, OnProjectChanged);
            }

            foreach (var projectFileInfo in _context.Projects.Values)
            {
                UpdateProject(projectFileInfo);
            }
        }
        /// <summary>
        /// Compiles an embedded resource into an executable and writes it to disk in the same
        /// directory as the executing assembly.
        /// </summary>
        /// <param name="sourceResourcePath">
        /// The relative resource path, as it must be formatted for a pack URI.
        /// </param>
        /// <param name="absOutputPath">
        /// The absolute path
        /// </param>
        private string CompileExe(string sourceResourcePath, string absOutputPath)
        {
            m_logger.Info("Compiling internal service: {0} to output {1}.", sourceResourcePath, absOutputPath);
            string scriptContents = string.Empty;

            using (var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(sourceResourcePath))
            {
                using (TextReader tsr = new StreamReader(resourceStream))
                {
                    scriptContents = tsr.ReadToEnd();
                }
            }

            if (scriptContents == null || scriptContents.Length == 0)
            {
                m_logger.Warn("When compiling internal service {0}, failed to load source code.", sourceResourcePath);
                return(string.Empty);
            }

            // The sentinel service is special. It's the only that's going to watch us.
            // So, we need to code our process name into its source before compilation.
            if (sourceResourcePath.IndexOf("Sentinel", StringComparison.OrdinalIgnoreCase) != -1)
            {
                scriptContents = scriptContents.Replace("TARGET_APPLICATION_NAME", Process.GetCurrentProcess().ProcessName);
            }

            HashSet <string> allRefs = new HashSet <string>();

            var dd      = typeof(Enumerable).GetTypeInfo().Assembly.Location;
            var coreDir = Directory.GetParent(dd);

            List <MetadataReference> references = new List <MetadataReference>
            {
                // Here we get the path to the mscorlib and private mscorlib
                // libraries that are required for compilation to succeed.
                //MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "mscorlib.dll"),
                MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location)
            };

            var referencedAssemblies = RecursivelyGetReferencedAssemblies(Assembly.GetEntryAssembly());

            foreach (var referencedAssembly in referencedAssemblies)
            {
                var mref = MetadataReference.CreateFromFile(referencedAssembly.Location);

                if (referencedAssembly.FullName.Contains("System.Runtime.Extension"))
                {
                    // Have to do this to avoid collisions with duplicate type
                    // definitions between private mscorlib and this assembly.
                    // XXX TODO - Needs to be solved in a better way?
                    mref = mref.WithAliases(new List <string>(new[] { "CorPrivate" }));
                }

                if (!allRefs.Contains(mref.Display))
                {
                    references.Add(mref);
                    allRefs.Add(mref.Display);
                }
            }

            // Setup syntax parse options for C#.
            CSharpParseOptions parseOptions = CSharpParseOptions.Default;

            parseOptions = parseOptions.WithLanguageVersion(LanguageVersion.CSharp6);
            parseOptions = parseOptions.WithDocumentationMode(DocumentationMode.None);
            parseOptions = parseOptions.WithKind(SourceCodeKind.Regular);

            // Parse text into syntax tree.
            SyntaxTree jobSyntaxTree = CSharpSyntaxTree.ParseText(scriptContents, parseOptions);

            // Initialize compilation arguments for the build script we're about
            // to compile.
            var op = new CSharpCompilationOptions(OutputKind.ConsoleApplication);

            op = op.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);
            op = op.WithGeneralDiagnosticOption(ReportDiagnostic.Warn);

            // Initialize the compilation with our options, references and the
            // already parsed syntax tree of the build script.
            CSharpCompilation compilation = CSharpCompilation.Create(
                Path.GetFileNameWithoutExtension(absOutputPath),
                syntaxTrees: new[] { jobSyntaxTree },
                references: references,
                options: op);

            // Compile and emit new assembly into memory.
            using (var ms = new MemoryStream())
            {
                EmitResult result = compilation.Emit(ms);

                if (result.Success)
                {
                    File.WriteAllBytes(absOutputPath, ms.ToArray());
                    m_logger.Info("Generated service assembly {0} for service {1}.", absOutputPath, Path.GetFileNameWithoutExtension(absOutputPath));
                    return(absOutputPath);
                }
                else
                {
                    // Compilation failed.
                    m_logger.Error("Failed to generate service assembly for service {0}.", Path.GetFileNameWithoutExtension(absOutputPath));

                    foreach (var diag in result.Diagnostics)
                    {
                        m_logger.Error(diag.GetMessage());
                    }
                }
            }

            return(string.Empty);
        }
Exemple #18
0
        public static void Compile()
        {
            var testTree = CSharpSyntaxTree.ParseText(@"
using System;
using ExternalLibrary;

namespace test{

    public class Power
    {

        public void power(int number)
        { 
            new ExternalClass().Print(number * number);
        } 

    }

}");

            var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true);

            options = options.WithAssemblyIdentityComparer(AssemblyIdentityComparer.Default);

            var references = new List <MetadataReference>
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51").Location),
                MetadataReference.CreateFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ExternalLibrary.dll"))
            };

            if (AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES") is string trustedAssemblies)
            {
                Console.WriteLine(trustedAssemblies);
                references.AddRange(
                    trustedAssemblies.Split(Path.PathSeparator).Select(path =>
                                                                       MetadataReference.CreateFromFile(path))
                    );
            }

            var compilation = CSharpCompilation.Create("DummyAssembly", options: options, references: references)
                              .AddSyntaxTrees(testTree);

            using (var stream = new MemoryStream())
            {
                var compilationResult = compilation.Emit(stream);

                if (!compilationResult.Success)
                {
                    Console.WriteLine(string.Join("\n", compilationResult.Diagnostics.Select(d => d.GetMessage())));
                }
                else
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    var assembly = Assembly.Load(stream.ToArray());
                    var type     = assembly.GetType("test.Power");
                    var power    = Activator.CreateInstance(type);
                    type.InvokeMember("power", BindingFlags.Default | BindingFlags.InvokeMethod, null, power, new object[] { 2 });
                }
            }
        }