예제 #1
0
        /// <summary>
        /// Gets the complete list of locations to locate references.
        /// </summary>
        /// <param name="args">Command line arguments.</param>
        /// <returns>List of directories.</returns>
        private static IEnumerable <string> FixedReferencePaths(Microsoft.CodeAnalysis.CommandLineArguments args)
        {
            // See https://msdn.microsoft.com/en-us/library/s5bac5fx.aspx
            // on how csc resolves references. Basically,
            // 1) Current working directory. This is the directory from which the compiler is invoked.
            // 2) The common language runtime system directory.
            // 3) Directories specified by / lib.
            // 4) Directories specified by the LIB environment variable.

            if (args.BaseDirectory is not null)
            {
                yield return(args.BaseDirectory);
            }

            foreach (var r in args.ReferencePaths)
            {
                yield return(r);
            }

            var lib = System.Environment.GetEnvironmentVariable("LIB");

            if (lib is not null)
            {
                yield return(lib);
            }
        }
예제 #2
0
 private void SetArgumentsCore(string commandLine, CommandLineArguments commandLineArguments)
 {
     lock (_gate)
     {
         _lastParsedCompilerOptions = commandLine;
         _lastParsedCommandLineArguments = commandLineArguments;
     }
 }
예제 #3
0
        /// <summary>
        /// Creates new parse options from parsed command line arguments (with overridden default DocumentationMode).
        /// It is expected that derived types which need to add more specific options will fetch the base options and override those options.
        /// </summary>
        protected virtual ParseOptions CreateParseOptions(CommandLineArguments commandLineArguments)
        {
            Contract.ThrowIfNull(commandLineArguments);

            // Override the default documentation mode.
            var documentationMode = commandLineArguments.DocumentationPath != null ? DocumentationMode.Diagnose : DocumentationMode.Parse;
            return commandLineArguments.ParseOptions.WithDocumentationMode(documentationMode);
        }
 private void PostSetOptions(CommandLineArguments commandLineArguments)
 {
     // Invoke SetOutputPathAndRelatedData to update the project obj output path.
     if (commandLineArguments.OutputFileName != null && commandLineArguments.OutputDirectory != null)
     {
         var objOutputPath = PathUtilities.CombinePathsUnchecked(commandLineArguments.OutputDirectory, commandLineArguments.OutputFileName);
         SetObjOutputPathAndRelatedData(objOutputPath);
     }
 }
 private void PostSetCommandLineArguments(CommandLineArguments commandLineArguments)
 {
     // Invoke SetOutputPathAndRelatedData to update the project tracker bin path for this project, if required.
     if (commandLineArguments.OutputFileName != null && commandLineArguments.OutputDirectory != null)
     {
         var newOutputPath = PathUtilities.CombinePathsUnchecked(commandLineArguments.OutputDirectory, commandLineArguments.OutputFileName);
         SetOutputPathAndRelatedData(newOutputPath, hasSameBinAndObjOutputPaths: true);
     }
 }
예제 #6
0
        /// <summary>
        /// Resets the last parsed command line and updates options with the same command line.
        /// </summary>
        /// <remarks>
        /// Use this method when options can go stale due to side effects, even though the command line is identical.
        /// For example, changes to contents of a ruleset file needs to force update the options for the same command line.
        /// </remarks>
        protected CommandLineArguments ResetArgumentsAndUpdateOptions()
        {
            // Clear last parsed command line.
            var savedLastParsedCompilerOptions = _lastParsedCompilerOptions;
            _lastParsedCompilerOptions = null;
            _lastParsedCommandLineArguments = null;

            // Now set arguments and update options with the saved command line.
            return SetArgumentsAndUpdateOptions(savedLastParsedCompilerOptions);
        }
예제 #7
0
        /// <summary>
        /// If the command line has changed from the last parsed command line, then it parses it and sets new command line arguments.
        /// </summary>
        /// <param name="commandlineForOptions"></param>
        /// <returns></returns>
        protected CommandLineArguments SetArguments(string commandlineForOptions)
        {
            if (!string.Equals(_lastParsedCompilerOptions, commandlineForOptions, StringComparison.OrdinalIgnoreCase))
            {
                // Command line options have changed, so update options with new parsed CommandLineArguments.
                var splitArguments = CommandLineParser.SplitCommandLineIntoArguments(commandlineForOptions, removeHashComments: false);
                _lastParsedCommandLineArguments = CommandLineParserService?.Parse(splitArguments, this.ContainingDirectoryPathOpt, isInteractive: false, sdkDirectory: null);
                _lastParsedCompilerOptions = commandlineForOptions;
            }

            return _lastParsedCommandLineArguments;
        }
예제 #8
0
        IProjectContext IProjectContextFactory.CreateProjectContext(
            string languageName,
            string projectDisplayName,
            string projectFilePath,
            Guid projectGuid,
            string projectTypeGuid,
            IVsHierarchy hierarchy,
            CommandLineArguments commandLineArguments)
        {
            Contract.ThrowIfNull(hierarchy);

            Func<ProjectId, IVsReportExternalErrors> getExternalErrorReporter = id => GetExternalErrorReporter(id, languageName);
            return new CPSProject(commandLineArguments, _projectTracker, getExternalErrorReporter, projectDisplayName, projectFilePath,
                projectGuid, projectTypeGuid, hierarchy, languageName, _serviceProvider, _visualStudioWorkspace, _hostDiagnosticUpdateSource);
        }
예제 #9
0
        /// <summary>
        /// Construct tasks for resolving references (possibly in parallel).
        ///
        /// The resolved references will be added (thread-safely) to the supplied
        /// list <paramref name="ret"/>.
        /// </summary>
        static IEnumerable <Action> ResolveReferences(Microsoft.CodeAnalysis.CommandLineArguments args, Analyser analyser, CanonicalPathCache canonicalPathCache, BlockingCollection <MetadataReference> ret)
        {
            var referencePaths = new Lazy <string[]>(() => FixedReferencePaths(args).ToArray());

            return(args.MetadataReferences.Select <CommandLineReference, Action>(clref => () =>
            {
                if (Path.IsPathRooted(clref.Reference))
                {
                    if (File.Exists(clref.Reference))
                    {
                        var reference = MakeReference(clref, canonicalPathCache.GetCanonicalPath(clref.Reference));
                        ret.Add(reference);
                    }
                    else
                    {
                        lock (analyser)
                        {
                            analyser.Logger.Log(Severity.Error, "  Reference '{0}' does not exist", clref.Reference);
                            ++analyser.CompilationErrors;
                        }
                    }
                }
                else
                {
                    bool referenceFound = false;
                    {
                        foreach (var composed in referencePaths.Value.
                                 Select(path => Path.Combine(path, clref.Reference)).
                                 Where(path => File.Exists(path)).
                                 Select(path => canonicalPathCache.GetCanonicalPath(path)))
                        {
                            referenceFound = true;
                            var reference = MakeReference(clref, composed);
                            ret.Add(reference);
                            break;
                        }
                        if (!referenceFound)
                        {
                            lock (analyser)
                            {
                                analyser.Logger.Log(Severity.Error, "  Unable to resolve reference '{0}'", clref.Reference);
                                ++analyser.CompilationErrors;
                            }
                        }
                    }
                }
            }));
        }
예제 #10
0
        int ICompilerOptionsHostObject.SetCompilerOptions(string compilerOptions, out bool supported)
        {
            if (!string.Equals(_lastParsedCompilerOptions, compilerOptions))
            {
                var splitArguments = CommandLineParser.SplitCommandLineIntoArguments(compilerOptions, removeHashComments: false);

                _lastParsedCommandLineArguments = ParseCommandLineArguments(splitArguments);
                _lastParsedCompilerOptions = compilerOptions;

                UpdateOptions();
            }

            supported = true;

            return VSConstants.S_OK;
        }
예제 #11
0
        /// <summary>
        /// Creates new compilation options from parsed command line arguments, with additional workspace specific options appended.
        /// It is expected that derived types which need to add more specific options will fetch the base options and override those options.
        /// </summary>
        protected virtual CompilationOptions CreateCompilationOptions(CommandLineArguments commandLineArguments, ParseOptions newParseOptions)
        {
            Contract.ThrowIfNull(commandLineArguments);

            // Get options from command line arguments.
            var options = commandLineArguments.CompilationOptions;

            // Now set the default workspace options (these are not set by the command line parser).
            string projectDirectory = this.ContainingDirectoryPathOpt;

            // TODO: #r support, should it include bin path?
            var referenceSearchPaths = ImmutableArray<string>.Empty;

            // TODO: #load support
            var sourceSearchPaths = ImmutableArray<string>.Empty;

            MetadataReferenceResolver referenceResolver;
            if (Workspace != null)
            {
                referenceResolver = new WorkspaceMetadataFileReferenceResolver(
                    Workspace.CurrentSolution.Services.MetadataService,
                    new RelativePathResolver(referenceSearchPaths, projectDirectory));
            }
            else
            {
                // can only happen in tests
                referenceResolver = null;
            }

            // Explicitly disable concurrent build.
            options = options.WithConcurrentBuild(concurrent: false);

            // Set default resolvers.
            options = options.WithMetadataReferenceResolver(referenceResolver)
                .WithXmlReferenceResolver(new XmlFileResolver(projectDirectory))
                .WithSourceReferenceResolver(new SourceFileResolver(sourceSearchPaths, projectDirectory))
                .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default)
                .WithStrongNameProvider(new DesktopStrongNameProvider(GetStrongNameKeyPaths()));

            return options;
        }
예제 #12
0
파일: CPSProject.cs 프로젝트: xyh413/roslyn
        public CPSProject(
            CommandLineArguments commandLineArguments,
            VisualStudioProjectTracker projectTracker,
            Func<ProjectId, IVsReportExternalErrors> reportExternalErrorCreatorOpt,
            string projectDisplayName,
            string projectFilePath,
            Guid projectGuid,
            string projectTypeGuid,
            IVsHierarchy hierarchy,
            string language,
            IServiceProvider serviceProvider,
            VisualStudioWorkspaceImpl visualStudioWorkspaceOpt,
            HostDiagnosticUpdateSource hostDiagnosticUpdateSourceOpt)
            : base(projectTracker, reportExternalErrorCreatorOpt, projectDisplayName, projectFilePath, projectGuid,
                   projectTypeGuid, hierarchy, language, serviceProvider, visualStudioWorkspaceOpt, hostDiagnosticUpdateSourceOpt)
        {
            // Set the initial options from the command line before we add the project to the project tracker.
            SetCommandLineArguments(commandLineArguments);

            projectTracker.AddProject(this);
        }
예제 #13
0
        // internal for testing
        internal static Stream GetWin32ResourcesInternal(CommonMessageProvider messageProvider, CommandLineArguments arguments, Compilation compilation, out IEnumerable<DiagnosticInfo> errors)
        {
            List<DiagnosticInfo> errorList = new List<DiagnosticInfo>();
            errors = errorList;

            if (arguments.Win32ResourceFile != null)
            {
                return OpenStream(messageProvider, arguments.Win32ResourceFile, arguments.BaseDirectory, messageProvider.ERR_CantOpenWin32Resource, errorList);
            }

            using (Stream manifestStream = OpenManifestStream(messageProvider, compilation.Options.OutputKind, arguments, errorList))
            {
                using (Stream iconStream = OpenStream(messageProvider, arguments.Win32Icon, arguments.BaseDirectory, messageProvider.ERR_CantOpenWin32Icon, errorList))
                {
                    try
                    {
                        return compilation.CreateDefaultWin32Resources(true, arguments.NoWin32Manifest, manifestStream, iconStream);
                    }
                    catch (ResourceException ex)
                    {
                        errorList.Add(new DiagnosticInfo(messageProvider, messageProvider.ERR_ErrorBuildingWin32Resource, ex.Message));
                    }
                    catch (OverflowException ex)
                    {
                        errorList.Add(new DiagnosticInfo(messageProvider, messageProvider.ERR_ErrorBuildingWin32Resource, ex.Message));
                    }
                }
            }

            return null;
        }
예제 #14
0
 protected Stream GetWin32Resources(CommandLineArguments arguments, Compilation compilation, out IEnumerable<DiagnosticInfo> errors)
 {
     return GetWin32ResourcesInternal(MessageProvider, arguments, compilation, out errors);
 }
