Optimize namespace comparisons (#17119)
Fixes: #16922 Improves the performance significantly by avoiding allocations for the purpose of comparing the namespace.
This commit is contained in:
parent
7cbe8aa5e3
commit
2ff8f45193
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using Microsoft.AspNetCore.Components.Analyzers;
|
using Microsoft.AspNetCore.Components.Analyzers;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
@ -15,6 +16,8 @@ namespace Microsoft.Extensions.Internal
|
||||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||||
public class ComponentInternalUsageDiagnosticAnalyzer : DiagnosticAnalyzer
|
public class ComponentInternalUsageDiagnosticAnalyzer : DiagnosticAnalyzer
|
||||||
{
|
{
|
||||||
|
private static readonly string[] NamespaceParts = new[] { "RenderTree", "Components", "AspNetCore", "Microsoft", };
|
||||||
|
|
||||||
private readonly InternalUsageAnalyzer _inner;
|
private readonly InternalUsageAnalyzer _inner;
|
||||||
|
|
||||||
public ComponentInternalUsageDiagnosticAnalyzer()
|
public ComponentInternalUsageDiagnosticAnalyzer()
|
||||||
|
|
@ -27,17 +30,25 @@ namespace Microsoft.Extensions.Internal
|
||||||
|
|
||||||
public override void Initialize(AnalysisContext context)
|
public override void Initialize(AnalysisContext context)
|
||||||
{
|
{
|
||||||
|
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
|
||||||
|
|
||||||
_inner.Register(context);
|
_inner.Register(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsInInternalNamespace(ISymbol symbol)
|
private static bool IsInInternalNamespace(ISymbol symbol)
|
||||||
{
|
{
|
||||||
if (symbol?.ContainingNamespace?.ToDisplayString() is string ns)
|
var @namespace = symbol?.ContainingNamespace;
|
||||||
|
for (var i = 0; i < NamespaceParts.Length; i++)
|
||||||
{
|
{
|
||||||
return string.Equals(ns, "Microsoft.AspNetCore.Components.RenderTree");
|
if (@namespace == null || !string.Equals(NamespaceParts[i], @namespace.Name, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@namespace = @namespace.ContainingNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return @namespace.IsGlobalNamespace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ namespace Microsoft.Extensions.Internal
|
||||||
context.RegisterOperationAction(
|
context.RegisterOperationAction(
|
||||||
AnalyzeOperation,
|
AnalyzeOperation,
|
||||||
OperationKind.ObjectCreation,
|
OperationKind.ObjectCreation,
|
||||||
|
OperationKind.Invocation,
|
||||||
OperationKind.FieldReference,
|
OperationKind.FieldReference,
|
||||||
OperationKind.MethodReference,
|
OperationKind.MethodReference,
|
||||||
OperationKind.PropertyReference,
|
OperationKind.PropertyReference,
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,11 @@ namespace Microsoft.AspNetCore.Components.Analyzers
|
||||||
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMField"], diagnostic.Location);
|
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMField"], diagnostic.Location);
|
||||||
},
|
},
|
||||||
diagnostic =>
|
diagnostic =>
|
||||||
|
{
|
||||||
|
Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor);
|
||||||
|
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMInvocation"], diagnostic.Location);
|
||||||
|
},
|
||||||
|
diagnostic =>
|
||||||
{
|
{
|
||||||
Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor);
|
Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor);
|
||||||
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMProperty"], diagnostic.Location);
|
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMProperty"], diagnostic.Location);
|
||||||
|
|
@ -84,6 +89,16 @@ namespace Microsoft.AspNetCore.Components.Analyzers
|
||||||
{
|
{
|
||||||
Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor);
|
Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor);
|
||||||
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMProperty"], diagnostic.Location);
|
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMProperty"], diagnostic.Location);
|
||||||
|
},
|
||||||
|
diagnostic =>
|
||||||
|
{
|
||||||
|
Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor);
|
||||||
|
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMNewObject2"], diagnostic.Location);
|
||||||
|
},
|
||||||
|
diagnostic =>
|
||||||
|
{
|
||||||
|
Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor);
|
||||||
|
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMInvocation"], diagnostic.Location);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ namespace Microsoft.AspNetCore.Components.Analyzers.Tests.TestFiles.ComponentInt
|
||||||
|
|
||||||
var frame = /*MMNewObject*/new RenderTreeFrame();
|
var frame = /*MMNewObject*/new RenderTreeFrame();
|
||||||
GC.KeepAlive(/*MMProperty*/frame.Component);
|
GC.KeepAlive(/*MMProperty*/frame.Component);
|
||||||
}
|
|
||||||
|
|
||||||
|
var range = /*MMNewObject2*/new ArrayRange<string>(null, 0);
|
||||||
|
/*MMInvocation*/range.Clone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers.Tests.TestFiles.ComponentInt
|
||||||
private Renderer /*MMField*/_field = null;
|
private Renderer /*MMField*/_field = null;
|
||||||
|
|
||||||
public UsesRendererTypesInDeclarations()
|
public UsesRendererTypesInDeclarations()
|
||||||
: base(null, null)
|
/*MMInvocation*/: base(null, null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue