Esempio n. 1
0
        public static bool TryGetBooleanOption(
            this AnalyzerConfigOptions options,
            string optionName,
            out bool optionValue)
        {
            if (options is null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (optionName is null)
            {
                throw new ArgumentNullException(nameof(optionName));
            }

            optionValue = default;

            if (options.TryGetValue(optionName, out var strValue) &&
                bool.TryParse(strValue, out var boolValue))
            {
                optionValue = boolValue;
                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        internal static bool TryGetValueAsBool(this AnalyzerConfigOptions analyzerConfigOptions, string key, out bool value)
        {
            value = false;

            return(analyzerConfigOptions.TryGetValue(key, out string rawValue) &&
                   bool.TryParse(rawValue, out value));
        }
Esempio n. 3
0
        public static int GetLargeStructThreshold(AnalyzerConfigOptions options)
        {
            if (!options.TryGetValue("error_prone.large_struct_threshold", out var thresholdString) ||
                string.IsNullOrEmpty(thresholdString) ||
                thresholdString == "unset")
            {
                return(DefaultLargeStructThreshold);
            }

            if (thresholdString.Length > 6)
            {
                // A threshold of 1MB or larger is a configuration error. Return early to ensure the code below will not
                // overflow.
                return(MaxLargeStructThreshold);
            }

            // Fast string to int
            var result = 0;

            foreach (var ch in thresholdString)
            {
                if (ch < '0' || ch > '9')
                {
                    return(DefaultLargeStructThreshold);
                }

                result = result * 10 + (ch - '0');
            }

            return(result);
        }
Esempio n. 4
0
            public override bool TryGetValue(string key, [NotNullWhen(true)] out string?value)
            {
                if (_workspaceOptions.TryGetValue(key, out value))
                {
                    return(true);
                }

                if (!_result.HasValue)
                {
                    value = null;
                    return(false);
                }

                if (_result.Value.AnalyzerOptions.TryGetValue(key, out value))
                {
                    return(true);
                }

                var diagnosticKey = "dotnet_diagnostic.(?<key>.*).severity";
                var match         = Regex.Match(key, diagnosticKey);

                if (match.Success && match.Groups["key"].Value is string isolatedKey &&
                    _result.Value.TreeOptions.TryGetValue(isolatedKey, out var severity))
                {
                    value = severity.ToEditorConfigString();
                    return(true);
                }

                value = null;
                return(false);
            }
Esempio n. 5
0
 public static string GetValueOrDefault(this AnalyzerConfigOptions options, string key, string defaultValue)
 {
     if (options.TryGetValue(key, out var value))
     {
         return(value);
     }
     return(defaultValue);
 }
Esempio n. 6
0
            public override bool TryGetValue(string key, out string value)
            {
                if (_options.TryGetValue(key, out value))
                {
                    return(true);
                }

                return(_fallbackOptions.TryGetValue(key, out value));
            }
Esempio n. 7
0
        private static bool TryGetEditorConfigOption <T>(
            this AnalyzerConfigOptions analyzerConfigOptions,
            TOption option,
            bool useDefaultIfMissing,
            out T?value
            )
        {
            var hasEditorConfigStorage = false;

            foreach (var storageLocation in option.StorageLocations)
            {
                // This code path will avoid allocating a Dictionary wrapper since we can get direct access to the KeyName.
                if (
                    storageLocation is EditorConfigStorageLocation <T> editorConfigStorageLocation &&
                    analyzerConfigOptions.TryGetValue(
                        editorConfigStorageLocation.KeyName,
                        out var stringValue
                        ) &&
                    editorConfigStorageLocation.TryGetOption(stringValue, typeof(T), out value)
                    )
                {
                    return(true);
                }

                if (!(storageLocation is IEditorConfigStorageLocation configStorageLocation))
                {
                    continue;
                }

                // This option has .editorconfig storage defined, even if the current configuration does not provide a
                // value for it.
                hasEditorConfigStorage = true;
                if (
                    configStorageLocation.TryGetOption(
                        analyzerConfigOptions,
                        option.Type,
                        out var objectValue
                        )
                    )
                {
                    value = (T)objectValue;
                    return(true);
                }
            }

            if (useDefaultIfMissing)
            {
                value = (T?)option.DefaultValue;
                return(hasEditorConfigStorage);
            }
            else
            {
                value = default;
                return(false);
            }
        }
Esempio n. 8
0
        public static ReportDiagnostic GetEffectiveSeverity(this DiagnosticDescriptor descriptor, AnalyzerConfigOptions analyzerConfigOptions)
        {
            // Check if the option is defined explicitly in the editorconfig
            var diagnosticKey = $"{DotnetDiagnosticPrefix}.{descriptor.Id}.{SeveritySuffix}";

            if (analyzerConfigOptions.TryGetValue(diagnosticKey, out var value) &&
                EditorConfigSeverityStrings.TryParse(value, out var severity))
            {
                return(severity);
            }

            // Check if the option is defined as part of a bulk configuration
            // Analyzer bulk configuration does not apply to:
            //  1. Disabled by default diagnostics
            //  2. Compiler diagnostics
            //  3. Non-configurable diagnostics
            if (!descriptor.IsEnabledByDefault ||
                descriptor.ImmutableCustomTags().Any(tag => tag is WellKnownDiagnosticTags.Compiler or WellKnownDiagnosticTags.NotConfigurable))
            {
                return(ReportDiagnostic.Default);
            }

            // If user has explicitly configured default severity for the diagnostic category, that should be respected.
            // For example, 'dotnet_analyzer_diagnostic.category-security.severity = error'
            var categoryBasedKey = $"{DotnetAnalyzerDiagnosticPrefix}.{CategoryPrefix}-{descriptor.Category}.{SeveritySuffix}";

            if (analyzerConfigOptions.TryGetValue(categoryBasedKey, out value) &&
                EditorConfigSeverityStrings.TryParse(value, out severity))
            {
                return(severity);
            }

            // Otherwise, if user has explicitly configured default severity for all analyzer diagnostics, that should be respected.
            // For example, 'dotnet_analyzer_diagnostic.severity = error'
            if (analyzerConfigOptions.TryGetValue(DotnetAnalyzerDiagnosticSeverityKey, out value) &&
                EditorConfigSeverityStrings.TryParse(value, out severity))
            {
                return(severity);
            }

            // option not defined in editorconfig, assumed to be the default
            return(ReportDiagnostic.Default);
        }
Esempio n. 9
0
        private static string GetDependenciesLocation(AnalyzerConfigOptions globalOptions)
        {
            globalOptions.TryGetValue("build_property.servicemodelgrpcdesigntime_dependencies", out var dependencies);

            if (string.IsNullOrEmpty(dependencies) || !Directory.Exists(dependencies))
            {
                throw new InvalidOperationException(string.Format("Dependencies not found in [{0}].", dependencies));
            }

            return(dependencies !);
        }
        public static bool TryGetEndOfLine(AnalyzerConfigOptions analyzerConfigOptions, [NotNullWhen(true)] out string?endOfLine)
        {
            if (analyzerConfigOptions.TryGetValue("end_of_line", out var endOfLineOption))
            {
                endOfLine = GetEndOfLine(endOfLineOption);
                return(true);
            }

            endOfLine = null;
            return(false);
        }
Esempio n. 11
0
        public static string GetValue(AnalyzerConfigOptions configOptions, ConfigOptionDescriptor option, string defaultValue = null)
        {
            if (configOptions.TryGetValue(option.Key, out string value))
            {
                return(value);
            }

            return(defaultValue
                   ?? CodeAnalysisConfig.Instance.EditorConfig.Options.GetValueOrDefault(option.Key)
                   ?? option.DefaultValue);
        }
Esempio n. 12
0
        private static bool TryGetCharset(AnalyzerConfigOptions analyzerConfigOptions, [NotNullWhen(true)] out Encoding?encoding)
        {
            if (analyzerConfigOptions.TryGetValue("charset", out var charsetOption))
            {
                encoding = GetCharset(charsetOption);
                return(true);
            }

            encoding = null;
            return(false);
        }
Esempio n. 13
0
        internal override async Task <SourceText> FormatFileAsync(
            Document document,
            SourceText sourceText,
            OptionSet optionSet,
            AnalyzerConfigOptions analyzerConfigOptions,
            FormatOptions formatOptions,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            try
            {
                // Only run formatter if the user has specifically configured one of the driving properties.
                if (!analyzerConfigOptions.TryGetValue("dotnet_sort_system_directives_first", out _) &&
                    !analyzerConfigOptions.TryGetValue("dotnet_separate_import_directive_groups", out _))
                {
                    return(sourceText);
                }

                var organizedDocument = await Formatter.OrganizeImportsAsync(document, cancellationToken);

                var isSameVersion = await IsSameDocumentAndVersionAsync(document, organizedDocument, cancellationToken).ConfigureAwait(false);

                if (isSameVersion)
                {
                    return(sourceText);
                }

                // Because the Formatter does not abide the `end_of_line` option we have to fix up the ends of the organized lines.
                // See https://github.com/dotnet/roslyn/issues/44136
                var organizedSourceText = await organizedDocument.GetTextAsync(cancellationToken);

                return(await _endOfLineFormatter.FormatFileAsync(organizedDocument, organizedSourceText, optionSet, analyzerConfigOptions, formatOptions, logger, cancellationToken));
            }
            catch (InsufficientExecutionStackException)
            {
                // This case is normally not hit when running against a handwritten code file.
                // https://github.com/dotnet/roslyn/issues/44710#issuecomment-636253053
                logger.LogWarning(Resources.Unable_to_organize_imports_for_0_The_document_is_too_complex, Path.GetFileName(document.FilePath));
                return(sourceText);
            }
        }
Esempio n. 14
0
        public static bool TryGetOption(this IEditorConfigStorageLocation editorConfigStorageLocation, AnalyzerConfigOptions analyzerConfigOptions, Type type, out object value)
        {
            var optionDictionary = analyzerConfigOptions.Keys.ToImmutableDictionary(
                key => key,
                key =>
            {
                analyzerConfigOptions.TryGetValue(key, out var optionValue);
                return(optionValue);
            });

            return(editorConfigStorageLocation.TryGetOption(optionDictionary, type, out value));
        }
Esempio n. 15
0
        public static bool?GetValueAsBool(AnalyzerConfigOptions configOptions, ConfigOptionDescriptor option, bool?defaultValue = null)
        {
            if (configOptions.TryGetValue(option.Key, out string rawValue) &&
                bool.TryParse(rawValue, out bool boolValue))
            {
                return(boolValue);
            }

            return(defaultValue
                   ?? CodeAnalysisConfig.Instance.GetOptionAsBool(option.Key)
                   ?? option.DefaultValueAsBool);
        }
Esempio n. 16
0
        public static int GetMaxLineLength(this AnalyzerConfigOptions configOptions)
        {
            if (configOptions.TryGetValue(ConfigOptionKeys.MaxLineLength, out string rawValue) &&
                int.TryParse(rawValue, out int value))
            {
                return(value);
            }

            if (CodeAnalysisConfig.Instance.MaxLineLength != null)
            {
                return(CodeAnalysisConfig.Instance.MaxLineLength.Value);
            }

            if (configOptions.TryGetValue(LegacyConfigOptions.MaxLineLength.Key, out rawValue) &&
                int.TryParse(rawValue, out value))
            {
                return(value);
            }

            return(ConfigOptionDefaultValues.MaxLineLength);
        }
Esempio n. 17
0
        internal static bool?GetIsGeneratedCodeFromOptions(AnalyzerConfigOptions options)
        {
            // Check for explicit user configuration for generated code.
            //     generated_code = true | false
            if (options.TryGetValue("generated_code", out string?optionValue) &&
                bool.TryParse(optionValue, out var boolValue))
            {
                return(boolValue);
            }

            // Either no explicit user configuration or we don't recognize the option value.
            return(null);
        }
Esempio n. 18
0
        public static bool TryGetValue(AnalyzerConfigOptions configOptions, ConfigOptionDescriptor option, out string value, string defaultValue = null)
        {
            if (configOptions.TryGetValue(option.Key, out string rawValue))
            {
                value = rawValue;
                return(true);
            }

            value = defaultValue
                    ?? CodeAnalysisConfig.Instance.EditorConfig.Options.GetValueOrDefault(option.Key)
                    ?? option.DefaultValue;

            return(value != null);
        }
Esempio n. 19
0
        public static Options Read(AnalyzerConfigOptions configOptions)
        {
            try
            {
                if (configOptions.TryGetValue("build_property.nullableextendedanalyzer", out var options) &&
                    !string.IsNullOrEmpty(options))
                {
                    return(Deserialize(options));
                }
            }
            catch
            {
                // just go with default options
            }

            return(new Options());
        }
Esempio n. 20
0
        internal override async Task <SourceText> FormatFileAsync(
            Document document,
            SourceText sourceText,
            OptionSet optionSet,
            AnalyzerConfigOptions analyzerConfigOptions,
            FormatOptions formatOptions,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            if (!analyzerConfigOptions.TryGetValue("insert_final_newline", out var insertFinalNewlineValue) ||
                !bool.TryParse(insertFinalNewlineValue, out var insertFinalNewline))
            {
                return(await document.GetTextAsync(cancellationToken).ConfigureAwait(false));
            }

            if (!EndOfLineFormatter.TryGetEndOfLine(analyzerConfigOptions, out var endOfLine))
            {
                endOfLine = Environment.NewLine;
            }

            var lastLine        = sourceText.Lines.Last();
            var hasFinalNewline = lastLine.Span.IsEmpty;

            if (insertFinalNewline && !hasFinalNewline)
            {
                var finalNewlineSpan = new TextSpan(lastLine.End, 0);
                var addNewlineChange = new TextChange(finalNewlineSpan, endOfLine);
                sourceText = sourceText.WithChanges(addNewlineChange);
            }
            else if (!insertFinalNewline && hasFinalNewline)
            {
                // In the case of empty files where there is a single empty line, there is nothing to remove.
                while (sourceText.Lines.Count > 1 && hasFinalNewline)
                {
                    var lineBeforeLast      = sourceText.Lines[sourceText.Lines.Count - 2];
                    var finalNewlineSpan    = new TextSpan(lineBeforeLast.End, lineBeforeLast.EndIncludingLineBreak - lineBeforeLast.End);
                    var removeNewlineChange = new TextChange(finalNewlineSpan, string.Empty);
                    sourceText = sourceText.WithChanges(removeNewlineChange);

                    lastLine        = sourceText.Lines.Last();
                    hasFinalNewline = lastLine.Span.IsEmpty;
                }
            }

            return(sourceText);
        }
        public static bool IsDefinedInEditorConfig(this DiagnosticDescriptor descriptor, AnalyzerConfigOptions analyzerConfigOptions)
        {
            // Check if the option is defined explicitly in the editorconfig
            var diagnosticKey = $"{DotnetDiagnosticPrefix}.{descriptor.Id}.{SeveritySuffix}";

            if (analyzerConfigOptions.TryGetValue(diagnosticKey, out var value) &&
                EditorConfigSeverityStrings.TryParse(value, out var severity))
            {
                return(true);
            }

            // Check if the option is defined as part of a bulk configuration
            // Analyzer bulk configuration does not apply to:
            //  1. Disabled by default diagnostics
            //  2. Compiler diagnostics
            //  3. Non-configurable diagnostics
            if (!descriptor.IsEnabledByDefault ||
                descriptor.ImmutableCustomTags().Any(static tag => tag is WellKnownDiagnosticTags.Compiler or WellKnownDiagnosticTags.NotConfigurable))
        internal override async Task <SourceText> FormatFileAsync(
            Document document,
            SourceText sourceText,
            OptionSet optionSet,
            AnalyzerConfigOptions analyzerConfigOptions,
            FormatOptions formatOptions,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            if (!analyzerConfigOptions.TryGetValue("insert_final_newline", out var insertFinalNewlineValue) ||
                !bool.TryParse(insertFinalNewlineValue, out var insertFinalNewline))
            {
                return(await document.GetTextAsync(cancellationToken).ConfigureAwait(false));
            }

            if (!EndOfLineFormatter.TryGetEndOfLine(analyzerConfigOptions, out var endOfLine))
            {
                endOfLine = Environment.NewLine;
            }

            var lastLine        = sourceText.Lines[^ 1];
Esempio n. 23
0
        public static bool TryGetValueAsBool(AnalyzerConfigOptions configOptions, ConfigOptionDescriptor option, out bool value, bool?defaultValue = null)
        {
            if (configOptions.TryGetValue(option.Key, out string rawValue) &&
                bool.TryParse(rawValue, out bool boolValue))
            {
                value = boolValue;
                return(true);
            }

            bool?maybeValue = defaultValue
                              ?? CodeAnalysisConfig.Instance.GetOptionAsBool(option.Key)
                              ?? option.DefaultValueAsBool;

            if (maybeValue != null)
            {
                value = maybeValue.Value;
                return(true);
            }

            value = false;
            return(false);
        }
Esempio n. 24
0
        private static List <RazorPageItem> DiscoverRazorPages(IEnumerable <AdditionalText> additionalFiles, Compilation compilation, AnalyzerConfigOptions configOptions)
        {
            // Discover .cshtml files in AdditionalFiles.
            var cshtmlFiles = additionalFiles
                              .Where(file => file.Path.EndsWith(".cshtml"))
                              .ToList();

            // If no .cshtml in AdditionalFiles, try get MSBuildProjectDirectory and look in there.
            if (!cshtmlFiles.Any() && configOptions.TryGetValue("build_property.MSBuildProjectDirectory", out var projectDirectory) && !string.IsNullOrEmpty(projectDirectory))
            {
                cshtmlFiles = Directory.EnumerateFiles(projectDirectory, "*.cshtml", SearchOption.AllDirectories)
                              .Select(file => (AdditionalText) new FileSystemAdditionalText(file.Substring(projectDirectory.Length), projectDirectory))
                              .ToList();
            }

            var pages = cshtmlFiles
                        .Where(PagesFacts.IsRazorPage)
                        .Select(file => new RazorPageItem(file))
                        .ToList();

            return(pages);
        }
        public static bool TryGetEditorConfigOption <T>(this AnalyzerConfigOptions analyzerConfigOptions, IOption option, out T value)
        {
            foreach (var storageLocation in option.StorageLocations)
            {
                // This code path will avoid allocating a Dictionary wrapper since we can get direct access to the KeyName.
                if (storageLocation is EditorConfigStorageLocation <T> editorConfigStorageLocation &&
                    analyzerConfigOptions.TryGetValue(editorConfigStorageLocation.KeyName, out var stringValue) &&
                    editorConfigStorageLocation.TryGetOption(stringValue, typeof(T), out value))
                {
                    return(true);
                }

                if (storageLocation is IEditorConfigStorageLocation configStorageLocation &&
                    configStorageLocation.TryGetOption(analyzerConfigOptions, option.Type, out var objectValue))
                {
                    value = (T)objectValue;
                    return(true);
                }
            }

            value = default;
            return(false);
        }
Esempio n. 26
0
 public static string?TryGetAdditionalFileMetadataValue(this AnalyzerConfigOptions options, string propertyName) =>
 options.TryGetValue($"build_metadata.AdditionalFiles.{propertyName}");
Esempio n. 27
0
 public static string?TryGetValue(this AnalyzerConfigOptions options, string key) =>
 options.TryGetValue(key, out var value) ? value : null;
Esempio n. 28
0
 internal static string?SingleTestDisplayName(this AnalyzerConfigOptions options) => options.TryGetValue(SingleTestDisplayNameOption, out string?displayName) ? displayName : null;
Esempio n. 29
0
 internal static string?TestAssemblyRelativePath(this AnalyzerConfigOptions options) => options.TryGetValue(TestAssemblyRelativePathOption, out string?relativePath) ? relativePath : null;
Esempio n. 30
0
 internal static string?TestFilter(this AnalyzerConfigOptions options) => options.TryGetValue(TestFilterOption, out string?filter) ? filter : null;