From b58e228f89367eb19678754aab3358b24e7241d0 Mon Sep 17 00:00:00 2001 From: Chris Sienkiewicz Date: Tue, 13 May 2025 10:15:18 -0700 Subject: [PATCH 1/4] Add a new analyzer + baseline for existing: - Adds a new analyzer that looks for creations of IntermediateToken with a type of CSharp - Adds a baseline file that covers all existing usages - Warns if any new usages are introduced - Adds a startup profile for the local analyzers that runs them on the compiler project --- .../DiagnosticCategory.cs | 2 + .../DiagnosticIds.cs | 2 + .../GlobalSuppressions.cs | 1 + .../IntermediateTokenAnalyzer.cs | 126 ++++++++++++++++++ .../Properties/launchSettings.json | 11 ++ .../Razor.Diagnostics.Analyzers.csproj | 1 + .../src/IntermediateTokenBaseline.txt | 82 ++++++++++++ ...crosoft.CodeAnalysis.Razor.Compiler.csproj | 4 + 8 files changed, 229 insertions(+) create mode 100644 src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs create mode 100644 src/Analyzers/Razor.Diagnostics.Analyzers/Properties/launchSettings.json create mode 100644 src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt diff --git a/src/Analyzers/Razor.Diagnostics.Analyzers/DiagnosticCategory.cs b/src/Analyzers/Razor.Diagnostics.Analyzers/DiagnosticCategory.cs index 23c96fb1651..120723a31de 100644 --- a/src/Analyzers/Razor.Diagnostics.Analyzers/DiagnosticCategory.cs +++ b/src/Analyzers/Razor.Diagnostics.Analyzers/DiagnosticCategory.cs @@ -6,4 +6,6 @@ namespace Razor.Diagnostics.Analyzers; internal static class DiagnosticCategory { public const string Reliability = nameof(Reliability); + + public const string Usage = nameof(Usage); } diff --git a/src/Analyzers/Razor.Diagnostics.Analyzers/DiagnosticIds.cs b/src/Analyzers/Razor.Diagnostics.Analyzers/DiagnosticIds.cs index a8085d5f252..6532426b192 100644 --- a/src/Analyzers/Razor.Diagnostics.Analyzers/DiagnosticIds.cs +++ b/src/Analyzers/Razor.Diagnostics.Analyzers/DiagnosticIds.cs @@ -8,4 +8,6 @@ internal static class DiagnosticIds public const string PooledArrayBuilderAsRef = "RZD001"; public const string IRemoteJsonServiceParameter = "RZD002"; + + public const string RawIntermediateTokenCreation = "RZD003"; } diff --git a/src/Analyzers/Razor.Diagnostics.Analyzers/GlobalSuppressions.cs b/src/Analyzers/Razor.Diagnostics.Analyzers/GlobalSuppressions.cs index 836b20ab931..71d37cab462 100644 --- a/src/Analyzers/Razor.Diagnostics.Analyzers/GlobalSuppressions.cs +++ b/src/Analyzers/Razor.Diagnostics.Analyzers/GlobalSuppressions.cs @@ -10,3 +10,4 @@ [assembly: SuppressMessage("MicrosoftCodeAnalysisReleaseTracking", "RS2008:Enable analyzer release tracking", Justification = "", Scope = "member", Target = "~F:Razor.Diagnostics.Analyzers.PooledArrayBuilderAsRefAnalyzer.Rule")] [assembly: SuppressMessage("MicrosoftCodeAnalysisReleaseTracking", "RS2008:Enable analyzer release tracking", Justification = "", Scope = "member", Target = "~F:Razor.Diagnostics.Analyzers.IRemoteJsonServiceParameterAnalyzer.Rule")] +[assembly: SuppressMessage("MicrosoftCodeAnalysisReleaseTracking", "RS2008:Enable analyzer release tracking", Justification = "", Scope = "member", Target = "~F:Razor.Diagnostics.Analyzers.IntermediateTokenAnalyzer.Rule")] diff --git a/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs b/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs new file mode 100644 index 00000000000..b93fd3e2f32 --- /dev/null +++ b/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs @@ -0,0 +1,126 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.IO; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; + +namespace Razor.Diagnostics.Analyzers; + +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public class IntermediateTokenAnalyzer : DiagnosticAnalyzer +{ + private const string Title = "IntermediateToken with Kind CSharp"; + private const string MessageFormat = "Avoid directly creating an IntermediateToken with Kind 'CSharp'. Instead, lower to an appropriate intermediate node and emit the C# in the output writer."; + private const string BaselineFileName = "IntermediateTokenBaseline.txt"; + + internal static readonly DiagnosticDescriptor Rule = new( + DiagnosticIds.RawIntermediateTokenCreation, + Title, + MessageFormat, + DiagnosticCategory.Usage, + DiagnosticSeverity.Warning, + isEnabledByDefault: true); + + public override ImmutableArray SupportedDiagnostics => [Rule]; + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); + + context.RegisterOperationAction(AnalyzeObjectCreation, OperationKind.ObjectCreation); + context.RegisterOperationAction(AnalyzeMethodInvocation, OperationKind.Invocation); + } + + private void AnalyzeObjectCreation(OperationAnalysisContext context) + { + var objectCreation = (IObjectCreationOperation)context.Operation; + + // Check if the type is IntermediateToken + if (objectCreation.Type?.Name != "IntermediateToken") + { + return; + } + + // Resolve the TokenKind.CSharp enum value + var tokenKindType = context.Compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Razor.Language.Intermediate.TokenKind"); + if (tokenKindType == null) + { + return; // TokenKind enum not found + } + + var csharpEnumMember = tokenKindType.GetMembers("CSharp").FirstOrDefault() as IFieldSymbol; + if (csharpEnumMember == null) + { + return; // TokenKind.CSharp enum member not found + } + + // Check if the Kind property is set to TokenKind.CSharp via an initializer + var kindInitializer = objectCreation.Initializer?.Initializers + .OfType() + .FirstOrDefault(init => + init.Target is IPropertyReferenceOperation property && + property.Property.Name == "Kind" && + init.Value.ConstantValue.HasValue && + init.Value.ConstantValue.Value == csharpEnumMember.ConstantValue); + + // If the initializer doesnt set Kind to TokenKind.CSharp, return + if (kindInitializer == null) + { + return; + } + + // Report the diagnostic if not suppressed + ReportIfNotSuppressed(context, objectCreation.Syntax.GetLocation()); + } + + private void AnalyzeMethodInvocation(OperationAnalysisContext context) + { + var invocation = (IInvocationOperation)context.Operation; + + // Check if the method is IntermediateToken.CreateCSharpToken + if (invocation.TargetMethod.Name != "CreateCSharpToken" || + invocation.TargetMethod.ContainingType.Name != "IntermediateToken") + { + return; + } + + ReportIfNotSuppressed(context, invocation.Syntax.GetLocation()); + } + + private void ReportIfNotSuppressed(OperationAnalysisContext context, Location location) + { + // If we're a test project, ignore. + if (context.Compilation.AssemblyName?.Contains(".Test") == true) + { + return; + } + + // Check if the warning is suppressed in the baseline file + // Note: code for regenerating the baseline from scratch can be found here: https://gist.github.com/chsienki/d06b2a3ee583191cacf80da79f6fc540 + var additionalFiles = context.Options.AdditionalFiles; + var baselineFile = additionalFiles.FirstOrDefault(file => Path.GetFileName(file.Path) == BaselineFileName); + if (baselineFile != null) + { + var baselineDirectory = Path.GetDirectoryName(baselineFile.Path); + var locationFilePath = location.SourceTree?.FilePath; + + var relativePath = locationFilePath?.Substring(baselineDirectory?.Length + 1 ?? 0); + var linePosition = location.GetLineSpan().StartLinePosition; + var locationString = $"{relativePath}:{linePosition.Line + 1}:{linePosition.Character + 1}"; + + var baselineContent = baselineFile.GetText(context.CancellationToken)?.ToString(); + if (baselineContent != null && baselineContent.Contains(locationString)) + { + return; + } + } + + // Report the diagnostic + context.ReportDiagnostic(Diagnostic.Create(Rule, location)); + } +} diff --git a/src/Analyzers/Razor.Diagnostics.Analyzers/Properties/launchSettings.json b/src/Analyzers/Razor.Diagnostics.Analyzers/Properties/launchSettings.json new file mode 100644 index 00000000000..9cb7fad3483 --- /dev/null +++ b/src/Analyzers/Razor.Diagnostics.Analyzers/Properties/launchSettings.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "Razor.Diagnostics.Analyzers": { + "commandName": "Project" + }, + "Run on Razor.Compiler": { + "commandName": "DebugRoslynComponent", + "targetProject": "..\\..\\Compiler\\Microsoft.CodeAnalysis.Razor.Compiler\\src\\Microsoft.CodeAnalysis.Razor.Compiler.csproj" + } + } +} \ No newline at end of file diff --git a/src/Analyzers/Razor.Diagnostics.Analyzers/Razor.Diagnostics.Analyzers.csproj b/src/Analyzers/Razor.Diagnostics.Analyzers/Razor.Diagnostics.Analyzers.csproj index 345b7c9363f..71073959c7e 100644 --- a/src/Analyzers/Razor.Diagnostics.Analyzers/Razor.Diagnostics.Analyzers.csproj +++ b/src/Analyzers/Razor.Diagnostics.Analyzers/Razor.Diagnostics.Analyzers.csproj @@ -6,6 +6,7 @@ true false false + true diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt new file mode 100644 index 00000000000..3e2633d2e21 --- /dev/null +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt @@ -0,0 +1,82 @@ +Mvc\PagesPropertyInjectionPass.cs:32:34 +Mvc\PagesPropertyInjectionPass.cs:42:40 +Language\Intermediate\IntermediateToken.cs:22:103 +Language\Components\ComponentBindLoweringPass.cs:404:22 +Language\Components\ComponentBindLoweringPass.cs:421:23 +Language\Components\ComponentBindLoweringPass.cs:591:57 +Language\Components\ComponentBindLoweringPass.cs:812:40 +Language\Components\ComponentBindLoweringPass.cs:835:40 +Language\Components\ComponentBindLoweringPass.cs:841:40 +Language\Components\ComponentBindLoweringPass.cs:850:40 +Language\Components\ComponentBindLoweringPass.cs:871:36 +Language\Components\ComponentBindLoweringPass.cs:880:40 +Language\Components\ComponentBindLoweringPass.cs:895:40 +Language\Components\ComponentBindLoweringPass.cs:901:40 +Language\Components\ComponentBindLoweringPass.cs:910:40 +Language\Components\ComponentBindLoweringPass.cs:916:40 +Language\Components\ComponentBindLoweringPass.cs:922:40 +Language\Components\ComponentBindLoweringPass.cs:929:36 +Language\Components\ComponentBindLoweringPass.cs:951:35 +Language\Components\ComponentBindLoweringPass.cs:960:39 +Language\Components\ComponentBindLoweringPass.cs:970:39 +Language\Components\ComponentBindLoweringPass.cs:978:35 +Language\Components\ComponentBindLoweringPass.cs:1001:36 +Language\Components\ComponentBindLoweringPass.cs:1010:40 +Language\Components\ComponentBindLoweringPass.cs:1019:40 +Language\Components\ComponentBindLoweringPass.cs:1025:40 +Language\Components\ComponentBindLoweringPass.cs:1034:40 +Language\Components\ComponentBindLoweringPass.cs:1040:40 +Language\Components\ComponentBindLoweringPass.cs:1049:40 +Language\Components\ComponentBindLoweringPass.cs:1055:40 +Language\Components\ComponentBindLoweringPass.cs:1061:40 +Language\Components\ComponentBindLoweringPass.cs:1068:36 +Language\Components\ComponentBindLoweringPass.cs:1074:36 +Language\Components\ComponentBindLoweringPass.cs:1082:40 +Language\Components\ComponentBindLoweringPass.cs:1091:40 +Language\Components\ComponentBindLoweringPass.cs:1098:36 +Language\Components\ComponentBindLoweringPass.cs:1113:20 +Language\Components\ComponentBindLoweringPass.cs:1121:20 +Language\Components\ComponentBindLoweringPass.cs:1143:20 +Mvc\ModelDirective.cs:61:24 +Mvc\ModelDirective.cs:67:20 +Mvc\ModelDirective.cs:71:20 +Language\Extensions\AttributeDirectivePass.cs:33:35 +Language\Components\ComponentLayoutDirectivePass.cs:37:13 +Language\Components\ComponentLayoutDirectivePass.cs:38:13 +Language\Components\ComponentLayoutDirectivePass.cs:39:13 +Language\Components\ComponentEventHandlerLoweringPass.cs:181:13 +Language\Components\ComponentEventHandlerLoweringPass.cs:193:13 +Language\Components\ComponentEventHandlerLoweringPass.cs:263:28 +Language\Components\ComponentEventHandlerLoweringPass.cs:273:28 +Language\Extensions\DesignTimeDirectivePass.cs:42:25 +Language\Extensions\DesignTimeDirectivePass.cs:53:25 +Language\Extensions\DesignTimeDirectivePass.cs:64:25 +Language\Components\ComponentRenderModeDirectivePass.cs:51:17 +Language\Components\ComponentRenderModeDirectivePass.cs:63:28 +Language\Components\ComponentRenderModeDirectivePass.cs:70:17 +Language\Components\ComponentRenderModeDirectivePass.cs:81:17 +Language\Components\ComponentRenderModeDirectivePass.cs:93:36 +Mvc\ModelExpressionPass.cs:43:41 +Mvc\ModelExpressionPass.cs:53:45 +Mvc\ModelExpressionPass.cs:81:41 +Language\Components\ComponentRuntimeNodeWriter.cs:1048:25 +Language\Components\ComponentRuntimeNodeWriter.cs:1066:17 +Language\Components\ComponentRuntimeNodeWriter.cs:1076:17 +Mvc.Version2_X\PagesPropertyInjectionPass.cs:28:34 +Mvc.Version2_X\PagesPropertyInjectionPass.cs:36:36 +Mvc.Version2_X\AssemblyAttributeInjectionPass.cs:70:36 +Language\Extensions\EliminateMethodBodyPass.cs:47:21 +Language\Extensions\EliminateMethodBodyPass.cs:54:21 +Language\Extensions\EliminateMethodBodyPass.cs:61:21 +Language\Intermediate\BaseTypeWithModel.cs:14:24 +Language\Intermediate\BaseTypeWithModel.cs:15:27 +Language\Intermediate\BaseTypeWithModel.cs:16:25 +Language\Intermediate\BaseTypeWithModel.cs:17:24 +Language\Intermediate\BaseTypeWithModel.cs:30:24 +Mvc.Version2_X\InstrumentationPass.cs:42:32 +Mvc.Version2_X\InstrumentationPass.cs:55:30 +Language\Extensions\ImplementsDirectivePass.cs:26:39 +Language\Components\ComponentDesignTimeNodeWriter.cs:1181:25 +Language\Components\ComponentDesignTimeNodeWriter.cs:1205:29 +Language\Components\ComponentDesignTimeNodeWriter.cs:1224:17 +Language\Components\ComponentDesignTimeNodeWriter.cs:1234:17 diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Microsoft.CodeAnalysis.Razor.Compiler.csproj b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Microsoft.CodeAnalysis.Razor.Compiler.csproj index 3d491fee7b9..e4b63e4093e 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Microsoft.CodeAnalysis.Razor.Compiler.csproj +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Microsoft.CodeAnalysis.Razor.Compiler.csproj @@ -15,6 +15,10 @@ $(NoWarn);RS2008;RS1036 + + + + From 3754bd4e894c88283e7ba3c3a526b6bf7c0eeed7 Mon Sep 17 00:00:00 2001 From: Chris Sienkiewicz Date: Tue, 13 May 2025 10:30:45 -0700 Subject: [PATCH 2/4] Normalize file paths --- .../IntermediateTokenAnalyzer.cs | 2 +- .../src/IntermediateTokenBaseline.txt | 164 +++++++++--------- 2 files changed, 83 insertions(+), 83 deletions(-) diff --git a/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs b/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs index b93fd3e2f32..d2affabf8e6 100644 --- a/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs +++ b/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs @@ -109,7 +109,7 @@ private void ReportIfNotSuppressed(OperationAnalysisContext context, Location lo var baselineDirectory = Path.GetDirectoryName(baselineFile.Path); var locationFilePath = location.SourceTree?.FilePath; - var relativePath = locationFilePath?.Substring(baselineDirectory?.Length + 1 ?? 0); + var relativePath = locationFilePath?.Substring(baselineDirectory?.Length + 1 ?? 0).Replace("\\", "/"); var linePosition = location.GetLineSpan().StartLinePosition; var locationString = $"{relativePath}:{linePosition.Line + 1}:{linePosition.Character + 1}"; diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt index 3e2633d2e21..3341f26e8d4 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt @@ -1,82 +1,82 @@ -Mvc\PagesPropertyInjectionPass.cs:32:34 -Mvc\PagesPropertyInjectionPass.cs:42:40 -Language\Intermediate\IntermediateToken.cs:22:103 -Language\Components\ComponentBindLoweringPass.cs:404:22 -Language\Components\ComponentBindLoweringPass.cs:421:23 -Language\Components\ComponentBindLoweringPass.cs:591:57 -Language\Components\ComponentBindLoweringPass.cs:812:40 -Language\Components\ComponentBindLoweringPass.cs:835:40 -Language\Components\ComponentBindLoweringPass.cs:841:40 -Language\Components\ComponentBindLoweringPass.cs:850:40 -Language\Components\ComponentBindLoweringPass.cs:871:36 -Language\Components\ComponentBindLoweringPass.cs:880:40 -Language\Components\ComponentBindLoweringPass.cs:895:40 -Language\Components\ComponentBindLoweringPass.cs:901:40 -Language\Components\ComponentBindLoweringPass.cs:910:40 -Language\Components\ComponentBindLoweringPass.cs:916:40 -Language\Components\ComponentBindLoweringPass.cs:922:40 -Language\Components\ComponentBindLoweringPass.cs:929:36 -Language\Components\ComponentBindLoweringPass.cs:951:35 -Language\Components\ComponentBindLoweringPass.cs:960:39 -Language\Components\ComponentBindLoweringPass.cs:970:39 -Language\Components\ComponentBindLoweringPass.cs:978:35 -Language\Components\ComponentBindLoweringPass.cs:1001:36 -Language\Components\ComponentBindLoweringPass.cs:1010:40 -Language\Components\ComponentBindLoweringPass.cs:1019:40 -Language\Components\ComponentBindLoweringPass.cs:1025:40 -Language\Components\ComponentBindLoweringPass.cs:1034:40 -Language\Components\ComponentBindLoweringPass.cs:1040:40 -Language\Components\ComponentBindLoweringPass.cs:1049:40 -Language\Components\ComponentBindLoweringPass.cs:1055:40 -Language\Components\ComponentBindLoweringPass.cs:1061:40 -Language\Components\ComponentBindLoweringPass.cs:1068:36 -Language\Components\ComponentBindLoweringPass.cs:1074:36 -Language\Components\ComponentBindLoweringPass.cs:1082:40 -Language\Components\ComponentBindLoweringPass.cs:1091:40 -Language\Components\ComponentBindLoweringPass.cs:1098:36 -Language\Components\ComponentBindLoweringPass.cs:1113:20 -Language\Components\ComponentBindLoweringPass.cs:1121:20 -Language\Components\ComponentBindLoweringPass.cs:1143:20 -Mvc\ModelDirective.cs:61:24 -Mvc\ModelDirective.cs:67:20 -Mvc\ModelDirective.cs:71:20 -Language\Extensions\AttributeDirectivePass.cs:33:35 -Language\Components\ComponentLayoutDirectivePass.cs:37:13 -Language\Components\ComponentLayoutDirectivePass.cs:38:13 -Language\Components\ComponentLayoutDirectivePass.cs:39:13 -Language\Components\ComponentEventHandlerLoweringPass.cs:181:13 -Language\Components\ComponentEventHandlerLoweringPass.cs:193:13 -Language\Components\ComponentEventHandlerLoweringPass.cs:263:28 -Language\Components\ComponentEventHandlerLoweringPass.cs:273:28 -Language\Extensions\DesignTimeDirectivePass.cs:42:25 -Language\Extensions\DesignTimeDirectivePass.cs:53:25 -Language\Extensions\DesignTimeDirectivePass.cs:64:25 -Language\Components\ComponentRenderModeDirectivePass.cs:51:17 -Language\Components\ComponentRenderModeDirectivePass.cs:63:28 -Language\Components\ComponentRenderModeDirectivePass.cs:70:17 -Language\Components\ComponentRenderModeDirectivePass.cs:81:17 -Language\Components\ComponentRenderModeDirectivePass.cs:93:36 -Mvc\ModelExpressionPass.cs:43:41 -Mvc\ModelExpressionPass.cs:53:45 -Mvc\ModelExpressionPass.cs:81:41 -Language\Components\ComponentRuntimeNodeWriter.cs:1048:25 -Language\Components\ComponentRuntimeNodeWriter.cs:1066:17 -Language\Components\ComponentRuntimeNodeWriter.cs:1076:17 -Mvc.Version2_X\PagesPropertyInjectionPass.cs:28:34 -Mvc.Version2_X\PagesPropertyInjectionPass.cs:36:36 -Mvc.Version2_X\AssemblyAttributeInjectionPass.cs:70:36 -Language\Extensions\EliminateMethodBodyPass.cs:47:21 -Language\Extensions\EliminateMethodBodyPass.cs:54:21 -Language\Extensions\EliminateMethodBodyPass.cs:61:21 -Language\Intermediate\BaseTypeWithModel.cs:14:24 -Language\Intermediate\BaseTypeWithModel.cs:15:27 -Language\Intermediate\BaseTypeWithModel.cs:16:25 -Language\Intermediate\BaseTypeWithModel.cs:17:24 -Language\Intermediate\BaseTypeWithModel.cs:30:24 -Mvc.Version2_X\InstrumentationPass.cs:42:32 -Mvc.Version2_X\InstrumentationPass.cs:55:30 -Language\Extensions\ImplementsDirectivePass.cs:26:39 -Language\Components\ComponentDesignTimeNodeWriter.cs:1181:25 -Language\Components\ComponentDesignTimeNodeWriter.cs:1205:29 -Language\Components\ComponentDesignTimeNodeWriter.cs:1224:17 -Language\Components\ComponentDesignTimeNodeWriter.cs:1234:17 +Mvc/PagesPropertyInjectionPass.cs:32:34 +Mvc/PagesPropertyInjectionPass.cs:42:40 +Language/Intermediate/IntermediateToken.cs:22:103 +Language/Components/ComponentBindLoweringPass.cs:404:22 +Language/Components/ComponentBindLoweringPass.cs:421:23 +Language/Components/ComponentBindLoweringPass.cs:591:57 +Language/Components/ComponentBindLoweringPass.cs:812:40 +Language/Components/ComponentBindLoweringPass.cs:835:40 +Language/Components/ComponentBindLoweringPass.cs:841:40 +Language/Components/ComponentBindLoweringPass.cs:850:40 +Language/Components/ComponentBindLoweringPass.cs:871:36 +Language/Components/ComponentBindLoweringPass.cs:880:40 +Language/Components/ComponentBindLoweringPass.cs:895:40 +Language/Components/ComponentBindLoweringPass.cs:901:40 +Language/Components/ComponentBindLoweringPass.cs:910:40 +Language/Components/ComponentBindLoweringPass.cs:916:40 +Language/Components/ComponentBindLoweringPass.cs:922:40 +Language/Components/ComponentBindLoweringPass.cs:929:36 +Language/Components/ComponentBindLoweringPass.cs:951:35 +Language/Components/ComponentBindLoweringPass.cs:960:39 +Language/Components/ComponentBindLoweringPass.cs:970:39 +Language/Components/ComponentBindLoweringPass.cs:978:35 +Language/Components/ComponentBindLoweringPass.cs:1001:36 +Language/Components/ComponentBindLoweringPass.cs:1010:40 +Language/Components/ComponentBindLoweringPass.cs:1019:40 +Language/Components/ComponentBindLoweringPass.cs:1025:40 +Language/Components/ComponentBindLoweringPass.cs:1034:40 +Language/Components/ComponentBindLoweringPass.cs:1040:40 +Language/Components/ComponentBindLoweringPass.cs:1049:40 +Language/Components/ComponentBindLoweringPass.cs:1055:40 +Language/Components/ComponentBindLoweringPass.cs:1061:40 +Language/Components/ComponentBindLoweringPass.cs:1068:36 +Language/Components/ComponentBindLoweringPass.cs:1074:36 +Language/Components/ComponentBindLoweringPass.cs:1082:40 +Language/Components/ComponentBindLoweringPass.cs:1091:40 +Language/Components/ComponentBindLoweringPass.cs:1098:36 +Language/Components/ComponentBindLoweringPass.cs:1113:20 +Language/Components/ComponentBindLoweringPass.cs:1121:20 +Language/Components/ComponentBindLoweringPass.cs:1143:20 +Mvc/ModelDirective.cs:61:24 +Mvc/ModelDirective.cs:67:20 +Mvc/ModelDirective.cs:71:20 +Language/Extensions/AttributeDirectivePass.cs:33:35 +Language/Components/ComponentLayoutDirectivePass.cs:37:13 +Language/Components/ComponentLayoutDirectivePass.cs:38:13 +Language/Components/ComponentLayoutDirectivePass.cs:39:13 +Language/Components/ComponentEventHandlerLoweringPass.cs:181:13 +Language/Components/ComponentEventHandlerLoweringPass.cs:193:13 +Language/Components/ComponentEventHandlerLoweringPass.cs:263:28 +Language/Components/ComponentEventHandlerLoweringPass.cs:273:28 +Language/Extensions/DesignTimeDirectivePass.cs:42:25 +Language/Extensions/DesignTimeDirectivePass.cs:53:25 +Language/Extensions/DesignTimeDirectivePass.cs:64:25 +Language/Components/ComponentRenderModeDirectivePass.cs:51:17 +Language/Components/ComponentRenderModeDirectivePass.cs:63:28 +Language/Components/ComponentRenderModeDirectivePass.cs:70:17 +Language/Components/ComponentRenderModeDirectivePass.cs:81:17 +Language/Components/ComponentRenderModeDirectivePass.cs:93:36 +Mvc/ModelExpressionPass.cs:43:41 +Mvc/ModelExpressionPass.cs:53:45 +Mvc/ModelExpressionPass.cs:81:41 +Language/Components/ComponentRuntimeNodeWriter.cs:1048:25 +Language/Components/ComponentRuntimeNodeWriter.cs:1066:17 +Language/Components/ComponentRuntimeNodeWriter.cs:1076:17 +Mvc.Version2_X/PagesPropertyInjectionPass.cs:28:34 +Mvc.Version2_X/PagesPropertyInjectionPass.cs:36:36 +Mvc.Version2_X/AssemblyAttributeInjectionPass.cs:70:36 +Language/Extensions/EliminateMethodBodyPass.cs:47:21 +Language/Extensions/EliminateMethodBodyPass.cs:54:21 +Language/Extensions/EliminateMethodBodyPass.cs:61:21 +Language/Intermediate/BaseTypeWithModel.cs:14:24 +Language/Intermediate/BaseTypeWithModel.cs:15:27 +Language/Intermediate/BaseTypeWithModel.cs:16:25 +Language/Intermediate/BaseTypeWithModel.cs:17:24 +Language/Intermediate/BaseTypeWithModel.cs:30:24 +Mvc.Version2_X/InstrumentationPass.cs:42:32 +Mvc.Version2_X/InstrumentationPass.cs:55:30 +Language/Extensions/ImplementsDirectivePass.cs:26:39 +Language/Components/ComponentDesignTimeNodeWriter.cs:1181:25 +Language/Components/ComponentDesignTimeNodeWriter.cs:1205:29 +Language/Components/ComponentDesignTimeNodeWriter.cs:1224:17 +Language/Components/ComponentDesignTimeNodeWriter.cs:1234:17 From 9150b0445f50ff62e2e679eaeff111fd2c5fe60a Mon Sep 17 00:00:00 2001 From: Chris Sienkiewicz Date: Tue, 13 May 2025 14:10:36 -0700 Subject: [PATCH 3/4] Fixup baselines after rebase --- .../src/IntermediateTokenBaseline.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt index 3341f26e8d4..b95e46b34c8 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/IntermediateTokenBaseline.txt @@ -1,5 +1,5 @@ Mvc/PagesPropertyInjectionPass.cs:32:34 -Mvc/PagesPropertyInjectionPass.cs:42:40 +Mvc/PagesPropertyInjectionPass.cs:40:36 Language/Intermediate/IntermediateToken.cs:22:103 Language/Components/ComponentBindLoweringPass.cs:404:22 Language/Components/ComponentBindLoweringPass.cs:421:23 From c78ce186d19975eeb162e1e3aa945a5010e8c78b Mon Sep 17 00:00:00 2001 From: Chris Sienkiewicz Date: Tue, 13 May 2025 14:19:49 -0700 Subject: [PATCH 4/4] Add help link --- .../Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs b/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs index d2affabf8e6..7e5afd1a532 100644 --- a/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs +++ b/src/Analyzers/Razor.Diagnostics.Analyzers/IntermediateTokenAnalyzer.cs @@ -23,7 +23,8 @@ public class IntermediateTokenAnalyzer : DiagnosticAnalyzer MessageFormat, DiagnosticCategory.Usage, DiagnosticSeverity.Warning, - isEnabledByDefault: true); + isEnabledByDefault: true, + helpLinkUri: "https://github.com/dotnet/razor/issues/11858"); public override ImmutableArray SupportedDiagnostics => [Rule];