예제 #15
0
 // internal for testing purposes only.
 internal static CPSProject CreateCPSProject(VisualStudioProjectTracker projectTracker, IServiceProvider serviceProvider, IVsHierarchy hierarchy, string projectDisplayName, string projectFilePath, string language, Guid projectGuid, string projectTypeGuid, CommandLineArguments commandLineArguments)
 {
     return new CPSProject(commandLineArguments, projectTracker, reportExternalErrorCreatorOpt: null, hierarchy: hierarchy, language: language,
         serviceProvider: serviceProvider, visualStudioWorkspaceOpt: null, hostDiagnosticUpdateSourceOpt: null, projectDisplayName: projectDisplayName,
         projectFilePath: projectFilePath, projectGuid: projectGuid, projectTypeGuid: projectTypeGuid);
 }
예제 #16
0
        /// <summary>
        /// The string returned from this function represents the inputs to the compiler which impact determinism.  It is 
        /// meant to be inline with the specification here:
        /// 
        ///     - https://github.com/dotnet/roslyn/blob/master/docs/compilers/Deterministic%20Inputs.md
        /// 
        /// Issue #8193 tracks filling this out to the full specification. 
        /// 
        ///     https://github.com/dotnet/roslyn/issues/8193
        /// </summary>
        private static string CreateDeterminismKey(CommandLineArguments args, string[] rawArgs, string baseDirectory, CommandLineParser parser)
        {
            List<Diagnostic> diagnostics = new List<Diagnostic>();
            List<string> flattenedArgs = new List<string>();
            parser.FlattenArgs(rawArgs, diagnostics, flattenedArgs, null, baseDirectory);

            var builder = new StringBuilder();
            var name = !string.IsNullOrEmpty(args.OutputFileName)
                ? Path.GetFileNameWithoutExtension(Path.GetFileName(args.OutputFileName))
                : $"no-output-name-{Guid.NewGuid().ToString()}";

            builder.AppendLine($"{name}");
            builder.AppendLine($"Command Line:");
            foreach (var current in flattenedArgs)
            {
                builder.AppendLine($"\t{current}");
            }

            builder.AppendLine("Source Files:");
            var hash = new MD5CryptoServiceProvider();
            foreach (var sourceFile in args.SourceFiles)
            {
                var sourceFileName = Path.GetFileName(sourceFile.Path);

                string hashValue;
                try
                {
                    var bytes = PortableShim.File.ReadAllBytes(sourceFile.Path);
                    var hashBytes = hash.ComputeHash(bytes);
                    var data = BitConverter.ToString(hashBytes);
                    hashValue = data.Replace("-", "");
                }
                catch (Exception ex)
                {
                    hashValue = $"Could not compute {ex.Message}";
                }
                builder.AppendLine($"\t{sourceFileName} - {hashValue}");
            }

            return builder.ToString();
        }
예제 #17
0
 private static void EmitDeterminismKey(CommandLineArguments args, string[] rawArgs, string baseDirectory, CommandLineParser parser)
 {
     var key = CreateDeterminismKey(args, rawArgs, baseDirectory, parser);
     var filePath = Path.Combine(args.OutputDirectory, args.OutputFileName + ".key");
     using (var stream = PortableShim.File.Create(filePath))
     {
         var bytes = Encoding.UTF8.GetBytes(key);
         stream.Write(bytes, 0, bytes.Length);
     }
 }
예제 #18
0
        public void SetCommandLineArguments(CommandLineArguments commandLineArguments)
        {
            SetArgumentsAndUpdateOptions(commandLineArguments);

            // If outputPath has changed, then invoke SetOutputPathAndRelatedData to update the project tracker bin path for this project.
            if (commandLineArguments.OutputFileName != null && commandLineArguments.OutputDirectory != null)
            {
                var newOutputPath = PathUtilities.CombinePathsUnchecked(commandLineArguments.OutputDirectory, commandLineArguments.OutputFileName);
                SetOutputPathAndRelatedData(newOutputPath, hasSameBinAndObjOutputPaths: true);
            }
        }
