-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add 'Prefer Project Reference' Check (#10955)
* Add EvaluatedItemCheckData * Fix build * Add 'Prefer Project Reference' Check * Remove extra code * Fix typo * Update Codes.md * Update documentation/specs/BuildCheck/Codes.md Co-authored-by: Chet Husk <[email protected]> * Apply suggestions from code review Co-authored-by: Jan Provazník <[email protected]> * Reflect PR suggestions * Reflected PR comments --------- Co-authored-by: Chet Husk <[email protected]> Co-authored-by: Jan Provazník <[email protected]>
- Loading branch information
1 parent
9c89563
commit e73ffcb
Showing
57 changed files
with
334 additions
and
151 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
[*.cs] | ||
csharp_style_namespace_declarations = file_scoped:warning | ||
dotnet_diagnostic.IDE0005.severity = warning |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
src/Build/BuildCheck/Checks/PreferProjectReferenceCheck.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Collections.Generic; | ||
using System.IO; | ||
using Microsoft.Build.Collections; | ||
using Microsoft.Build.Construction; | ||
using Microsoft.Build.Framework; | ||
using Microsoft.Build.Shared; | ||
|
||
namespace Microsoft.Build.Experimental.BuildCheck.Checks; | ||
internal class PreferProjectReferenceCheck : Check | ||
{ | ||
private const string RuleId = "BC0104"; | ||
public static CheckRule SupportedRule = new CheckRule(RuleId, "PreferProjectReference", | ||
ResourceUtilities.GetResourceString("BuildCheck_BC0104_Title")!, | ||
ResourceUtilities.GetResourceString("BuildCheck_BC0104_MessageFmt")!, | ||
new CheckConfiguration() { RuleId = RuleId, Severity = CheckResultSeverity.Warning }); | ||
|
||
public override string FriendlyName => "MSBuild.PreferProjectReferenceCheck"; | ||
|
||
public override IReadOnlyList<CheckRule> SupportedRules { get; } = [SupportedRule]; | ||
|
||
public override void Initialize(ConfigurationContext configurationContext) | ||
{ | ||
/* This is it - no custom configuration */ | ||
} | ||
|
||
public override void RegisterActions(IBuildCheckRegistrationContext registrationContext) | ||
{ | ||
registrationContext.RegisterEvaluatedPropertiesAction(EvaluatedPropertiesAction); | ||
registrationContext.RegisterEvaluatedItemsAction(EvaluatedItemsAction); | ||
} | ||
|
||
internal override bool IsBuiltIn => true; | ||
|
||
private readonly Dictionary<string, (string, string)> _projectsPerReferencePath = new(MSBuildNameIgnoreCaseComparer.Default); | ||
private readonly Dictionary<string, string> _projectsPerOutputPath = new(MSBuildNameIgnoreCaseComparer.Default); | ||
private readonly HashSet<string> _projectsSeen = new(MSBuildNameIgnoreCaseComparer.Default); | ||
|
||
private void EvaluatedPropertiesAction(BuildCheckDataContext<EvaluatedPropertiesCheckData> context) | ||
{ | ||
// We want to avoid repeated checking of a same project (as it might be evaluated multiple times) | ||
// for this reason we use a hashset with already seen projects. | ||
// We want to do the same prevention for both registered actions: EvaluatedPropertiesAction and EvaluatedItemsAction. | ||
// To avoid the need to have separate hashset for each of those functions - we use a single one and we use the fact that | ||
// both functions are always called after each other (EvaluatedPropertiesAction first, then EvaluatedItemsAction), | ||
// so this function just checks the hashset (not to prevent execution of EvaluatedItemsAction) and EvaluatedItemsAction | ||
// updates the hashset. | ||
if (_projectsSeen.Contains(context.Data.ProjectFilePath)) | ||
{ | ||
return; | ||
} | ||
|
||
string? targetPath; | ||
|
||
context.Data.EvaluatedProperties.TryGetValue(ItemMetadataNames.targetPath, out targetPath); | ||
|
||
if (string.IsNullOrEmpty(targetPath)) | ||
{ | ||
return; | ||
} | ||
|
||
targetPath = BuildCheckUtilities.RootEvaluatedPath(targetPath, context.Data.ProjectFilePath); | ||
|
||
_projectsPerOutputPath[targetPath] = context.Data.ProjectFilePath; | ||
|
||
(string, string) projectProducingOutput; | ||
if (_projectsPerReferencePath.TryGetValue(targetPath, out projectProducingOutput)) | ||
{ | ||
context.ReportResult(BuildCheckResult.Create( | ||
SupportedRule, | ||
// Populating precise location tracked via https://github.com/orgs/dotnet/projects/373/views/1?pane=issue&itemId=58661732 | ||
ElementLocation.EmptyLocation, | ||
Path.GetFileName(context.Data.ProjectFilePath), | ||
Path.GetFileName(projectProducingOutput.Item1), | ||
projectProducingOutput.Item2)); | ||
} | ||
} | ||
|
||
private void EvaluatedItemsAction(BuildCheckDataContext<EvaluatedItemsCheckData> context) | ||
{ | ||
// We want to avoid repeated checking of a same project (as it might be evaluated multiple times) | ||
// for this reason we use a hashset with already seen projects. | ||
if (!_projectsSeen.Add(context.Data.ProjectFilePath)) | ||
{ | ||
return; | ||
} | ||
|
||
foreach (ItemData itemData in context.Data.EnumerateItemsOfType(ItemNames.reference)) | ||
{ | ||
string evaluatedReferencePath = itemData.EvaluatedInclude; | ||
string referenceFullPath = BuildCheckUtilities.RootEvaluatedPath(evaluatedReferencePath, context.Data.ProjectFilePath); | ||
|
||
_projectsPerReferencePath[referenceFullPath] = (context.Data.ProjectFilePath, evaluatedReferencePath); | ||
string? projectReferencedViaOutput; | ||
if (_projectsPerOutputPath.TryGetValue(referenceFullPath, out projectReferencedViaOutput)) | ||
{ | ||
context.ReportResult(BuildCheckResult.Create( | ||
SupportedRule, | ||
// Populating precise location tracked via https://github.com/orgs/dotnet/projects/373/views/1?pane=issue&itemId=58661732 | ||
ElementLocation.EmptyLocation, | ||
Path.GetFileName(projectReferencedViaOutput), | ||
Path.GetFileName(context.Data.ProjectFilePath), | ||
evaluatedReferencePath)); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 0 additions & 7 deletions
7
src/Build/BuildCheck/Infrastructure/BuildCheckConnectorLogger.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.