private DesktopAssemblyIdentityComparer GetAssemblyIdentityComparer()
        {
            // https://github.com/dotnet/roslyn/blob/41950e21da3ac2c307fb46c2ca8c8509b5059909/src/Compilers/CSharp/Portable/CommandLine/CSharpCompiler.cs#L105
            if (CscArgs.AppConfigPath == null)
            {
                return(DesktopAssemblyIdentityComparer.Default);
            }

            using (var appConfigStream = File.OpenRead(CscArgs.AppConfigPath))
            {
                return(DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream));
            }
        }
Пример #2
0
        public override Compilation?CreateCompilation(
            TextWriter consoleOutput,
            TouchedFileLogger touchedFilesLogger,
            ErrorLogger errorLogger,
            ImmutableArray <AnalyzerConfigOptionsResult> analyzerConfigOptions,
            AnalyzerConfigOptionsResult globalConfigOptions)
        {
            var parseOptions = Arguments.ParseOptions;

            // We compute script parse options once so we don't have to do it repeatedly in
            // case there are many script files.
            var scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script);

            bool hadErrors = false;

            var sourceFiles         = Arguments.SourceFiles;
            var trees               = new SyntaxTree?[sourceFiles.Length];
            var normalizedFilePaths = new string[sourceFiles.Length];
            var diagnosticBag       = DiagnosticBag.GetInstance();

            if (Arguments.CompilationOptions.ConcurrentBuild)
            {
                Parallel.For(0, sourceFiles.Length, UICultureUtilities.WithCurrentUICulture <int>(i =>
                {
                    try
                    {
                        //NOTE: order of trees is important!!
                        trees[i] = ParseFile(
                            parseOptions,
                            scriptParseOptions,
                            ref hadErrors,
                            sourceFiles[i],
                            diagnosticBag,
                            out normalizedFilePaths[i]);
                    }
                    catch (Exception e) when(FatalError.Report(e))
                    {
                        throw ExceptionUtilities.Unreachable;
                    }
                }));
            }
            else
            {
                for (int i = 0; i < sourceFiles.Length; i++)
                {
                    //NOTE: order of trees is important!!
                    trees[i] = ParseFile(
                        parseOptions,
                        scriptParseOptions,
                        ref hadErrors,
                        sourceFiles[i],
                        diagnosticBag,
                        out normalizedFilePaths[i]);
                }
            }

            // If errors had been reported in ParseFile, while trying to read files, then we should simply exit.
            if (ReportDiagnostics(diagnosticBag.ToReadOnlyAndFree(), consoleOutput, errorLogger))
            {
                Debug.Assert(hadErrors);
                return(null);
            }

            var diagnostics     = new List <DiagnosticInfo>();
            var uniqueFilePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            for (int i = 0; i < sourceFiles.Length; i++)
            {
                var normalizedFilePath = normalizedFilePaths[i];
                Debug.Assert(normalizedFilePath != null);
                Debug.Assert(sourceFiles[i].IsInputRedirected || PathUtilities.IsAbsolute(normalizedFilePath));

                if (!uniqueFilePaths.Add(normalizedFilePath))
                {
                    // warning CS2002: Source file '{0}' specified multiple times
                    diagnostics.Add(new DiagnosticInfo(MessageProvider, (int)ErrorCode.WRN_FileAlreadyIncluded,
                                                       Arguments.PrintFullPaths ? normalizedFilePath : _diagnosticFormatter.RelativizeNormalizedPath(normalizedFilePath)));

                    trees[i] = null;
                }
            }

            if (Arguments.TouchedFilesPath != null)
            {
                foreach (var path in uniqueFilePaths)
                {
                    touchedFilesLogger.AddRead(path);
                }
            }

            var assemblyIdentityComparer = DesktopAssemblyIdentityComparer.Default;
            var appConfigPath            = this.Arguments.AppConfigPath;

            if (appConfigPath != null)
            {
                try
                {
                    using (var appConfigStream = new FileStream(appConfigPath, FileMode.Open, FileAccess.Read))
                    {
                        assemblyIdentityComparer = DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream);
                    }

                    if (touchedFilesLogger != null)
                    {
                        touchedFilesLogger.AddRead(appConfigPath);
                    }
                }
                catch (Exception ex)
                {
                    diagnostics.Add(new DiagnosticInfo(MessageProvider, (int)ErrorCode.ERR_CantReadConfigFile, appConfigPath, ex.Message));
                }
            }

            var xmlFileResolver    = new LoggingXmlFileResolver(Arguments.BaseDirectory, touchedFilesLogger);
            var sourceFileResolver = new LoggingSourceFileResolver(ImmutableArray <string> .Empty, Arguments.BaseDirectory, Arguments.PathMap, touchedFilesLogger);

            MetadataReferenceResolver referenceDirectiveResolver;
            var resolvedReferences = ResolveMetadataReferences(diagnostics, touchedFilesLogger, out referenceDirectiveResolver);

            if (ReportDiagnostics(diagnostics, consoleOutput, errorLogger))
            {
                return(null);
            }

            var loggingFileSystem = new LoggingStrongNameFileSystem(touchedFilesLogger, _tempDirectory);
            var optionsProvider   = new CompilerSyntaxTreeOptionsProvider(trees, analyzerConfigOptions, globalConfigOptions);

            return(CSharpCompilation.Create(
                       Arguments.CompilationName,
                       trees.WhereNotNull(),
                       resolvedReferences,
                       Arguments.CompilationOptions
                       .WithMetadataReferenceResolver(referenceDirectiveResolver)
                       .WithAssemblyIdentityComparer(assemblyIdentityComparer)
                       .WithXmlReferenceResolver(xmlFileResolver)
                       .WithStrongNameProvider(Arguments.GetStrongNameProvider(loggingFileSystem))
                       .WithSourceReferenceResolver(sourceFileResolver)
                       .WithSyntaxTreeOptionsProvider(optionsProvider)));
        }