예제 #19
0
 private static FileStream OpenManifestStream(CommonMessageProvider messageProvider, OutputKind outputKind, CommandLineArguments arguments, List <DiagnosticInfo> errorList)
 {
     return(outputKind.IsNetModule()
         ? null
         : OpenStream(messageProvider, arguments.Win32Manifest, arguments.BaseDirectory, messageProvider.ERR_CantOpenWin32Manifest, errorList));
 }
예제 #20
0
 protected Stream GetWin32Resources(CommandLineArguments arguments, Compilation compilation, out IEnumerable <DiagnosticInfo> errors)
 {
     return(GetWin32ResourcesInternal(MessageProvider, arguments, compilation, out errors));
 }
예제 #21
0
        // internal for testing
        internal static Stream GetWin32ResourcesInternal(CommonMessageProvider messageProvider, CommandLineArguments arguments, Compilation compilation, out IEnumerable <DiagnosticInfo> errors)
        {
            List <DiagnosticInfo> errorList = new List <DiagnosticInfo>();

            errors = errorList;

            if (arguments.Win32ResourceFile != null)
            {
                return(OpenStream(messageProvider, arguments.Win32ResourceFile, arguments.BaseDirectory, messageProvider.GetFieldOrProperty <int>("ERR_CantOpenWin32Resource"), errorList));
            }

            using (Stream manifestStream = OpenManifestStream(messageProvider, compilation.Options.OutputKind, arguments, errorList))
            {
                using (Stream iconStream = OpenStream(messageProvider, arguments.Win32Icon, arguments.BaseDirectory, messageProvider.GetFieldOrProperty <int>("ERR_CantOpenWin32Icon"), errorList))
                {
                    try
                    {
                        return(compilation.CreateDefaultWin32Resources(true, arguments.NoWin32Manifest, manifestStream, iconStream));
                    }
                    catch (Exception ex) when(ex.GetType().FullName == "Microsoft.CodeAnalysis.ResourceException")
                    {
                        errorList.Add(ReflDiagnosticInfo.ctor(messageProvider, messageProvider.GetFieldOrProperty <int>("ERR_ErrorBuildingWin32Resource"), new[] { ex.Message }));
                    }
                    catch (OverflowException ex)
                    {
                        errorList.Add(ReflDiagnosticInfo.ctor(messageProvider, messageProvider.GetFieldOrProperty <int>("ERR_ErrorBuildingWin32Resource"), new[] { ex.Message }));
                    }
                }
            }

            return(null);
        }
예제 #22
0
        protected override ParseOptions CreateParseOptions(CommandLineArguments commandLineArguments)
        {
            // Get the base parse options and override the defaults with the options from state.
            var options = (CSharpParseOptions)base.CreateParseOptions(commandLineArguments);
            var symbols = GetStringOption(CompilerOptions.OPTID_CCSYMBOLS, defaultValue: "").Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

            DocumentationMode documentationMode = DocumentationMode.Parse;
            if (GetStringOption(CompilerOptions.OPTID_XML_DOCFILE, defaultValue: null) != null)
            {
                documentationMode = DocumentationMode.Diagnose;
            }

            var languageVersion = CompilationOptionsConversion.GetLanguageVersion(GetStringOption(CompilerOptions.OPTID_COMPATIBILITY, defaultValue: ""))
                                  ?? CSharpParseOptions.Default.LanguageVersion;

            return options.WithKind(SourceCodeKind.Regular)
                .WithLanguageVersion(languageVersion)
                .WithPreprocessorSymbols(symbols.AsImmutable())
                .WithDocumentationMode(documentationMode);
        }
예제 #23
0
 private static Stream OpenManifestStream(CommonMessageProvider messageProvider, OutputKind outputKind, CommandLineArguments arguments, List <DiagnosticInfo> errorList)
 {
     return(outputKind == OutputKind.NetModule
         ? null
         : OpenStream(messageProvider, arguments.Win32Manifest, arguments.BaseDirectory, messageProvider.GetFieldOrProperty <int>("ERR_CantOpenWin32Manifest"), errorList));
 }
예제 #24
0
 private static Stream OpenManifestStream(CommonMessageProvider messageProvider, OutputKind outputKind, CommandLineArguments arguments, List<DiagnosticInfo> errorList)
 {
     return outputKind.IsNetModule()
         ? null
         : OpenStream(messageProvider, arguments.Win32Manifest, arguments.BaseDirectory, messageProvider.ERR_CantOpenWin32Manifest, errorList);
 }
