Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added ConfigFile to simplify AnalyzerConfigFile creation. #981

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;

namespace Microsoft.CodeAnalysis.Testing
{
public class ConfigFile : Dictionary<string, Dictionary<string, string>>
{
public string FileName { get; }

public Dictionary<string, string> Preamble { get; } = new Dictionary<string, string>();

public ConfigFile(string fileName)
{
FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
}

public new string this[string globalKey]
{
get
{
return Preamble[globalKey];
}

set
{
Preamble[globalKey] = value;
}
}

public string this[string sectionKey, string key]
{
get
{
if (!TryGetValue(sectionKey, out var values))
{
values = new Dictionary<string, string>();
base[sectionKey] = values;
}

return values[key];
}

set
{
if (!TryGetValue(sectionKey, out var values))
{
values = new Dictionary<string, string>();
base[sectionKey] = values;
}

values[key] = value;
}
}

public void Add(string globalKey, string value)
{
Preamble.Add(globalKey, value);
}

public void Add(string sectionKey, string key, string value)
{
if (!TryGetValue(sectionKey, out var values))
{
values = new Dictionary<string, string>();
base[sectionKey] = values;
}

values.Add(key, value);
}

private static string ToString(Dictionary<string, string> dictionary)
{
return string.Join(
Environment.NewLine,
dictionary.Select(pair => $@"{pair.Key} = {pair.Value}"));
}

private static string ToString(Dictionary<string, Dictionary<string, string>> dictionary)
{
return string.Join(
Environment.NewLine,
dictionary.Select(pair => $@"[{pair.Key}]
{ToString(pair.Value)}"));
}

public override string ToString()
{
return @$"
{ToString(Preamble)}

{ToString(this)}
";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Text;
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.CodeAnalysis.Testing
{
public class ConfigFileCollection : SourceFileCollection
{
public void Add(ConfigFile file)
{
Add((file.FileName, SourceText.From(file.ToString(), Encoding.UTF8)));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Microsoft.CodeAnalysis.Testing
{
public class EditorConfigFile : ConfigFile
{
public EditorConfigFile()
: base("/.editorconfig")
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Microsoft.CodeAnalysis.Testing
{
public class GlobalConfigFile : ConfigFile
{
public GlobalConfigFile()
: base("/.globalconfig")
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ internal ProjectState(ProjectState sourceState)

public SourceFileCollection AdditionalFiles { get; } = new SourceFileCollection();

public SourceFileCollection AnalyzerConfigFiles { get; } = new SourceFileCollection();
public ConfigFileCollection AnalyzerConfigFiles { get; } = new ConfigFileCollection();

public List<Func<IEnumerable<(string filename, SourceText content)>>> AdditionalFilesFactories { get; } = new List<Func<IEnumerable<(string filename, SourceText content)>>>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,19 @@ Microsoft.CodeAnalysis.Testing.CompilerDiagnostics.Errors = 1 -> Microsoft.CodeA
Microsoft.CodeAnalysis.Testing.CompilerDiagnostics.None = 0 -> Microsoft.CodeAnalysis.Testing.CompilerDiagnostics
Microsoft.CodeAnalysis.Testing.CompilerDiagnostics.Suggestions = 3 -> Microsoft.CodeAnalysis.Testing.CompilerDiagnostics
Microsoft.CodeAnalysis.Testing.CompilerDiagnostics.Warnings = 2 -> Microsoft.CodeAnalysis.Testing.CompilerDiagnostics
Microsoft.CodeAnalysis.Testing.ConfigFile
Microsoft.CodeAnalysis.Testing.ConfigFile.Add(string globalKey, string value) -> void
Microsoft.CodeAnalysis.Testing.ConfigFile.Add(string sectionKey, string key, string value) -> void
Microsoft.CodeAnalysis.Testing.ConfigFile.ConfigFile(string fileName) -> void
Microsoft.CodeAnalysis.Testing.ConfigFile.FileName.get -> string
Microsoft.CodeAnalysis.Testing.ConfigFile.Preamble.get -> System.Collections.Generic.Dictionary<string, string>
Microsoft.CodeAnalysis.Testing.ConfigFile.this[string globalKey].get -> string
Microsoft.CodeAnalysis.Testing.ConfigFile.this[string globalKey].set -> void
Microsoft.CodeAnalysis.Testing.ConfigFile.this[string sectionKey, string key].get -> string
Microsoft.CodeAnalysis.Testing.ConfigFile.this[string sectionKey, string key].set -> void
Microsoft.CodeAnalysis.Testing.ConfigFileCollection
Microsoft.CodeAnalysis.Testing.ConfigFileCollection.Add(Microsoft.CodeAnalysis.Testing.ConfigFile file) -> void
Microsoft.CodeAnalysis.Testing.ConfigFileCollection.ConfigFileCollection() -> void
Microsoft.CodeAnalysis.Testing.DefaultVerifier
Microsoft.CodeAnalysis.Testing.DefaultVerifier.Context.get -> System.Collections.Immutable.ImmutableStack<string>
Microsoft.CodeAnalysis.Testing.DefaultVerifier.DefaultVerifier() -> void
Expand Down Expand Up @@ -97,8 +110,12 @@ Microsoft.CodeAnalysis.Testing.DiagnosticResult.WithSpan(Microsoft.CodeAnalysis.
Microsoft.CodeAnalysis.Testing.DiagnosticResult.WithSpan(Microsoft.CodeAnalysis.FileLinePositionSpan span, Microsoft.CodeAnalysis.Testing.DiagnosticLocationOptions options) -> Microsoft.CodeAnalysis.Testing.DiagnosticResult
Microsoft.CodeAnalysis.Testing.DiagnosticResult.WithSpan(int startLine, int startColumn, int endLine, int endColumn) -> Microsoft.CodeAnalysis.Testing.DiagnosticResult
Microsoft.CodeAnalysis.Testing.DiagnosticResult.WithSpan(string path, int startLine, int startColumn, int endLine, int endColumn) -> Microsoft.CodeAnalysis.Testing.DiagnosticResult
Microsoft.CodeAnalysis.Testing.EditorConfigFile
Microsoft.CodeAnalysis.Testing.EditorConfigFile.EditorConfigFile() -> void
Microsoft.CodeAnalysis.Testing.EmptyDiagnosticAnalyzer
Microsoft.CodeAnalysis.Testing.EmptyDiagnosticAnalyzer.EmptyDiagnosticAnalyzer() -> void
Microsoft.CodeAnalysis.Testing.GlobalConfigFile
Microsoft.CodeAnalysis.Testing.GlobalConfigFile.GlobalConfigFile() -> void
Microsoft.CodeAnalysis.Testing.IVerifier
Microsoft.CodeAnalysis.Testing.IVerifier.Empty<T>(string collectionName, System.Collections.Generic.IEnumerable<T> collection) -> void
Microsoft.CodeAnalysis.Testing.IVerifier.Equal<T>(T expected, T actual, string message = null) -> void
Expand Down Expand Up @@ -153,7 +170,7 @@ Microsoft.CodeAnalysis.Testing.ProjectState.AdditionalFiles.get -> Microsoft.Cod
Microsoft.CodeAnalysis.Testing.ProjectState.AdditionalFilesFactories.get -> System.Collections.Generic.List<System.Func<System.Collections.Generic.IEnumerable<(string filename, Microsoft.CodeAnalysis.Text.SourceText content)>>>
Microsoft.CodeAnalysis.Testing.ProjectState.AdditionalProjectReferences.get -> System.Collections.Generic.List<string>
Microsoft.CodeAnalysis.Testing.ProjectState.AdditionalReferences.get -> Microsoft.CodeAnalysis.Testing.MetadataReferenceCollection
Microsoft.CodeAnalysis.Testing.ProjectState.AnalyzerConfigFiles.get -> Microsoft.CodeAnalysis.Testing.SourceFileCollection
Microsoft.CodeAnalysis.Testing.ProjectState.AnalyzerConfigFiles.get -> Microsoft.CodeAnalysis.Testing.ConfigFileCollection
Microsoft.CodeAnalysis.Testing.ProjectState.AssemblyName.get -> string
Microsoft.CodeAnalysis.Testing.ProjectState.DocumentationMode.get -> Microsoft.CodeAnalysis.DocumentationMode?
Microsoft.CodeAnalysis.Testing.ProjectState.DocumentationMode.set -> void
Expand Down Expand Up @@ -240,6 +257,7 @@ abstract Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.DefaultFileExt.g
abstract Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.GetDiagnosticAnalyzers() -> System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer>
abstract Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.Language.get -> string
abstract Microsoft.CodeAnalysis.Testing.CodeActionTest<TVerifier>.SyntaxKindType.get -> System.Type
override Microsoft.CodeAnalysis.Testing.ConfigFile.ToString() -> string
override Microsoft.CodeAnalysis.Testing.DiagnosticResult.ToString() -> string
override Microsoft.CodeAnalysis.Testing.EmptyDiagnosticAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext context) -> void
override Microsoft.CodeAnalysis.Testing.EmptyDiagnosticAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.DiagnosticDescriptor>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#if !NETCOREAPP1_1 && !NET46

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text;
using System.Threading.Tasks;
Expand Down Expand Up @@ -97,13 +98,6 @@ public async Task TestDiagnosticInAnalyzerConfigFileWithCombinedSyntaxDuplicate(
[Fact]
public async Task TestDiagnosticInAnalyzerConfigFileBraceNotTreatedAsMarkup()
{
var editorConfig = @"
root = true

[*]
key = {|Literal:value|}
";

await new CSharpTest
{
TestState =
Expand All @@ -112,13 +106,61 @@ public async Task TestDiagnosticInAnalyzerConfigFileBraceNotTreatedAsMarkup()
ExpectedDiagnostics = { new DiagnosticResult(HighlightBracesIfAnalyzerConfigMissingAnalyzer.Descriptor).WithLocation(1, 23) },
AnalyzerConfigFiles =
{
("/.editorconfig", SourceText.From(editorConfig, Encoding.UTF8)),
new EditorConfigFile
{
["root"] = "true",
["*", "key"] = "{|Literal:value|}",
},
},
MarkupHandling = MarkupMode.None,
},
}.RunAsync();
}

[Fact]
public void AnalyzerConfigFileViaDictionarySyntaxEquivalentToManualCreation()
{
var expected = @"
root = true

[*]
key = {|Literal:value|}
";

var actual = new EditorConfigFile
{
["root"] = "true",
["*", "key"] = "{|Literal:value|}",
}.ToString();

Assert.Equal(expected, actual);
}

[Fact]
public void AnalyzerConfigFileViaAddSyntaxEquivalentToManualCreation()
{
var expected = @"
root = true

[*]
key = {|Literal:value|}
";

var actual = new EditorConfigFile
{
{ "root", "true" },
{
"*", new Dictionary<string, string>
{
["key"] = "{|Literal:value|}",
}
},
{ "*", "key", "{|Literal:value|}" },
}.ToString();

Assert.Equal(expected, actual);
}

[DiagnosticAnalyzer(LanguageNames.CSharp)]
internal class HighlightBracesIfAnalyzerConfigMissingAnalyzer : DiagnosticAnalyzer
{
Expand Down