Пример #3
0
        public override Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger errorLogger)
        {
            var parseOptions       = Arguments.ParseOptions;
            var scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script);

            bool hadErrors = false;

            var sourceFiles         = Arguments.SourceFiles;
            var trees               = new SyntaxTree[sourceFiles.Length];
            var normalizedFilePaths = new String[sourceFiles.Length];

            if (Arguments.CompilationOptions.ConcurrentBuild)
            {
                Parallel.For(0, sourceFiles.Length, UICultureUtilities.WithCurrentUICulture <int>(i =>
                {
                    //NOTE: order of trees is important!!
                    trees[i] = ParseFile(consoleOutput, parseOptions, scriptParseOptions, ref hadErrors, sourceFiles[i], errorLogger, out normalizedFilePaths[i]);
                }));
            }
            else
            {
                for (int i = 0; i < sourceFiles.Length; i++)
                {
                    //NOTE: order of trees is important!!
                    trees[i] = ParseFile(consoleOutput, parseOptions, scriptParseOptions, ref hadErrors, sourceFiles[i], errorLogger, out normalizedFilePaths[i]);
                }
            }

            // If errors had been reported in ParseFile, while trying to read files, then we should simply exit.
            if (hadErrors)
            {
                return(null);
            }

            var diagnostics = new List <DiagnosticInfo>();

            var uniqueFilePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            for (int i = 0; i < sourceFiles.Length; i++)
            {
                var normalizedFilePath = normalizedFilePaths[i];
                Debug.Assert(normalizedFilePath != null);
                Debug.Assert(PathUtilities.IsAbsolute(normalizedFilePath));

                if (!uniqueFilePaths.Add(normalizedFilePath))
                {
                    // warning CS2002: Source file '{0}' specified multiple times
                    diagnostics.Add(new DiagnosticInfo(MessageProvider, (int)ErrorCode.WRN_FileAlreadyIncluded,
                                                       Arguments.PrintFullPaths ? normalizedFilePath : _diagnosticFormatter.RelativizeNormalizedPath(normalizedFilePath)));

                    trees[i] = null;
                }
            }

            if (Arguments.TouchedFilesPath != null)
            {
                foreach (var path in uniqueFilePaths)
                {
                    touchedFilesLogger.AddRead(path);
                }
            }

            var assemblyIdentityComparer = DesktopAssemblyIdentityComparer.Default;
            var appConfigPath            = this.Arguments.AppConfigPath;

            if (appConfigPath != null)
            {
                try
                {
                    using (var appConfigStream = new FileStream(appConfigPath, FileMode.Open, FileAccess.Read))
                    {
                        assemblyIdentityComparer = DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream);
                    }

                    if (touchedFilesLogger != null)
                    {
                        touchedFilesLogger.AddRead(appConfigPath);
                    }
                }
                catch (Exception ex)
                {
                    diagnostics.Add(new DiagnosticInfo(MessageProvider, (int)ErrorCode.ERR_CantReadConfigFile, appConfigPath, ex.Message));
                }
            }

            var metadataProvider   = GetMetadataProvider();
            var xmlFileResolver    = new LoggingXmlFileResolver(Arguments.BaseDirectory, touchedFilesLogger);
            var sourceFileResolver = new LoggingSourceFileResolver(ImmutableArray <string> .Empty, Arguments.BaseDirectory, touchedFilesLogger);

            var externalReferenceResolver = GetExternalMetadataResolver(touchedFilesLogger);
            MetadataFileReferenceResolver referenceDirectiveResolver;
            var resolvedReferences = ResolveMetadataReferences(externalReferenceResolver, metadataProvider, diagnostics, assemblyIdentityComparer, touchedFilesLogger, out referenceDirectiveResolver);

            if (ReportErrors(diagnostics, consoleOutput, errorLogger))
            {
                return(null);
            }

            var strongNameProvider = new LoggingStrongNameProvider(Arguments.KeyFileSearchPaths, touchedFilesLogger);

            var compilation = CSharpCompilation.Create(
                Arguments.CompilationName,
                trees.WhereNotNull(),
                resolvedReferences,
                Arguments.CompilationOptions.
                WithMetadataReferenceResolver(new AssemblyReferenceResolver(referenceDirectiveResolver, metadataProvider)).
                WithAssemblyIdentityComparer(assemblyIdentityComparer).
                WithStrongNameProvider(strongNameProvider).
                WithXmlReferenceResolver(xmlFileResolver).
                WithSourceReferenceResolver(sourceFileResolver));

            return(compilation);
        }
Пример #4
0
        protected override Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger)
        {
            var parseOptions       = Arguments.ParseOptions;
            var scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script);

            bool hadErrors = false;

            var sourceFiles         = Arguments.SourceFiles;
            var trees               = new SyntaxTree[sourceFiles.Length];
            var normalizedFilePaths = new String[sourceFiles.Length];

            if (Arguments.CompilationOptions.ConcurrentBuild)
            {
                var tasks = new Task[sourceFiles.Length];
                for (int i = 0; i < sourceFiles.Length; i++)
                {
                    //NOTE: order of trees is important!!
                    var treeIndex = i;
                    tasks[treeIndex] = Task.Run(async() =>
                    {
                        var file = sourceFiles[treeIndex];

                        var fileReadDiagnostics = new List <DiagnosticInfo>();
                        var result = await ReadFileContentAsync(file, fileReadDiagnostics, Arguments.Encoding).ConfigureAwait(false);

                        var content = result.Item1;
                        normalizedFilePaths[treeIndex] = result.Item2;

                        if (content == null)
                        {
                            PrintErrors(fileReadDiagnostics, consoleOutput);
                            fileReadDiagnostics.Clear();
                            hadErrors        = true;
                            trees[treeIndex] = null;
                        }
                        else
                        {
                            trees[treeIndex] = ParseFile(parseOptions, scriptParseOptions, content, file);
                        }
                    });
                }

                Task.WaitAll(tasks);
            }
            else
            {
                for (int i = 0; i < sourceFiles.Length; i++)
                {
                    var file = sourceFiles[i];

                    //NOTE: order of trees is important!!
                    trees[i] = ParseFile(consoleOutput, parseOptions, scriptParseOptions, ref hadErrors, file, out normalizedFilePaths[i]);
                }
            }

            // If errors had been reported in ParseFile, while trying to read files, then we should simply exit.
            if (hadErrors)
            {
                return(null);
            }

            var diagnostics = new List <DiagnosticInfo>();

            var uniqueFilePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            for (int i = 0; i < sourceFiles.Length; i++)
            {
                var normalizedFilePath = normalizedFilePaths[i];
                Debug.Assert(normalizedFilePath != null);
                Debug.Assert(PathUtilities.IsAbsolute(normalizedFilePath));

                if (!uniqueFilePaths.Add(normalizedFilePath))
                {
                    // warning CS2002: Source file '{0}' specified multiple times
                    diagnostics.Add(new DiagnosticInfo(MessageProvider, (int)ErrorCode.WRN_FileAlreadyIncluded,
                                                       Arguments.PrintFullPaths ? normalizedFilePath : this.diagnosticFormatter.RelativizeNormalizedPath(normalizedFilePath)));

                    trees[i] = null;
                }
            }

            if (Arguments.TouchedFilesPath != null)
            {
                foreach (var path in uniqueFilePaths)
                {
                    touchedFilesLogger.AddRead(path);
                }
            }

            var assemblyIdentityComparer = DesktopAssemblyIdentityComparer.Default;
            var appConfigPath            = this.Arguments.AppConfigPath;

            if (appConfigPath != null)
            {
                try
                {
                    using (var appConfigStream = new FileStream(appConfigPath, FileMode.Open, FileAccess.Read))
                    {
                        assemblyIdentityComparer = DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream);
                    }

                    if (touchedFilesLogger != null)
                    {
                        touchedFilesLogger.AddRead(appConfigPath);
                    }
                }
                catch (Exception ex)
                {
                    diagnostics.Add(new DiagnosticInfo(MessageProvider, (int)ErrorCode.ERR_CantReadConfigFile, appConfigPath, ex.Message));
                }
            }

            var metadataProvider   = GetMetadataProvider();
            var xmlFileResolver    = new LoggingXmlFileResolver(Arguments.BaseDirectory, touchedFilesLogger);
            var sourceFileResolver = new LoggingSourceFileResolver(ImmutableArray <string> .Empty, Arguments.BaseDirectory, touchedFilesLogger);

            var externalReferenceResolver = GetExternalMetadataResolver(touchedFilesLogger);
            MetadataReferenceResolver referenceDirectiveResolver;
            var resolvedReferences = ResolveMetadataReferences(externalReferenceResolver, metadataProvider, diagnostics, assemblyIdentityComparer, touchedFilesLogger, out referenceDirectiveResolver);

            if (PrintErrors(diagnostics, consoleOutput))
            {
                return(null);
            }

            var strongNameProvider = new LoggingStrongNameProvider(Arguments.KeyFileSearchPaths, touchedFilesLogger);

            var compilation = CSharpCompilation.Create(
                Arguments.CompilationName,
                trees.WhereNotNull(),
                resolvedReferences,
                Arguments.CompilationOptions.
                WithMetadataReferenceResolver(referenceDirectiveResolver).
                WithMetadataReferenceProvider(metadataProvider).
                WithAssemblyIdentityComparer(assemblyIdentityComparer).
                WithStrongNameProvider(strongNameProvider).
                WithXmlReferenceResolver(xmlFileResolver).
                WithSourceReferenceResolver(sourceFileResolver));

            // Print the diagnostics produced during the parsing stage and exit if there were any errors.
            if (PrintErrors(compilation.GetParseDiagnostics(), consoleOutput))
            {
                return(null);
            }

            if (PrintErrors(compilation.GetDeclarationDiagnostics(), consoleOutput))
            {
                return(null);
            }

            return(compilation);
        }
