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); }
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)); }
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); }
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); }
public static string GetValueOrDefault(this AnalyzerConfigOptions options, string key, string defaultValue) { if (options.TryGetValue(key, out var value)) { return(value); } return(defaultValue); }
public override bool TryGetValue(string key, out string value) { if (_options.TryGetValue(key, out value)) { return(true); } return(_fallbackOptions.TryGetValue(key, out value)); }
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); } }
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); }
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); }
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); }
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); }
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); } }
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)); }
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); }
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); }
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); }
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); }
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()); }
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];
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); }
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); }
public static string?TryGetAdditionalFileMetadataValue(this AnalyzerConfigOptions options, string propertyName) => options.TryGetValue($"build_metadata.AdditionalFiles.{propertyName}");
public static string?TryGetValue(this AnalyzerConfigOptions options, string key) => options.TryGetValue(key, out var value) ? value : null;
internal static string?SingleTestDisplayName(this AnalyzerConfigOptions options) => options.TryGetValue(SingleTestDisplayNameOption, out string?displayName) ? displayName : null;
internal static string?TestAssemblyRelativePath(this AnalyzerConfigOptions options) => options.TryGetValue(TestAssemblyRelativePathOption, out string?relativePath) ? relativePath : null;
internal static string?TestFilter(this AnalyzerConfigOptions options) => options.TryGetValue(TestFilterOption, out string?filter) ? filter : null;