Skip to content

Commit

Permalink
Add support for .editorconfig documents
Browse files Browse the repository at this point in the history
  • Loading branch information
sharwell committed Feb 23, 2021
1 parent 6f9cf96 commit dfdbcb7
Show file tree
Hide file tree
Showing 12 changed files with 738 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,12 @@ protected virtual async Task<Project> CreateProjectImplAsync(EvaluatedProjectSta
var documentId = DocumentId.CreateNewId(additionalProjectId, debugName: newFileName);
solution = solution.AddAdditionalDocument(documentId, newFileName, source, filePath: newFileName);
}

foreach (var (newFileName, source) in projectState.AnalyzerConfigFiles)
{
var documentId = DocumentId.CreateNewId(additionalProjectId, debugName: newFileName);
solution = solution.AddAnalyzerConfigDocument(documentId, newFileName, source, filePath: newFileName);
}
}

solution = solution.AddMetadataReferences(projectId, primaryProject.AdditionalReferences);
Expand All @@ -1153,6 +1159,12 @@ protected virtual async Task<Project> CreateProjectImplAsync(EvaluatedProjectSta
solution = solution.AddAdditionalDocument(documentId, newFileName, source, filePath: newFileName);
}

foreach (var (newFileName, source) in primaryProject.AnalyzerConfigFiles)
{
var documentId = DocumentId.CreateNewId(projectId, debugName: newFileName);
solution = solution.AddAnalyzerConfigDocument(documentId, newFileName, source, filePath: newFileName);
}

solution = AddProjectReferences(solution, projectId, primaryProject.AdditionalProjectReferences.Select(name => projectIdMap[name]));
foreach (var projectState in additionalProjects)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,15 @@ protected static bool CodeActionExpected(SolutionState state)
|| state.MarkupHandling != null
|| state.Sources.Any()
|| state.AdditionalFiles.Any()
|| state.AnalyzerConfigFiles.Any()
|| state.AdditionalFilesFactories.Any();
}

protected static bool HasAnyChange(SolutionState oldState, SolutionState newState)
{
return !oldState.Sources.SequenceEqual(newState.Sources, SourceFileEqualityComparer.Instance)
|| !oldState.AdditionalFiles.SequenceEqual(newState.AdditionalFiles, SourceFileEqualityComparer.Instance);
|| !oldState.AdditionalFiles.SequenceEqual(newState.AdditionalFiles, SourceFileEqualityComparer.Instance)
|| !oldState.AnalyzerConfigFiles.SequenceEqual(newState.AnalyzerConfigFiles, SourceFileEqualityComparer.Instance);
}

protected static CodeAction? TryGetCodeActionToApply(ImmutableArray<CodeAction> actions, int? codeActionIndex, string? codeActionEquivalenceKey, Action<CodeAction, IVerifier>? codeActionVerifier, IVerifier verifier)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// 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.Reflection;

namespace Microsoft.CodeAnalysis.Testing
{
internal static class ProjectExtensions
{
private static readonly Func<Project, IEnumerable<TextDocument>> s_analyzerConfigDocuments;

static ProjectExtensions()
{
var analyzerConfigDocumentType = typeof(Project).GetTypeInfo().Assembly.GetType("Microsoft.CodeAnalysis.AnalyzerConfigDocument");
if (analyzerConfigDocumentType is { })
{
var analyzerConfigDocumentsProperty = typeof(Project).GetProperty(nameof(AnalyzerConfigDocuments), typeof(IEnumerable<>).MakeGenericType(analyzerConfigDocumentType));
if (analyzerConfigDocumentsProperty is { GetMethod: { } getMethod })
{
s_analyzerConfigDocuments = (Func<Project, IEnumerable<TextDocument>>)getMethod.CreateDelegate(typeof(Func<Project, IEnumerable<TextDocument>>), target: null);
}
else
{
s_analyzerConfigDocuments = project => throw new NotSupportedException();
}
}
else
{
s_analyzerConfigDocuments = project => throw new NotSupportedException();
}
}

public static IEnumerable<TextDocument> AnalyzerConfigDocuments(this Project project)
=> s_analyzerConfigDocuments(project);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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.Reflection;
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.CodeAnalysis.Testing
{
internal static class SolutionExtensions
{
private static readonly Func<Solution, DocumentId, string, SourceText, IEnumerable<string>?, string?, Solution> s_addAnalyzerConfigDocument;

static SolutionExtensions()
{
var methodInfo = typeof(Solution).GetMethod(nameof(AddAnalyzerConfigDocument), new[] { typeof(DocumentId), typeof(string), typeof(SourceText), typeof(IEnumerable<string>), typeof(string) });
if (methodInfo is { })
{
s_addAnalyzerConfigDocument = (Func<Solution, DocumentId, string, SourceText, IEnumerable<string>?, string?, Solution>)methodInfo.CreateDelegate(typeof(Func<Solution, DocumentId, string, SourceText, IEnumerable<string>, string, Solution>), target: null);
}
else
{
s_addAnalyzerConfigDocument = (solution, documentId, name, text, folders, filePath) => throw new NotSupportedException();
}
}

public static Solution AddAnalyzerConfigDocument(this Solution solution, DocumentId documentId, string name, SourceText text, IEnumerable<string>? folders = null, string? filePath = null)
{
return s_addAnalyzerConfigDocument(solution, documentId, name, text, folders, filePath);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
</Choose>

<ItemGroup>
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.CodeFix.Testing" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.Testing.Verifiers.MSTest" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.Testing.Verifiers.NUnit" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.Testing.Verifiers.XUnit" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public EvaluatedProjectState(ProjectState state, ReferenceAssemblies defaultRefe
state.DocumentationMode ?? DocumentationMode.Diagnose,
state.Sources.ToImmutableArray(),
state.AdditionalFiles.ToImmutableArray(),
state.AnalyzerConfigFiles.ToImmutableArray(),
state.AdditionalProjectReferences.ToImmutableArray(),
state.AdditionalReferences.ToImmutableArray())
{
Expand All @@ -36,6 +37,7 @@ private EvaluatedProjectState(
DocumentationMode documentationMode,
ImmutableArray<(string filename, SourceText content)> sources,
ImmutableArray<(string filename, SourceText content)> additionalFiles,
ImmutableArray<(string filename, SourceText content)> analyzerConfigFiles,
ImmutableArray<string> additionalProjectReferences,
ImmutableArray<MetadataReference> additionalReferences)
{
Expand All @@ -47,6 +49,7 @@ private EvaluatedProjectState(
DocumentationMode = documentationMode;
Sources = sources;
AdditionalFiles = additionalFiles;
AnalyzerConfigFiles = analyzerConfigFiles;
AdditionalProjectReferences = additionalProjectReferences;
AdditionalReferences = additionalReferences;
}
Expand All @@ -67,6 +70,8 @@ private EvaluatedProjectState(

public ImmutableArray<(string filename, SourceText content)> AdditionalFiles { get; }

public ImmutableArray<(string filename, SourceText content)> AnalyzerConfigFiles { get; }

public ImmutableArray<string> AdditionalProjectReferences { get; }

public ImmutableArray<MetadataReference> AdditionalReferences { get; }
Expand All @@ -90,6 +95,7 @@ private EvaluatedProjectState With(
Optional<DocumentationMode> documentationMode = default,
Optional<ImmutableArray<(string filename, SourceText content)>> sources = default,
Optional<ImmutableArray<(string filename, SourceText content)>> additionalFiles = default,
Optional<ImmutableArray<(string filename, SourceText content)>> analyzerConfigFiles = default,
Optional<ImmutableArray<string>> additionalProjectReferences = default,
Optional<ImmutableArray<MetadataReference>> additionalReferences = default)
{
Expand All @@ -102,6 +108,7 @@ private EvaluatedProjectState With(
GetValueOrDefault(documentationMode, DocumentationMode),
GetValueOrDefault(sources, Sources),
GetValueOrDefault(additionalFiles, AdditionalFiles),
GetValueOrDefault(analyzerConfigFiles, AnalyzerConfigFiles),
GetValueOrDefault(additionalProjectReferences, AdditionalProjectReferences),
GetValueOrDefault(additionalReferences, AdditionalReferences));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ internal ProjectState(ProjectState sourceState)

Sources.AddRange(sourceState.Sources);
AdditionalFiles.AddRange(sourceState.AdditionalFiles);
AnalyzerConfigFiles.AddRange(sourceState.AnalyzerConfigFiles);
AdditionalFilesFactories.AddRange(sourceState.AdditionalFilesFactories);
AdditionalProjectReferences.AddRange(sourceState.AdditionalProjectReferences);
}
Expand Down Expand Up @@ -65,6 +66,8 @@ internal ProjectState(ProjectState sourceState)

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

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

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

public List<string> AdditionalProjectReferences { get; } = new List<string>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState
Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState.AdditionalFiles.get -> System.Collections.Immutable.ImmutableArray<(string filename, Microsoft.CodeAnalysis.Text.SourceText content)>
Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState.AdditionalProjectReferences.get -> System.Collections.Immutable.ImmutableArray<string>
Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState.AdditionalReferences.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.MetadataReference>
Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState.AnalyzerConfigFiles.get -> System.Collections.Immutable.ImmutableArray<(string filename, Microsoft.CodeAnalysis.Text.SourceText content)>
Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState.AssemblyName.get -> string
Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState.DocumentationMode.get -> Microsoft.CodeAnalysis.DocumentationMode
Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState.EvaluatedProjectState(Microsoft.CodeAnalysis.Testing.ProjectState state, Microsoft.CodeAnalysis.Testing.ReferenceAssemblies defaultReferenceAssemblies) -> void
Expand All @@ -144,6 +145,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.AssemblyName.get -> string
Microsoft.CodeAnalysis.Testing.ProjectState.DocumentationMode.get -> Microsoft.CodeAnalysis.DocumentationMode?
Microsoft.CodeAnalysis.Testing.ProjectState.DocumentationMode.set -> void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ public SolutionState WithInheritedValuesApplied(SolutionState? baseState, Immuta
result.AdditionalFiles.AddRange(baseState.AdditionalFiles);
}

if (AnalyzerConfigFiles.Count == 0)
{
result.AnalyzerConfigFiles.AddRange(baseState.AnalyzerConfigFiles);
}

if (AdditionalProjects.Count == 0)
{
result.AdditionalProjects.AddRange(baseState.AdditionalProjects);
Expand Down Expand Up @@ -172,6 +177,7 @@ public SolutionState WithInheritedValuesApplied(SolutionState? baseState, Immuta
result.InheritanceMode = StateInheritanceMode.Explicit;
result.Sources.AddRange(Sources);
result.AdditionalFiles.AddRange(AdditionalFiles);
result.AnalyzerConfigFiles.AddRange(AnalyzerConfigFiles);
result.AdditionalProjects.AddRange(AdditionalProjects);
result.AdditionalProjectReferences.AddRange(AdditionalProjectReferences);
result.AdditionalReferences.AddRange(AdditionalReferences);
Expand Down Expand Up @@ -202,6 +208,11 @@ private static bool HasAnyContentChanges(bool willInherit, SolutionState state,
return true;
}

if ((!willInherit || state.AnalyzerConfigFiles.Any()) && !ContentEqual(state.AnalyzerConfigFiles, baseState.AnalyzerConfigFiles))
{
return true;
}

if ((!willInherit || state.AdditionalReferences.Any()) && !state.AdditionalReferences.SequenceEqual(baseState.AdditionalReferences))
{
return true;
Expand Down Expand Up @@ -241,8 +252,8 @@ private static bool ContentEqual(SourceFileCollection x, SourceFileCollection y)
/// <summary>
/// Processes the markup syntax for this <see cref="SolutionState"/> according to the current
/// <see cref="MarkupHandling"/>, and returns a new <see cref="SolutionState"/> with the
/// <see cref="ProjectState.Sources"/>, <see cref="ProjectState.AdditionalFiles"/>, and
/// <see cref="ExpectedDiagnostics"/> updated accordingly.
/// <see cref="ProjectState.Sources"/>, <see cref="ProjectState.AdditionalFiles"/>,
/// <see cref="ProjectState.AnalyzerConfigFiles"/>, and <see cref="ExpectedDiagnostics"/> updated accordingly.
/// </summary>
/// <param name="markupOptions">Additional options to apply during markup processing.</param>
/// <param name="defaultDiagnostic">The diagnostic descriptor to use for markup spans without an explicit name,
Expand All @@ -265,7 +276,8 @@ public SolutionState WithProcessedMarkup(MarkupOptions markupOptions, Diagnostic

var markupLocations = ImmutableDictionary<string, FileLinePositionSpan>.Empty;
(var expected, var testSources) = ProcessMarkupSources(Sources, ExpectedDiagnostics, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);
var (additionalExpected, additionalFiles) = ProcessMarkupSources(AdditionalFiles.Concat(AdditionalFilesFactories.SelectMany(factory => factory())), expected, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);
var (additionalExpected1, additionalFiles) = ProcessMarkupSources(AdditionalFiles.Concat(AdditionalFilesFactories.SelectMany(factory => factory())), expected, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);
var (additionalExpected, analyzerConfigFiles) = ProcessMarkupSources(AnalyzerConfigFiles, additionalExpected1, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);

var result = new SolutionState(Name, Language, DefaultPrefix, DefaultExtension);
result.MarkupHandling = MarkupMode.None;
Expand All @@ -275,18 +287,22 @@ public SolutionState WithProcessedMarkup(MarkupOptions markupOptions, Diagnostic
result.DocumentationMode = DocumentationMode;
result.Sources.AddRange(testSources);
result.AdditionalFiles.AddRange(additionalFiles);
result.AnalyzerConfigFiles.AddRange(analyzerConfigFiles);

foreach (var (projectName, projectState) in AdditionalProjects)
{
var (correctedIntermediateDiagnostics, additionalProjectSources) = ProcessMarkupSources(projectState.Sources, additionalExpected, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);
var (correctedDiagnostics, additionalProjectAdditionalFiles) = ProcessMarkupSources(projectState.AdditionalFiles.Concat(projectState.AdditionalFilesFactories.SelectMany(factory => factory())), correctedIntermediateDiagnostics, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);
var (correctedDiagnostics1, additionalProjectAdditionalFiles) = ProcessMarkupSources(projectState.AdditionalFiles.Concat(projectState.AdditionalFilesFactories.SelectMany(factory => factory())), correctedIntermediateDiagnostics, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);
var (correctedDiagnostics, additionalProjectAnalyzerConfigFiles) = ProcessMarkupSources(projectState.AnalyzerConfigFiles, correctedDiagnostics1, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);

var processedProjectState = new ProjectState(projectState);
processedProjectState.Sources.Clear();
processedProjectState.Sources.AddRange(additionalProjectSources);
processedProjectState.AdditionalFiles.Clear();
processedProjectState.AdditionalFilesFactories.Clear();
processedProjectState.AdditionalFiles.AddRange(additionalProjectAdditionalFiles);
processedProjectState.AnalyzerConfigFiles.Clear();
processedProjectState.AnalyzerConfigFiles.AddRange(additionalProjectAnalyzerConfigFiles);

result.AdditionalProjects.Add(projectName, processedProjectState);
additionalExpected = correctedDiagnostics;
Expand Down
Loading

0 comments on commit dfdbcb7

Please sign in to comment.