Пример #5
0
        public override Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger2 errorLogger)
        {
            var parseOptions = Arguments.ParseOptions;

            // We compute script parse options once so we don't have to do it repeatedly in
            // case there are many script files.
            var scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script);

            bool hadErrors = false;

            var sourceFiles         = Arguments.SourceFiles;
            var trees               = new SyntaxTree[sourceFiles.Length];
            var normalizedFilePaths = new String[sourceFiles.Length];

            for (int i = 0; i < sourceFiles.Length; i++)
            {
                //NOTE: order of trees is important!!
                trees[i] = ParseFile(consoleOutput, parseOptions, scriptParseOptions, ref hadErrors, sourceFiles[i], errorLogger, out normalizedFilePaths[i]);
            }


            // If errors had been reported in ParseFile, while trying to read files, then we should simply exit.
            if (hadErrors)
            {
                return(null);
            }

            var diagnostics = typeof(List <>).MakeGenericTypeFast(Refl.Type_DiagnosticInfo).InvokeFunction(".ctor");

            var uniqueFilePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            for (int i = 0; i < sourceFiles.Length; i++)
            {
                var normalizedFilePath = normalizedFilePaths[i];
                Debug.Assert(normalizedFilePath != null);
                Debug.Assert(ReflPathUtilities.IsAbsolute(normalizedFilePath));

                if (!uniqueFilePaths.Add(normalizedFilePath))
                {
                    // warning CS2002: Source file '{0}' specified multiple times
                    diagnostics.InvokeAction("Add", ReflDiagnosticInfo.ctor(MessageProvider, (int)Compatibility.WRN_FileAlreadyIncluded,
                                                                            new object[] { Arguments.PrintFullPaths?normalizedFilePath: ReflCommandLineDiagnosticFormatter.RelativizeNormalizedPath(_diagnosticFormatter, normalizedFilePath) }));

                    trees[i] = null;
                }
            }

            if (Arguments.TouchedFilesPath != null)
            {
                foreach (var path in uniqueFilePaths)
                {
                    ReflTouchedFileLogger.AddRead(touchedFilesLogger, path);
                }
            }

            var assemblyIdentityComparer = DesktopAssemblyIdentityComparer.Default;
            var appConfigPath            = this.Arguments.AppConfigPath;

            if (appConfigPath != null)
            {
                try
                {
                    using (var appConfigStream = new FileStream(appConfigPath, FileMode.Open, FileAccess.Read))
                    {
                        assemblyIdentityComparer = DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream);
                    }

                    if (touchedFilesLogger != null)
                    {
                        ReflTouchedFileLogger.AddRead(touchedFilesLogger, appConfigPath);
                    }
                }
                catch (Exception ex)
                {
                    diagnostics.InvokeAction("Add", ReflDiagnosticInfo.ctor(MessageProvider, (int)Compatibility.ERR_CantReadConfigFile, new object[] { appConfigPath, ex.Message }));
                }
            }

            var xmlFileResolver    = ReflLoggingXmlFileResolver.ctor(Arguments.BaseDirectory, touchedFilesLogger);
            var sourceFileResolver = ReflLoggingSourceFileResolver.ctor(ImmutableArray <string> .Empty, Arguments.BaseDirectory, Arguments.PathMap, touchedFilesLogger);

            MetadataReferenceResolver referenceDirectiveResolver;
            var resolvedReferences = ResolveMetadataReferences(diagnostics, touchedFilesLogger, out referenceDirectiveResolver);

            if (ReportErrors((IEnumerable <DiagnosticInfo>)diagnostics, consoleOutput, errorLogger))
            {
                return(null);
            }

            var strongNameProvider = ReflLoggingStrongNameProvider.ctor(Arguments.KeyFileSearchPaths, touchedFilesLogger);

            var compilation = CSharpCompilation.Create(
                Arguments.CompilationName,
                trees.Where(x => x != null),
                resolvedReferences,
                Arguments.CompilationOptions.
                WithMetadataReferenceResolver(referenceDirectiveResolver).
                WithAssemblyIdentityComparer(assemblyIdentityComparer).
                WithStrongNameProvider(strongNameProvider).
                WithXmlReferenceResolver(xmlFileResolver).
                WithSourceReferenceResolver(sourceFileResolver));

            return(compilation);
        }
