Merge pull request #154 from Youssef1313/refactor-analyzer-config

refactor: Refactor analyzer config implementation to match Roslyn
This commit is contained in:
Jérôme Laban 2022-09-13 07:58:16 -04:00 коммит произвёл GitHub
Родитель 81ad60014d 0e8290abc4
Коммит 77cea5f3a1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 103 добавлений и 44 удалений

Просмотреть файл

@ -1,5 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// https://github.com/dotnet/roslyn/blob/3e39dd3535962bf9e30bd650e4ff34b610b8349a/src/Workspaces/Core/MSBuild/MSBuild/CSharp/CSharpCommandLineArgumentReader.cs
using System.Collections.Immutable;
using Uno.SourceGeneration.Engine.Workspace.Constants;
using MSB = Microsoft.Build;
@ -31,7 +33,6 @@ namespace Uno.SourceGeneration.Engine.Workspace
ReadPlatform();
ReadReferences();
ReadSigning();
ReadAnalyzerConfig();
AddIfNotNullOrWhiteSpace("appconfig", Project.ReadPropertyString(PropertyNames.AppConfigForCompiler));
AddIfNotNullOrWhiteSpace("baseaddress", Project.ReadPropertyString(PropertyNames.BaseAddress));

Просмотреть файл

@ -1,5 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// https://github.com/dotnet/roslyn/blob/3e39dd3535962bf9e30bd650e4ff34b610b8349a/src/Workspaces/Core/MSBuild/MSBuild/ProjectFile/CommandLineArgumentReader.cs
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@ -40,11 +42,11 @@ namespace Uno.SourceGeneration.Engine.Workspace
_builder.Add($"/{name}");
}
protected void Add(string name, string value)
protected void Add(string name, string value, bool addQuoteIfValueContainsWhitespace = true)
{
ValidateName(name);
if (string.IsNullOrEmpty(value) || value.Any(char.IsWhiteSpace))
if (string.IsNullOrEmpty(value) || (addQuoteIfValueContainsWhitespace && value.Any(char.IsWhiteSpace)))
{
_builder.Add($"/{name}:\"{value}\"");
}
@ -59,11 +61,11 @@ namespace Uno.SourceGeneration.Engine.Workspace
Add(name, value.ToString());
}
protected void AddIfNotNullOrWhiteSpace(string name, string value)
protected void AddIfNotNullOrWhiteSpace(string name, string? value, bool addQuoteIfValueContainsWhitespace = true)
{
if (!string.IsNullOrWhiteSpace(value))
{
Add(name, value);
Add(name, value, addQuoteIfValueContainsWhitespace);
}
}
@ -120,8 +122,9 @@ namespace Uno.SourceGeneration.Engine.Workspace
protected string GetAbsolutePath(string path)
{
var directoryPath = PathUtilities.GetDirectoryName(Project.FullPath);
return Path.GetFullPath(FileUtilities.ResolveRelativePath(path, directoryPath) ?? path);
var baseDirectory = PathUtilities.GetDirectoryName(Project.FullPath);
var absolutePath = FileUtilities.ResolveRelativePath(path, baseDirectory) ?? path;
return FileUtilities.TryNormalizeAbsolutePath(absolutePath) ?? absolutePath;
}
protected void ReadAdditionalFiles()
@ -169,8 +172,7 @@ namespace Uno.SourceGeneration.Engine.Workspace
if (emitDebugInfo)
{
var debugType = Project.ReadPropertyString(PropertyNames.DebugType);
if (s_debugTypeValues.TryGetValue(debugType, out var value))
if (debugType != null && s_debugTypeValues.TryGetValue(debugType, out var value))
{
Add("debug", value);
}
@ -210,9 +212,17 @@ namespace Uno.SourceGeneration.Engine.Workspace
protected void ReadImports()
{
var imports = Project.GetTaskItems(ItemNames.Import);
if (imports != null)
if (imports == null)
return;
// In case of import alias clause in the form of `aliasname = namespace`,
// we want to add quotes to that single clause only instead of the entire imports.
AddIfNotNullOrWhiteSpace("imports", string.Join(",", imports.Select(ReadImportItem)), addQuoteIfValueContainsWhitespace: false);
static string ReadImportItem(MSB.Framework.ITaskItem item)
{
AddIfNotNullOrWhiteSpace("imports", string.Join(",", imports.Select(item => item.ItemSpec.Trim())));
var trimmed = item.ItemSpec.Trim();
return trimmed.Contains(' ') ? $"\"{trimmed}\"" : trimmed;
}
}
@ -283,15 +293,6 @@ namespace Uno.SourceGeneration.Engine.Workspace
}
}
protected void ReadAnalyzerConfig()
{
var editorConfigFiles = Project.GetItems("EditorConfigFiles");
foreach (var editorConfigFile in editorConfigFiles)
{
Add("analyzerconfig", editorConfigFile.EvaluatedInclude);
}
}
protected ImmutableArray<string> Read()
{
ReadCore();

Просмотреть файл

@ -1,5 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// https://github.com/dotnet/roslyn/blob/3e39dd3535962bf9e30bd650e4ff34b610b8349a/src/Workspaces/Core/MSBuild/MSBuild/Constants/ItemNames.cs
namespace Uno.SourceGeneration.Engine.Workspace.Constants
{
internal static class ItemNames
@ -9,6 +11,7 @@ namespace Uno.SourceGeneration.Engine.Workspace.Constants
public const string Compile = nameof(Compile);
public const string CscCommandLineArgs = nameof(CscCommandLineArgs);
public const string DocFileItem = nameof(DocFileItem);
public const string EditorConfigFiles = nameof(EditorConfigFiles);
public const string Import = nameof(Import);
public const string ProjectReference = nameof(ProjectReference);
public const string Reference = nameof(Reference);

Просмотреть файл

@ -1,5 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// https://github.com/dotnet/roslyn/blob/3e39dd3535962bf9e30bd650e4ff34b610b8349a/src/Workspaces/Core/MSBuild/MSBuild/ProjectFile/Extensions.cs
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@ -21,6 +23,9 @@ namespace Uno.SourceGeneration.Engine.Workspace
public static IEnumerable<MSB.Framework.ITaskItem> GetDocuments(this MSB.Execution.ProjectInstance executedProject)
=> executedProject.GetItems(ItemNames.Compile);
public static IEnumerable<MSB.Framework.ITaskItem> GetEditorConfigFiles(this MSB.Execution.ProjectInstance executedProject)
=> executedProject.GetItems(ItemNames.EditorConfigFiles);
public static IEnumerable<MSB.Framework.ITaskItem> GetMetadataReferences(this MSB.Execution.ProjectInstance executedProject)
=> executedProject.GetItems(ItemNames.ReferencePath);

Просмотреть файл

@ -1,5 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// https://github.com/dotnet/roslyn/blob/main/src/Workspaces/Core/MSBuild/MSBuild/ProjectFile/ProjectFileInfo.cs
using Microsoft.Build.Evaluation;
using Microsoft.Build.Execution;
using Microsoft.Build.Framework;
@ -44,6 +46,21 @@ namespace Uno.SourceGeneration.Engine.Workspace
/// </summary>
public string OutputRefFilePath { get; }
#if false
/// <summary>
/// The default namespace of the project ("" if not defined, which means global namespace),
/// or null if it is unknown or not applicable.
/// </summary>
/// <remarks>
/// Right now VB doesn't have the concept of "default namespace". But we conjure one in workspace
/// by assigning the value of the project's root namespace to it. So various feature can choose to
/// use it for their own purpose.
/// In the future, we might consider officially exposing "default namespace" for VB project
/// (e.g. through a "defaultnamespace" msbuild property)
/// </remarks>
public string DefaultNamespace { get; }
#endif
/// <summary>
/// The target framework of this project.
/// This takes the form of the 'short name' form used by NuGet (e.g. net46, netcoreapp2.0, etc.)
@ -65,14 +82,27 @@ namespace Uno.SourceGeneration.Engine.Workspace
/// </summary>
public ImmutableArray<DocumentFileInfo> AdditionalDocuments { get; }
/// <summary>
/// The analyzer config documents.
/// </summary>
public ImmutableArray<DocumentFileInfo> AnalyzerConfigDocuments { get; }
/// <summary>
/// References to other projects.
/// </summary>
public ImmutableArray<ProjectFileReference> ProjectReferences { get; }
#if false
/// <summary>
/// The error message produced when a failure occurred attempting to get the info.
/// If a failure occurred some or all of the information may be inaccurate or incomplete.
/// </summary>
public DiagnosticLog Log { get; }
#endif
public override string ToString()
=> string.IsNullOrWhiteSpace(TargetFramework)
? FilePath
? FilePath ?? string.Empty
: $"{FilePath} ({TargetFramework})";
private ProjectFileInfo(
@ -81,11 +111,15 @@ namespace Uno.SourceGeneration.Engine.Workspace
string filePath,
string outputFilePath,
string outputRefFilePath,
//string defaultNamespace,
string targetFramework,
ImmutableArray<string> commandLineArgs,
ImmutableArray<DocumentFileInfo> documents,
ImmutableArray<DocumentFileInfo> additionalDocuments,
ImmutableArray<ProjectFileReference> projectReferences)
ImmutableArray<DocumentFileInfo> analyzerConfigDocuments,
ImmutableArray<ProjectFileReference> projectReferences
//DiagnosticLog log
)
{
Debug.Assert(filePath != null);
@ -94,11 +128,14 @@ namespace Uno.SourceGeneration.Engine.Workspace
this.FilePath = filePath;
this.OutputFilePath = outputFilePath;
this.OutputRefFilePath = outputRefFilePath;
//this.DefaultNamespace = defaultNamespace;
this.TargetFramework = targetFramework;
this.CommandLineArgs = commandLineArgs;
this.Documents = documents;
this.AdditionalDocuments = additionalDocuments;
this.AnalyzerConfigDocuments = analyzerConfigDocuments;
this.ProjectReferences = projectReferences;
//this.Log = log;
}
public static ProjectFileInfo Create(
@ -106,36 +143,47 @@ namespace Uno.SourceGeneration.Engine.Workspace
string filePath,
string outputFilePath,
string outputRefFilePath,
//string defaultNamespace,
string targetFramework,
ImmutableArray<string> commandLineArgs,
ImmutableArray<DocumentFileInfo> documents,
ImmutableArray<DocumentFileInfo> additionalDocuments,
ImmutableArray<ProjectFileReference> projectReferences)
=> new ProjectFileInfo(
ImmutableArray<DocumentFileInfo> analyzerConfigDocuments,
ImmutableArray<ProjectFileReference> projectReferences
//DiagnosticLog log)
)
=> new(
isEmpty: false,
language,
filePath,
outputFilePath,
outputRefFilePath,
//defaultNamespace,
targetFramework,
commandLineArgs,
documents,
additionalDocuments,
projectReferences);
analyzerConfigDocuments,
projectReferences
//log
);
public static ProjectFileInfo CreateEmpty(string language, string filePath)
=> new ProjectFileInfo(
public static ProjectFileInfo CreateEmpty(string language, string filePath) // , DiagnosticLog log
=> new(
isEmpty: true,
language,
filePath,
outputFilePath: null,
outputRefFilePath: null,
//defaultNamespace: null,
targetFramework: null,
commandLineArgs: ImmutableArray<string>.Empty,
documents: ImmutableArray<DocumentFileInfo>.Empty,
additionalDocuments: ImmutableArray<DocumentFileInfo>.Empty,
projectReferences: ImmutableArray<ProjectFileReference>.Empty);
analyzerConfigDocuments: ImmutableArray<DocumentFileInfo>.Empty,
projectReferences: ImmutableArray<ProjectFileReference>.Empty
//log
);
public static ProjectFileInfo FromMSBuildProjectInstance(string language, Microsoft.Build.Evaluation.Project loadedProject, ProjectInstance project)
=> new Builder(loadedProject, project).Build(language);
@ -180,9 +228,14 @@ namespace Uno.SourceGeneration.Engine.Workspace
.ToImmutableArray();
var additionalDocs = _project.GetAdditionalFiles()
.Select(MakeAdditionalDocumentFileInfo)
.Select(MakeNonSourceFileDocumentFileInfo)
.ToImmutableArray();
var analyzerConfigDocs = _project.GetEditorConfigFiles()
.Select(MakeNonSourceFileDocumentFileInfo)
.ToImmutableArray();
return ProjectFileInfo.Create(
language,
_loadedProject.FullPath,
@ -192,17 +245,17 @@ namespace Uno.SourceGeneration.Engine.Workspace
commandLineArgs,
docs,
additionalDocs,
analyzerConfigDocs,
_project.GetProjectReferences().ToImmutableArray()
);
}
private DocumentFileInfo MakeAdditionalDocumentFileInfo(ITaskItem documentItem)
private DocumentFileInfo MakeNonSourceFileDocumentFileInfo(ITaskItem documentItem)
{
var filePath = GetDocumentFilePath(documentItem);
var logicalPath = GetDocumentLogicalPath(documentItem, _project.Directory);
var isLinked = IsDocumentLinked(documentItem);
var isGenerated = IsDocumentGenerated(documentItem);
return new DocumentFileInfo(filePath, logicalPath, isLinked, isGenerated, SourceCodeKind.Regular);
}

