Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Editorconfig vs Global analyzerconfig #47707

@mavasani

Description

@mavasani

Editorconfig

  • Starting VS2019 16.3, Roslyn compiler and IDE supports analyzer and source generator configuration via regular .editorconfig files for configuration that applies to specific source files and/or folders within a project, applicable files and/or folders are selected by section headers.

  • Designed to work well will existing .editorconfig files used to configure editor style settings for different IDEs.

  • File/directory based discovery and configuration:

    • Implicitly discovered by the project system by walking the file system and passed to the compiler
    • All supported analyzer configuration entries must be under section headers to select applicable files and/or folders. Configuration entries not under a section header are ignored by the compiler.
  • Core scenarios: Support end user analyzer and source generator configuration via below entries:

    • Options: Key-value pair entries of the form key = value for analyzer config options passed to analyzers and source generators
    • Diagnostic severity settings: Certain well-known key value pairs as per the syntax here and here to configure diagnostic severity of analyzer diagnostics and compiler warnings.
  • Conflict resolution:

    • Regular editorconfig conflict resolution mechanism is applied so that editorconfig files deeper in the directory structure override the settings from editorconfig files that are higher up.
    • Highest precedence for diagnostic severity configuration entries: Overrides diagnostic severity settings that come from command line options (/nowarn, /warnaserror) and entries coming from ruleset or global analyzerconfig files.
  • Example:

# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true

# C# files
[*.cs]

#### Core EditorConfig Options ####

# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4

#### .NET Coding Conventions ####

# this. and Me. preferences
dotnet_style_qualification_for_method = true:warning

#### Diagnostic configuration ####

# CA1000: Do not declare static members on generic types
dotnet_diagnostic.CA1000.severity = warning

Global analyzerconfig

  • Starting VS2019 16.7, Roslyn compiler and IDE supports special global, compilation level analyzer/source generator configuration files for specifying configuration that applies to all the source files in the compilation/project, regardless of the actual file names or file paths of these source files.

  • Unlike editorconfig files, these are not designed to configure editor style settings for different IDEs.

    • File name: No restrictions or requirements
    • File format:
      • Simple key-value pair configuration entries of the form key = value
      • Must contain a top level entry of the form is_global = true
      • Can contain section headers, as long as the headers specify an absolute file path. Section headers based on globbing or relative file paths are ignored.
  • File/directory agnostic configuration:

    • No implicit discovery: Need to be explicitly specified in the MSBuild targets/project file to be passed to the compiler:
      <ItemGroup>
        <EditorConfgFiles Include="<%path_to_global_analyzer_config%>" />
      </ItemGroup>
    • No globbing or relative file path based section headers allowed: All supported analyzer configuration entries must either be top level without section header OR section header must have an absolute file path. Entries under any section headers that are based on globs, say [*.cs] or [*], or section headers that use relative file paths are ignored.
  • Core scenarios: Support identical analyzer configuration entries as editorconfig files, but for different core scenarios:

    • Allow NuGet packages and SDKs to ship compilation level analyzer configuration files that apply to all source files in the project, regardless of the actual file names or file paths of these source files.
    • Allow passing in project-level MSBuild property values and item metadata to analyzers and source generators: Details here
    • Allow configuration of no-location analyzer diagnostics that do not have a file path and hence cannot be configured via regular editorconfig files.
  • Conflict resolution:

    • Entries with same key coming from different global analyzerconfig files are ignored and compiler generates warnings about each of these conflicts.
    • Lowest precedence for option configuration entries: For entries with same key coming from a global analyzerconfig and editorconfig file, the editorconfig file entry always overrides the global analyzerconfig entry
    • Lowest precedence for diagnostic severity configuration entries: Diagnostic severity settings that come from editorconfig files and those that come from command line options (/nowarn, /warnaserror) always override the entries from global analyzerconfig files.
  • Example:

# Top level entry required to mark this as a global analyzer config file
is_global = true

# NOTE: No section headers for configuration entries

#### .NET Coding Conventions ####

# this. and Me. preferences
dotnet_style_qualification_for_method = true:warning

#### Diagnostic configuration ####

# CA1000: Do not declare static members on generic types
dotnet_diagnostic.CA1000.severity = warning

Confusion points

The core points of confusion are:

  • Both file kinds have a similar end user goal of configuring analyzers and/or source generators, even though they have completely orthogonal purposes - path based vs path agnostic configuration for source files in the compilation.
  • Both files have similar format for the core configuration entries: key-value pair based entries, including support for the well-known diagnostic severity configuration entries
  • Use of same compiler switch for both files + Use of the editorconfig terminology in the MSBuild item name to specify global analyzerconfig files, i.e. <EditorConfgFiles Include="path_to_global_analyzer_config"/>. This was done to reduce the engineering cost on project system side, especially legacy project system. However, this makes the user feel the file name and format must match regular .editorconfig files, including use of globbing based section headers. For example, classic user mistake highlighted in the issue here.
  • Global analyzer config files can be named .editorconfig and things work just fine as long as entries abide by the global analyzerconfig's required format.
  • Global analyzer config files silently ignore analyzer configuration entries under section headers
  • Lack of tooling support in VS to create/edit global config files, so user has to manually do all the steps, making it hard to reason about the subtle differences between the two file formats.

Action items for future work

There are few action items that we plan to take up to reduce the above confusion:

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions