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

Analyzers acquisition experience #10014

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
a59fe1e
Initial demonstration version
JanKrivanek Feb 12, 2024
628394d
Make analyzer test use bootstrap properly (#9733)
JanKrivanek Feb 13, 2024
59ab931
Hook analyzers stats stub
JanKrivanek Feb 13, 2024
92e3795
Fix unit tests by explicitly opting into analysis
JanKrivanek Feb 14, 2024
33c4d2e
Disable build acceleration for MSBuild.Bootstrap
ladipro Feb 15, 2024
b37e495
Make EndToEndTests disposable
ladipro Feb 15, 2024
2db509f
Support running Analyzers.UnitTests from stage1
ladipro Feb 15, 2024
4cdd903
Fix MSBuild.dll casing
ladipro Feb 15, 2024
05450bb
Don't run netfx Analyzer.UnitTests in Windows Core builds
ladipro Feb 16, 2024
7e12ef0
Fix Analyzers.UnitTests on Mac
ladipro Feb 16, 2024
fdda2cd
Renaming changes
JanKrivanek Feb 16, 2024
72749c4
Renaming for clarity (#9754)
JanKrivanek Feb 16, 2024
9314121
Removing unnecessary types
JanKrivanek Feb 20, 2024
886c483
Code move
JanKrivanek Feb 20, 2024
60e01a7
Adjust namespaces
JanKrivanek Feb 20, 2024
b474fa1
Simplify TestEnvironments in EndToEndTests
ladipro Feb 21, 2024
ac76b77
Support for per-project configuration, Acquisition mounting, etc
JanKrivanek Feb 28, 2024
0467261
Add more comments
JanKrivanek Feb 28, 2024
5f9d941
Grace handle double initialization attempts
JanKrivanek Feb 29, 2024
40dd6e0
Fix tests
JanKrivanek Feb 29, 2024
bddef4c
Troubleshoot test, comment
JanKrivanek Feb 29, 2024
296faa9
Reflect PR comments
JanKrivanek Mar 1, 2024
f873eda
Fix build
JanKrivanek Mar 1, 2024
3db5e97
Fix build - proper multitargeting on core builds
JanKrivanek Mar 5, 2024
6021771
Adjust API naming and exposure
JanKrivanek Mar 12, 2024
72f2d51
Merge branch 'main' into exp/build-analyzers
JanKrivanek Mar 18, 2024
178907f
Add forgotten acquisition data sending
JanKrivanek Mar 18, 2024
e178918
Renaming BuildCop to BuildCheck (#9893)
maridematte Mar 19, 2024
0892e86
Renamed a few files missed (#9900)
maridematte Mar 21, 2024
31a2a0e
Add template for custom analyzers (#9789)
YuliiaKovalova Mar 25, 2024
d710e00
Merge branch 'main' into exp/build-analyzers
JanKrivanek Mar 25, 2024
2aeda7e
init changes
YuliiaKovalova Mar 26, 2024
5fab936
Run tests against just-built bootstrap environment
ladipro Apr 3, 2024
9b5b925
Reflecting PR comments
JanKrivanek Apr 4, 2024
d97a611
Add test without analysis
JanKrivanek Apr 4, 2024
e18f00f
Rename tests project
JanKrivanek Apr 4, 2024
368cb08
Force case renaming
JanKrivanek Apr 4, 2024
e1112be
pass logging context to inrinsic function
YuliiaKovalova Apr 4, 2024
e721c0a
merge
YuliiaKovalova Apr 4, 2024
7025f3a
Simplify GlobalInstance initialization
JanKrivanek Apr 5, 2024
aeb4107
Remove multiple registrations checking
JanKrivanek Apr 5, 2024
01510e2
Reflect on PR feedback
JanKrivanek Apr 5, 2024
1d7c4c6
Apply suggestions from code review
JanKrivanek Apr 5, 2024
25b5f75
Reflect on PR comments
JanKrivanek Apr 5, 2024
53a7c8b
implement full aquisition flow
YuliiaKovalova Apr 8, 2024
5dea8dc
merge
YuliiaKovalova Apr 8, 2024
06e06d5
cleanup
YuliiaKovalova Apr 8, 2024
ab744f6
fix template
YuliiaKovalova Apr 8, 2024
5b86a3d
add test coverage
YuliiaKovalova Apr 9, 2024
b73069c
cleanup
YuliiaKovalova Apr 9, 2024
0fdf77f
cleanup
YuliiaKovalova Apr 9, 2024
aaaafcc
Update src/Build/BuildCheck/API/BuildAnalyzerRule.cs
JanKrivanek Apr 10, 2024
cf29add
Reflect PR comments
JanKrivanek Apr 10, 2024
402f490
Merge branch 'exp/build-analyzers' of https://github.com/dotnet/msbui…
JanKrivanek Apr 10, 2024
8e04656
merge + fix review comments
YuliiaKovalova Apr 11, 2024
c7d1b1d
fix test failure
YuliiaKovalova Apr 11, 2024
724f1f3
fix review comments
YuliiaKovalova Apr 15, 2024
3e0b455
fix review comments
YuliiaKovalova Apr 15, 2024
086dbea
merge
YuliiaKovalova Apr 16, 2024
dde2231
remove extra file
YuliiaKovalova Apr 16, 2024
c5dbb56
fix review comments
YuliiaKovalova Apr 17, 2024
0071485
fix review comments
YuliiaKovalova Apr 23, 2024
74d2af9
Merge branch 'main' into dev/ykovalova/analyzers_aquisition_experience
YuliiaKovalova Apr 23, 2024
ed8e6a5
Update Strings.resx
YuliiaKovalova Apr 23, 2024
bcb5ba3
update string resources
YuliiaKovalova Apr 23, 2024
b2d984e
add one more exception catching layer
YuliiaKovalova Apr 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/Build.UnitTests/Evaluation/Expander_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
using System.Threading;
using System.Xml;
using Microsoft.Build.BackEnd;
using Microsoft.Build.BackEnd.Logging;
using Microsoft.Build.Collections;
using Microsoft.Build.Engine.UnitTests;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Execution;
using Microsoft.Build.Experimental.BuildCheck;
using Microsoft.Build.Framework;
using Microsoft.Build.Internal;
using Microsoft.Build.Shared;
Expand All @@ -23,7 +26,6 @@
using Microsoft.Win32;
using Shouldly;
using Xunit;
using Xunit.NetCore.Extensions;
using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException;
using ProjectHelpers = Microsoft.Build.UnitTests.BackEnd.ProjectHelpers;
using ProjectItemInstanceFactory = Microsoft.Build.Execution.ProjectItemInstance.TaskItem.ProjectItemInstanceFactory;
Expand Down Expand Up @@ -5055,5 +5057,27 @@ private static bool ICUModeAvailable()
int version = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
return version != 0 && version == sortVersion.FullVersion;
}

[Fact]
public void PropertyFunctionRegisterAnalyzer()
{
using (var env = TestEnvironment.Create())
{
var logger = new MockLogger();
ILoggingService loggingService = LoggingService.CreateLoggingService(LoggerMode.Synchronous, 1);
loggingService.RegisterLogger(logger);
var loggingContext = new MockLoggingContext(
loggingService,
new BuildEventContext(0, 0, BuildEventContext.InvalidProjectContextId, 0, 0));
var dummyAssemblyFile = env.CreateFile(env.CreateFolder(), "test.dll");

var result = new Expander<ProjectPropertyInstance, ProjectItemInstance>(new PropertyDictionary<ProjectPropertyInstance>(), FileSystems.Default)
.ExpandIntoStringLeaveEscaped($"$([MSBuild]::RegisterAnalyzer({dummyAssemblyFile.Path}))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance, loggingContext);

result.ShouldBe(Boolean.TrueString);
_ = logger.AllBuildEvents.Select(be => be.ShouldBeOfType<BuildCheckAcquisitionEventArgs>());
logger.AllBuildEvents.Count.ShouldBe(1);
}
}
}
}
1 change: 1 addition & 0 deletions src/Build/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
[assembly: InternalsVisibleTo("Microsoft.Build.Conversion.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
[assembly: InternalsVisibleTo("Microsoft.Build.Conversion.Unittest, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")]
[assembly: InternalsVisibleTo("Microsoft.Build.Tasks.Cop, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")]
[assembly: InternalsVisibleTo("Microsoft.Build.BuildCheck.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")]
// DO NOT expose Internals to "Microsoft.Build.UnitTests.OM.OrcasCompatibility" as this assembly is supposed to only see public interface

// This will enable passing the SafeDirectories flag to any P/Invoke calls/implementations within the assembly,
Expand Down
12 changes: 8 additions & 4 deletions src/Build/BackEnd/Components/Logging/EvaluationLoggingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
namespace Microsoft.Build.BackEnd.Components.Logging
{
/// <summary>
/// Logging context and helpers for evaluation logging
/// Logging context and helpers for evaluation logging.
/// </summary>
internal class EvaluationLoggingContext : LoggingContext
{
private readonly string _projectFile;

public EvaluationLoggingContext(ILoggingService loggingService, BuildEventContext buildEventContext, string projectFile) :
base(
public EvaluationLoggingContext(ILoggingService loggingService, BuildEventContext buildEventContext, string projectFile)
: base(
loggingService,
loggingService.CreateEvaluationBuildEventContext(buildEventContext.NodeId, buildEventContext.SubmissionId))
{
Expand All @@ -33,8 +33,12 @@ public void LogProjectEvaluationStarted()
}

/// <summary>
/// Log that the project has finished
/// Logs that the project evaluation has finished.
/// </summary>
/// <param name="globalProperties">Global properties used in the project evaluation.</param>
/// <param name="properties">Properties used in the project evaluation.</param>
/// <param name="items">Items used in the project evaluation.</param>
/// <param name="profilerResult">Parameter contains the profiler result of the project evaluation.</param>
internal void LogProjectEvaluationFinished(IEnumerable globalProperties, IEnumerable properties, IEnumerable items, ProfilerResult? profilerResult)
{
ErrorUtilities.VerifyThrow(IsValid, "invalid");
Expand Down
1 change: 1 addition & 0 deletions src/Build/BackEnd/Components/Logging/EventSourceSink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ internal void UnregisterAllEventHandlers()
StatusEventRaised = null;
AnyEventRaised = null;
TelemetryLogged = null;
BuildCheckEventRaised = null;
}

#endregion
Expand Down
8 changes: 4 additions & 4 deletions src/Build/BuildCheck/Acquisition/AnalyzerAcquisitionData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ namespace Microsoft.Build.BuildCheck.Acquisition;
// https://github.com/dotnet/msbuild/issues/9633
// Acquisition
// define the data that will be passed to the acquisition module (and remoted if needed)
internal class AnalyzerAcquisitionData(string data)
internal class AnalyzerAcquisitionData(string assemblyPath)
{
public string Data { get; init; } = data;
public string AssemblyPath { get; init; } = assemblyPath;
}

internal static class AnalyzerAcquisitionDataExtensions
{
public static AnalyzerAcquisitionData ToAnalyzerAcquisitionData(this BuildCheckAcquisitionEventArgs eventArgs) =>
new(eventArgs.AcquisitionData);
new(eventArgs.AcquisitionPath);

public static BuildCheckAcquisitionEventArgs ToBuildEventArgs(this AnalyzerAcquisitionData data) => new(data.Data);
public static BuildCheckAcquisitionEventArgs ToBuildEventArgs(this AnalyzerAcquisitionData data) => new(data.AssemblyPath);
}
70 changes: 62 additions & 8 deletions src/Build/BuildCheck/Acquisition/BuildCheckAcquisitionModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Build.BuildCheck.Analyzers;
using System.Reflection;
using Microsoft.Build.BackEnd.Logging;
using Microsoft.Build.BuildCheck.Infrastructure;
using Microsoft.Build.Experimental.BuildCheck;
using Microsoft.Build.Framework;
using Microsoft.Build.Shared;

namespace Microsoft.Build.BuildCheck.Acquisition;

internal class BuildCheckAcquisitionModule
internal class BuildCheckAcquisitionModule : IBuildCheckAcquisitionModule
{
private static T Construct<T>() where T : new() => new();
public BuildAnalyzerFactory CreateBuildAnalyzerFactory(AnalyzerAcquisitionData analyzerAcquisitionData)
private readonly ILoggingService _loggingService;

internal BuildCheckAcquisitionModule(ILoggingService loggingService) => _loggingService = loggingService;

#if FEATURE_ASSEMBLYLOADCONTEXT
/// <summary>
/// AssemblyContextLoader used to load DLLs outside of msbuild.exe directory.
/// </summary>
private static readonly CoreClrAssemblyLoader s_coreClrAssemblyLoader = new();
#endif

/// <summary>
/// Creates a list of factory delegates for building analyzer rules instances from a given assembly path.
/// </summary>
public List<BuildAnalyzerFactory> CreateBuildAnalyzerFactories(AnalyzerAcquisitionData analyzerAcquisitionData, BuildEventContext buildEventContext)
{
// Acquisition module - https://github.com/dotnet/msbuild/issues/9633
return Construct<SharedOutputPathAnalyzer>;
var analyzersFactories = new List<BuildAnalyzerFactory>();

try
{
Assembly? assembly = null;
#if FEATURE_ASSEMBLYLOADCONTEXT
assembly = s_coreClrAssemblyLoader.LoadFromPath(analyzerAcquisitionData.AssemblyPath);
#else
assembly = Assembly.LoadFrom(analyzerAcquisitionData.AssemblyPath);
#endif

IEnumerable<Type> analyzerTypes = assembly.GetExportedTypes().Where(t => typeof(BuildAnalyzer).IsAssignableFrom(t));

foreach (Type analyzerType in analyzerTypes)
{
if (Activator.CreateInstance(analyzerType) is BuildAnalyzer instance)
{
analyzersFactories.Add(() => instance);
YuliiaKovalova marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
throw new InvalidOperationException($"Failed to create an instance of type {analyzerType.FullName} as BuildAnalyzer.");
}
}
}
catch (ReflectionTypeLoadException ex)
YuliiaKovalova marked this conversation as resolved.
Show resolved Hide resolved
{
if (ex.LoaderExceptions.Length != 0)
{
foreach (Exception? loaderException in ex.LoaderExceptions)
{
_loggingService.LogComment(buildEventContext, MessageImportance.Normal, "CustomAnalyzerFailedRuleLoading", loaderException?.Message);
}
}
}
catch (Exception ex)
{
_loggingService.LogComment(buildEventContext, MessageImportance.Normal, "CustomAnalyzerFailedRuleLoading", ex?.Message);
}

return analyzersFactories;
}
}
16 changes: 16 additions & 0 deletions src/Build/BuildCheck/Acquisition/IBuildCheckAcquisitionModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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 Microsoft.Build.BuildCheck.Infrastructure;
using Microsoft.Build.Framework;

namespace Microsoft.Build.BuildCheck.Acquisition;

internal interface IBuildCheckAcquisitionModule
{
/// <summary>
/// Creates a list of factory delegates for building analyzer rules instances from a given assembly path.
/// </summary>
List<BuildAnalyzerFactory> CreateBuildAnalyzerFactories(AnalyzerAcquisitionData analyzerAcquisitionData, BuildEventContext buildEventContext);
}
106 changes: 58 additions & 48 deletions src/Build/BuildCheck/Infrastructure/BuildCheckConnectorLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,32 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.Build.BackEnd.Logging;
using Microsoft.Build.BuildCheck.Acquisition;
using Microsoft.Build.BuildCheck.Logging;
using Microsoft.Build.Experimental.BuildCheck;
using Microsoft.Build.Framework;
using static Microsoft.Build.BuildCheck.Infrastructure.BuildCheckManagerProvider;

namespace Microsoft.Build.BuildCheck.Infrastructure;
internal sealed class BuildCheckConnectorLogger(IBuildAnalysisLoggingContextFactory loggingContextFactory, IBuildCheckManager buildCheckManager)
: ILogger

internal sealed class BuildCheckConnectorLogger : ILogger
{
private readonly Dictionary<Type, Action<BuildEventArgs>> _eventHandlers;
private readonly IBuildCheckManager _buildCheckManager;
private readonly IBuildAnalysisLoggingContextFactory _loggingContextFactory;

internal BuildCheckConnectorLogger(
IBuildAnalysisLoggingContextFactory loggingContextFactory,
IBuildCheckManager buildCheckManager)
{
_buildCheckManager = buildCheckManager;
_loggingContextFactory = loggingContextFactory;
_eventHandlers = GetBuildEventHandlers();
}

public LoggerVerbosity Verbosity { get; set; }

public string? Parameters { get; set; }

public void Initialize(IEventSource eventSource)
Expand All @@ -24,70 +37,67 @@ public void Initialize(IEventSource eventSource)
eventSource.BuildFinished += EventSource_BuildFinished;
}

private void EventSource_AnyEventRaised(object sender, BuildEventArgs e)
public void Shutdown()
{
if (e is ProjectEvaluationFinishedEventArgs projectEvaluationFinishedEventArgs)
{
if (projectEvaluationFinishedEventArgs.ProjectFile?.EndsWith(".metaproj") ?? false)
{
return;
}

buildCheckManager.ProcessEvaluationFinishedEventArgs(
loggingContextFactory.CreateLoggingContext(e.BuildEventContext!),
projectEvaluationFinishedEventArgs);
}

buildCheckManager.EndProjectEvaluation(BuildCheckDataSource.EventArgs, e.BuildEventContext!);
}
else if (e is ProjectEvaluationStartedEventArgs projectEvaluationStartedEventArgs)
{
// Skip autogenerated transient projects (as those are not user projects to be analyzed)
if (projectEvaluationStartedEventArgs.ProjectFile?.EndsWith(".metaproj") ?? false)
{
return;
}

buildCheckManager.StartProjectEvaluation(BuildCheckDataSource.EventArgs, e.BuildEventContext!,
projectEvaluationStartedEventArgs.ProjectFile!);
}
else if (e is ProjectStartedEventArgs projectStartedEvent)
private void HandleProjectEvaluationFinishedEvent(ProjectEvaluationFinishedEventArgs eventArgs)
{
if (!IsMetaProjFile(eventArgs.ProjectFile))
{
buildCheckManager.StartProjectRequest(BuildCheckDataSource.EventArgs, e.BuildEventContext!);
_buildCheckManager.ProcessEvaluationFinishedEventArgs(
_loggingContextFactory.CreateLoggingContext(eventArgs.BuildEventContext!),
eventArgs);

_buildCheckManager.EndProjectEvaluation(BuildCheckDataSource.EventArgs, eventArgs.BuildEventContext!);
}
else if (e is ProjectFinishedEventArgs projectFinishedEventArgs)
}

private void HandleProjectEvaluationStartedEvent(ProjectEvaluationStartedEventArgs eventArgs)
{
if (!IsMetaProjFile(eventArgs.ProjectFile))
{
buildCheckManager.EndProjectRequest(BuildCheckDataSource.EventArgs, e.BuildEventContext!);
_buildCheckManager.StartProjectEvaluation(BuildCheckDataSource.EventArgs, eventArgs.BuildEventContext!, eventArgs.ProjectFile!);
}
else if (e is BuildCheckEventArgs buildCheckBuildEventArgs)
}

private bool IsMetaProjFile(string? projectFile) => !string.IsNullOrEmpty(projectFile) && projectFile!.EndsWith(".metaproj", StringComparison.OrdinalIgnoreCase);

private void EventSource_AnyEventRaised(object sender, BuildEventArgs e)
{
if (_eventHandlers.TryGetValue(e.GetType(), out Action<BuildEventArgs>? handler))
{
if (buildCheckBuildEventArgs is BuildCheckTracingEventArgs tracingEventArgs)
{
_stats.Merge(tracingEventArgs.TracingData, (span1, span2) => span1 + span2);
}
else if (buildCheckBuildEventArgs is BuildCheckAcquisitionEventArgs acquisitionEventArgs)
{
buildCheckManager.ProcessAnalyzerAcquisition(acquisitionEventArgs.ToAnalyzerAcquisitionData());
}
handler(e);
}
}

private readonly Dictionary<string, TimeSpan> _stats = new Dictionary<string, TimeSpan>();

private void EventSource_BuildFinished(object sender, BuildFinishedEventArgs e)
{
_stats.Merge(buildCheckManager.CreateTracingStats(), (span1, span2) => span1 + span2);
_stats.Merge(_buildCheckManager.CreateTracingStats(), (span1, span2) => span1 + span2);
string msg = string.Join(Environment.NewLine, _stats.Select(a => a.Key + ": " + a.Value));

BuildEventContext buildEventContext = e.BuildEventContext ?? new BuildEventContext(
BuildEventContext.InvalidNodeId, BuildEventContext.InvalidTargetId,
BuildEventContext.InvalidProjectContextId, BuildEventContext.InvalidTaskId);
BuildEventContext buildEventContext = e.BuildEventContext
?? new BuildEventContext(
BuildEventContext.InvalidNodeId,
BuildEventContext.InvalidTargetId,
BuildEventContext.InvalidProjectContextId,
BuildEventContext.InvalidTaskId);

LoggingContext loggingContext = loggingContextFactory.CreateLoggingContext(buildEventContext);
LoggingContext loggingContext = _loggingContextFactory.CreateLoggingContext(buildEventContext);

// Tracing: https://github.com/dotnet/msbuild/issues/9629
loggingContext.LogCommentFromText(MessageImportance.High, msg);
}

public void Shutdown()
{ }
private Dictionary<Type, Action<BuildEventArgs>> GetBuildEventHandlers() => new()
{
{ typeof(ProjectEvaluationFinishedEventArgs), (BuildEventArgs e) => HandleProjectEvaluationFinishedEvent((ProjectEvaluationFinishedEventArgs) e) },
{ typeof(ProjectEvaluationStartedEventArgs), (BuildEventArgs e) => HandleProjectEvaluationStartedEvent((ProjectEvaluationStartedEventArgs) e) },
{ typeof(ProjectStartedEventArgs), (BuildEventArgs e) => _buildCheckManager.StartProjectRequest(BuildCheckDataSource.EventArgs, e.BuildEventContext!) },
{ typeof(ProjectFinishedEventArgs), (BuildEventArgs e) => _buildCheckManager.EndProjectRequest(BuildCheckDataSource.EventArgs, e.BuildEventContext!) },
{ typeof(BuildCheckTracingEventArgs), (BuildEventArgs e) => _stats.Merge(((BuildCheckTracingEventArgs)e).TracingData, (span1, span2) => span1 + span2) },
{ typeof(BuildCheckAcquisitionEventArgs), (BuildEventArgs e) => _buildCheckManager.ProcessAnalyzerAcquisition(((BuildCheckAcquisitionEventArgs)e).ToAnalyzerAcquisitionData(), e.BuildEventContext!) },
};
}
Loading
Loading