Просмотреть файл

@ -12,6 +12,9 @@ using Uno.SourceGeneration.Engine.Workspace.Utilities;
using Uno.SourceGeneration.Host;
using Uno.SourceGeneration.Host.Helpers;
// Almost taken from https://github.com/dotnet/roslyn/blob/3e39dd3535962bf9e30bd650e4ff34b610b8349a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker.cs
// But not an exact copy.
namespace Uno.SourceGeneration.Engine.Workspace
{
internal class ProjectInfoBuilder
@ -60,6 +63,7 @@ namespace Uno.SourceGeneration.Engine.Workspace
var documents = CreateDocumentInfos(projectFileInfo.Documents, projectId, commandLineArgs.Encoding);
var additionalDocuments = CreateDocumentInfos(projectFileInfo.AdditionalDocuments, projectId, commandLineArgs.Encoding);
var analyzerConfigDocuments = CreateDocumentInfos(projectFileInfo.AnalyzerConfigDocuments, projectId, commandLineArgs.Encoding);
// CheckForDuplicateDocuments(documents, additionalDocuments, projectPath, projectId);
var resolvedReferences = ResolveReferencesAsync(projectId, projectFileInfo, commandLineArgs);
@ -79,16 +83,8 @@ namespace Uno.SourceGeneration.Engine.Workspace
analyzerReferences: Enumerable.Empty<AnalyzerReference>(),
additionalDocuments: additionalDocuments,
isSubmission: false,
hostObjectType: null).WithAnalyzerConfigDocuments(commandLineArgs.AnalyzerConfigPaths.Select(CreateDocumentInfo));
DocumentInfo CreateDocumentInfo(string path)
{
return DocumentInfo.Create(
DocumentId.CreateNewId(projectId, path),
name: path,
filePath: path,
loader: new FileTextLoader(path, commandLineArgs.Encoding));
}
hostObjectType: null)
.WithAnalyzerConfigDocuments(analyzerConfigDocuments);
}
private readonly struct ResolvedReferences

Просмотреть файл

@ -7,7 +7,7 @@
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<LangVersion>7.2</LangVersion>
<LangVersion>9</LangVersion>
<AppConfig>$(MSBuildThisFileDirectory)app.$(TargetFramework).config</AppConfig>
<RollForward>LatestMajor</RollForward>
</PropertyGroup>