예제 #25
0
        // internal for testing
        internal static Stream GetWin32ResourcesInternal(CommonMessageProvider messageProvider, CommandLineArguments arguments, Compilation compilation, out IEnumerable <DiagnosticInfo> errors)
        {
            List <DiagnosticInfo> errorList = new List <DiagnosticInfo>();

            errors = errorList;

            if (arguments.Win32ResourceFile != null)
            {
                return(OpenStream(messageProvider, arguments.Win32ResourceFile, arguments.BaseDirectory, messageProvider.ERR_CantOpenWin32Resource, errorList));
            }

            using (Stream manifestStream = OpenManifestStream(messageProvider, compilation.Options.OutputKind, arguments, errorList))
            {
                using (Stream iconStream = OpenStream(messageProvider, arguments.Win32Icon, arguments.BaseDirectory, messageProvider.ERR_CantOpenWin32Icon, errorList))
                {
                    try
                    {
                        return(compilation.CreateDefaultWin32Resources(true, arguments.NoWin32Manifest, manifestStream, iconStream));
                    }
                    catch (ResourceException ex)
                    {
                        errorList.Add(new DiagnosticInfo(messageProvider, messageProvider.ERR_ErrorBuildingWin32Resource, ex.Message));
                    }
                    catch (OverflowException ex)
                    {
                        errorList.Add(new DiagnosticInfo(messageProvider, messageProvider.ERR_ErrorBuildingWin32Resource, ex.Message));
                    }
                }
            }

            return(null);
        }
예제 #26
0
 /// <summary>
 /// Sets the given command line arguments to be the last parsed command line arguments.
 /// </summary>
 protected void SetArguments(CommandLineArguments commandLineArguments)
 {
     _lastParsedCommandLineArguments = commandLineArguments;
 }
예제 #27
0
        private static IReadOnlySet<string> GetEmbedddedSourcePaths(CommandLineArguments arguments)
        {
            if (arguments.EmbeddedFiles.IsEmpty)
            {
                return SpecializedCollections.EmptyReadOnlySet<string>();
            }

            // Note that we require an exact match between source and embedded file paths (case-sensitive
            // and without normalization). If two files are the same but spelled differently, they will
            // be handled as separate files, meaning the embedding pass will read the content a second
            // time. This can also lead to more than one document entry in the PDB for the same document
            // if the PDB document de-duping policy in emit (normalize + case-sensitive in C#,
            // normalize + case-insensitive in VB) is not enough to converge them.
            var set = new HashSet<string>(arguments.EmbeddedFiles.Select(f => f.Path));
            set.IntersectWith(arguments.SourceFiles.Select(f => f.Path));
            return SpecializedCollections.StronglyTypedReadOnlySet(set);
        }
