Merge pull request #154 from Youssef1313/refactor-analyzer-config
refactor: Refactor analyzer config implementation to match Roslyn
This commit is contained in:
Коммит
77cea5f3a1
|
@ -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>
|
||||
|
|
Загрузка…
Ссылка в новой задаче