Пример #6
0
                public bool SetApplicationConfiguration(string applicationConfiguration)
                {
                    if (!string.IsNullOrEmpty(applicationConfiguration))
                    {
                        var appConfigPath = FileUtilities.ResolveRelativePath(applicationConfiguration, Path.GetDirectoryName(_projectFile.FilePath));
                        try
                        {
                            using (var appConfigStream = new FileStream(appConfigPath, FileMode.Open, FileAccess.Read))
                            {
                                this.CompilationOptions = this.CompilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream));
                            }
                        }
                        catch (Exception)
                        {
                        }
                    }

                    return(true);
                }
Пример #7
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));
        }
Пример #8
0
        public override Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger errorLogger)
        {
#if XSHARP
            var parseOptions = Arguments.ParseOptions.WithOutput(consoleOutput);
#else
            var parseOptions = Arguments.ParseOptions;
#endif

            // We compute script parse options once so we don't have to do it repeatedly in
            // case there are many script files.
            var scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script);

            bool hadErrors = false;

            var sourceFiles         = Arguments.SourceFiles;
            var trees               = new SyntaxTree[sourceFiles.Length];
            var normalizedFilePaths = new string[sourceFiles.Length];
            var diagnosticBag       = DiagnosticBag.GetInstance();

            if (Arguments.CompilationOptions.ConcurrentBuild)
            {
                Parallel.For(0, sourceFiles.Length, UICultureUtilities.WithCurrentUICulture <int>(i =>
                {
                    //NOTE: order of trees is important!!
                    trees[i] = ParseFile(parseOptions, scriptParseOptions, ref hadErrors, sourceFiles[i], diagnosticBag, out normalizedFilePaths[i]);
                }));
            }
            else
            {
                for (int i = 0; i < sourceFiles.Length; i++)
                {
                    //NOTE: order of trees is important!!
                    trees[i] = ParseFile(parseOptions, scriptParseOptions, ref hadErrors, sourceFiles[i], diagnosticBag, out normalizedFilePaths[i]);
                }
            }

            // If errors had been reported in ParseFile, while trying to read files, then we should simply exit.
            if (hadErrors)
            {
                Debug.Assert(diagnosticBag.HasAnyErrors());
                ReportErrors(diagnosticBag.ToReadOnlyAndFree(), consoleOutput, errorLogger);
                return(null);
            }
            else
            {
                Debug.Assert(diagnosticBag.IsEmptyWithoutResolution);
                diagnosticBag.Free();
            }