예제 #28
0
        protected override CompilationOptions CreateCompilationOptions(CommandLineArguments commandLineArguments, ParseOptions newParseOptions)
        {
            // Get the base options from command line arguments + common workspace defaults.
            var options = (CSharpCompilationOptions)base.CreateCompilationOptions(commandLineArguments, newParseOptions);

            // Now override these with the options from our state.
            IDictionary<string, ReportDiagnostic> ruleSetSpecificDiagnosticOptions = null;

            // Get options from the ruleset file, if any, first. That way project-specific
            // options can override them.
            ReportDiagnostic? ruleSetGeneralDiagnosticOption = null;
            if (this.RuleSetFile != null)
            {
                ruleSetGeneralDiagnosticOption = this.RuleSetFile.GetGeneralDiagnosticOption();
                ruleSetSpecificDiagnosticOptions = new Dictionary<string, ReportDiagnostic>(this.RuleSetFile.GetSpecificDiagnosticOptions());
            }
            else
            {
                ruleSetSpecificDiagnosticOptions = new Dictionary<string, ReportDiagnostic>();
            }

            UpdateRuleSetError(this.RuleSetFile);

            ReportDiagnostic generalDiagnosticOption;
            var warningsAreErrors = GetNullableBooleanOption(CompilerOptions.OPTID_WARNINGSAREERRORS);
            if (warningsAreErrors.HasValue)
            {
                generalDiagnosticOption = warningsAreErrors.Value ? ReportDiagnostic.Error : ReportDiagnostic.Default;
            }
            else if (ruleSetGeneralDiagnosticOption.HasValue)
            {
                generalDiagnosticOption = ruleSetGeneralDiagnosticOption.Value;
            }
            else
            {
                generalDiagnosticOption = ReportDiagnostic.Default;
            }

            // Start with the rule set options
            IDictionary<string, ReportDiagnostic> diagnosticOptions = new Dictionary<string, ReportDiagnostic>(ruleSetSpecificDiagnosticOptions);

            // Update the specific options based on the general settings
            if (warningsAreErrors.HasValue && warningsAreErrors.Value == true)
            {
                foreach (var pair in ruleSetSpecificDiagnosticOptions)
                {
                    if (pair.Value == ReportDiagnostic.Warn)
                    {
                        diagnosticOptions[pair.Key] = ReportDiagnostic.Error;
                    }
                }
            }

            // Update the specific options based on the specific settings
            foreach (var diagnosticID in ParseWarningCodes(CompilerOptions.OPTID_WARNASERRORLIST))
            {
                diagnosticOptions[diagnosticID] = ReportDiagnostic.Error;
            }

            foreach (var diagnosticID in ParseWarningCodes(CompilerOptions.OPTID_WARNNOTASERRORLIST))
            {
                ReportDiagnostic ruleSetOption;
                if (ruleSetSpecificDiagnosticOptions.TryGetValue(diagnosticID, out ruleSetOption))
                {
                    diagnosticOptions[diagnosticID] = ruleSetOption;
                }
                else
                {
                    diagnosticOptions[diagnosticID] = ReportDiagnostic.Default;
                }
            }

            foreach (var diagnosticID in ParseWarningCodes(CompilerOptions.OPTID_NOWARNLIST))
            {
                diagnosticOptions[diagnosticID] = ReportDiagnostic.Suppress;
            }

            Platform platform;

            if (!Enum.TryParse(GetStringOption(CompilerOptions.OPTID_PLATFORM, ""), ignoreCase: true, result: out platform))
            {
                platform = Platform.AnyCpu;
            }

            int warningLevel;

            if (!int.TryParse(GetStringOption(CompilerOptions.OPTID_WARNINGLEVEL, defaultValue: ""), out warningLevel))
            {
                warningLevel = 4;
            }

            // TODO: appConfigPath: GetFilePathOption(CompilerOptions.OPTID_FUSIONCONFIG), bug #869604

            return options.WithAllowUnsafe(GetBooleanOption(CompilerOptions.OPTID_UNSAFE))
                .WithOverflowChecks(GetBooleanOption(CompilerOptions.OPTID_CHECKED))
                .WithCryptoKeyContainer(GetStringOption(CompilerOptions.OPTID_KEYNAME, defaultValue: null))
                .WithCryptoKeyFile(GetFilePathRelativeOption(CompilerOptions.OPTID_KEYFILE))
                .WithDelaySign(GetNullableBooleanOption(CompilerOptions.OPTID_DELAYSIGN))
                .WithGeneralDiagnosticOption(generalDiagnosticOption)
                .WithMainTypeName(_mainTypeName)
                .WithModuleName(GetStringOption(CompilerOptions.OPTID_MODULEASSEMBLY, defaultValue: null))
                .WithOptimizationLevel(GetBooleanOption(CompilerOptions.OPTID_OPTIMIZATIONS) ? OptimizationLevel.Release : OptimizationLevel.Debug)
                .WithOutputKind(_outputKind)
                .WithPlatform(platform)
                .WithSpecificDiagnosticOptions(diagnosticOptions)
                .WithWarningLevel(warningLevel);
        }
예제 #29
0
 /// <summary>
 /// Sets the given command line arguments to be the last parsed command line arguments and
 /// creates and sets new options using these command line arguments.
 /// </summary>
 protected void SetArgumentsAndUpdateOptions(CommandLineArguments commandLineArguments)
 {
     SetArguments(commandLineArguments);
     UpdateOptions();
 }