#if XSHARP
            var newtree = InternalSyntax.XSharpLanguageParser.ProcessTrees(trees, parseOptions);
            if (newtree != null)
            {
                var newtrees = new SyntaxTree[trees.Length + 1];
                Array.Copy(trees, newtrees, trees.Length);
                newtrees[trees.Length] = newtree;
                trees = newtrees;
            }
#endif

            var diagnostics = new List <DiagnosticInfo>();

            var uniqueFilePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            for (int i = 0; i < sourceFiles.Length; i++)
            {
                var normalizedFilePath = normalizedFilePaths[i];
                Debug.Assert(normalizedFilePath != null);
                Debug.Assert(PathUtilities.IsAbsolute(normalizedFilePath));

                if (!uniqueFilePaths.Add(normalizedFilePath))
                {
                    // warning CS2002: Source file '{0}' specified multiple times
                    diagnostics.Add(new DiagnosticInfo(MessageProvider, (int)ErrorCode.WRN_FileAlreadyIncluded,
                                                       Arguments.PrintFullPaths ? normalizedFilePath : _diagnosticFormatter.RelativizeNormalizedPath(normalizedFilePath)));

                    trees[i] = null;
                }
#if XSHARP
                else if (parseOptions.PreprocessorOutput && Arguments.TouchedFilesPath != null)
                {
                    touchedFilesLogger.AddWritten(FileNameUtilities.ChangeExtension(normalizedFilePath, ".ppo"));
                }
#endif
            }
#if XSHARP
            // Add the names of the header files that we have processed
            foreach (var tree in trees)
            {
                if (tree != null)
                {
                    if (tree.HasCompilationUnitRoot)
                    {
                        var root = tree.GetCompilationUnitRoot();
                        foreach (var file in root.IncludedFiles)
                        {
                            uniqueFilePaths.Add(file.Key);
                        }
                    }
                }
            }
#endif
            if (Arguments.TouchedFilesPath != null)
            {
                foreach (var path in uniqueFilePaths)
                {
                    touchedFilesLogger.AddRead(path);
                }
            }

            var assemblyIdentityComparer = DesktopAssemblyIdentityComparer.Default;
            var appConfigPath            = this.Arguments.AppConfigPath;
            if (appConfigPath != null)
            {
                try
                {
                    using (var appConfigStream = new FileStream(appConfigPath, FileMode.Open, FileAccess.Read))
                    {
                        assemblyIdentityComparer = DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream);
                    }

                    if (touchedFilesLogger != null)
                    {
                        touchedFilesLogger.AddRead(appConfigPath);
                    }
                }
                catch (Exception ex)
                {
                    diagnostics.Add(new DiagnosticInfo(MessageProvider, (int)ErrorCode.ERR_CantReadConfigFile, appConfigPath, ex.Message));
                }
            }

            var xmlFileResolver    = new LoggingXmlFileResolver(Arguments.BaseDirectory, touchedFilesLogger);
            var sourceFileResolver = new LoggingSourceFileResolver(ImmutableArray <string> .Empty, Arguments.BaseDirectory, Arguments.PathMap, touchedFilesLogger);

            MetadataReferenceResolver referenceDirectiveResolver;
            var resolvedReferences = ResolveMetadataReferences(diagnostics, touchedFilesLogger, out referenceDirectiveResolver);
            if (ReportErrors(diagnostics, consoleOutput, errorLogger))
            {
                return(null);
            }

            var loggingFileSystem = new LoggingStrongNameFileSystem(touchedFilesLogger);

            return(CSharpCompilation.Create(
                       Arguments.CompilationName,
                       trees.WhereNotNull(),
                       resolvedReferences,
                       Arguments.CompilationOptions.
                       WithMetadataReferenceResolver(referenceDirectiveResolver).
                       WithAssemblyIdentityComparer(assemblyIdentityComparer).
                       WithXmlReferenceResolver(xmlFileResolver).
                       WithStrongNameProvider(Arguments.GetStrongNameProvider(loggingFileSystem, _tempDirectory)).
                       WithSourceReferenceResolver(sourceFileResolver)));
        }