diff --git a/src/Mvc/Mvc.Analyzers/src/DiagnosticDescriptors.cs b/src/Mvc/Mvc.Analyzers/src/DiagnosticDescriptors.cs index 8dba4a4a07..c4940b371a 100644 --- a/src/Mvc/Mvc.Analyzers/src/DiagnosticDescriptors.cs +++ b/src/Mvc/Mvc.Analyzers/src/DiagnosticDescriptors.cs @@ -53,7 +53,15 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers isEnabledByDefault: true, helpLinkUri: "https://aka.ms/AA20pbc"); - // MVC1005 reserved for startup + + public static readonly DiagnosticDescriptor MVC1006_FunctionsContainingTagHelpersMustBeAsyncAndReturnTask = + new DiagnosticDescriptor( + "MVC1006", + "Methods containing TagHelpers must be async and return Task.", + "The method contains a TagHelper and therefore must be async and return a Task.", + "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true); } } diff --git a/src/Mvc/Mvc.Analyzers/src/SymbolNames.cs b/src/Mvc/Mvc.Analyzers/src/SymbolNames.cs index f8ac74c657..7b08c9082f 100644 --- a/src/Mvc/Mvc.Analyzers/src/SymbolNames.cs +++ b/src/Mvc/Mvc.Analyzers/src/SymbolNames.cs @@ -72,5 +72,11 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers public const string ConfigureServicesMethod = "ConfigureServices"; public const string ConfigureMethod = "Configure"; + + public const string RunAsyncMethodName = "RunAsync"; + + public const string TaskTypeName = "System.Threading.Tasks.Task"; + + public const string TagHelperRunnerTypeName = "Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner"; } } diff --git a/src/Mvc/Mvc.Analyzers/src/TagHelpersInCodeBlocksAnalyzer.cs b/src/Mvc/Mvc.Analyzers/src/TagHelpersInCodeBlocksAnalyzer.cs new file mode 100644 index 0000000000..9cf680f2e4 --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/src/TagHelpersInCodeBlocksAnalyzer.cs @@ -0,0 +1,184 @@ +// 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. + +using System.Collections.Generic; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public class TagHelpersInCodeBlocksAnalyzer : DiagnosticAnalyzer + { + public TagHelpersInCodeBlocksAnalyzer() + { + TagHelperInCodeBlockDiagnostic = DiagnosticDescriptors.MVC1006_FunctionsContainingTagHelpersMustBeAsyncAndReturnTask; + SupportedDiagnostics = ImmutableArray.Create(new[] { TagHelperInCodeBlockDiagnostic }); + } + + private DiagnosticDescriptor TagHelperInCodeBlockDiagnostic { get; } + + public override ImmutableArray SupportedDiagnostics { get; } + + public override void Initialize(AnalysisContext context) + { + // Generated Razor code is considered auto generated. By default analyzers skip over auto-generated code unless we say otherwise. + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); + context.RegisterCompilationStartAction(context => + { + if (!SymbolCache.TryCreate(context.Compilation, out var symbolCache)) + { + // No-op if we can't find types we care about. + return; + } + + InitializeWorker(context, symbolCache); + }); + } + + private void InitializeWorker(CompilationStartAnalysisContext context, SymbolCache symbolCache) + { + context.RegisterOperationBlockStartAction(startBlockContext => + { + var capturedDiagnosticLocations = new HashSet(); + startBlockContext.RegisterOperationAction(context => + { + var awaitOperation = (IAwaitOperation)context.Operation; + + if (awaitOperation.Operation.Kind != OperationKind.Invocation) + { + return; + } + + var invocationOperation = (IInvocationOperation)awaitOperation.Operation; + + if (!IsTagHelperRunnerRunAsync(invocationOperation.TargetMethod, symbolCache)) + { + return; + } + + var parent = context.Operation.Parent; + while (parent != null && !IsParentMethod(parent)) + { + parent = parent.Parent; + } + + if (parent == null) + { + return; + } + + var methodSymbol = (IMethodSymbol?)(parent switch + { + ILocalFunctionOperation localFunctionOperation => localFunctionOperation.Symbol, + IAnonymousFunctionOperation anonymousFunctionOperation => anonymousFunctionOperation.Symbol, + IMethodBodyOperation methodBodyOperation => startBlockContext.OwningSymbol, + _ => null, + }); + + if (methodSymbol == null) + { + // Unsupported operation type. + return; + } + + if (!methodSymbol.IsAsync || + !symbolCache.TaskType.IsAssignableFrom(methodSymbol.ReturnType)) + { + capturedDiagnosticLocations.Add(parent.Syntax.GetLocation()); + } + + }, OperationKind.Await); + + startBlockContext.RegisterOperationBlockEndAction(context => + { + foreach (var location in capturedDiagnosticLocations) + { + context.ReportDiagnostic( + Diagnostic.Create(TagHelperInCodeBlockDiagnostic, location)); + } + }); + }); + } + + private bool IsTagHelperRunnerRunAsync(IMethodSymbol method, SymbolCache symbolCache) + { + if (method != symbolCache.TagHelperRunnerRunAsyncMethodSymbol) + { + return false; + } + + return true; + } + + private bool IsParentMethod(IOperation operation) + { + if (operation.Kind == OperationKind.LocalFunction) + { + return true; + } + + if (operation.Kind == OperationKind.MethodBody) + { + return true; + } + + if (operation.Kind == OperationKind.AnonymousFunction) + { + return true; + } + + return false; + } + + private readonly struct SymbolCache + { + private SymbolCache( + IMethodSymbol tagHelperRunnerRunAsyncMethodSymbol, + INamedTypeSymbol taskType) + { + TagHelperRunnerRunAsyncMethodSymbol = tagHelperRunnerRunAsyncMethodSymbol; + TaskType = taskType; + } + + public IMethodSymbol TagHelperRunnerRunAsyncMethodSymbol { get; } + + public INamedTypeSymbol TaskType { get; } + + + public static bool TryCreate(Compilation compilation, out SymbolCache symbolCache) + { + symbolCache = default; + + if (!TryGetType(SymbolNames.TagHelperRunnerTypeName, out var tagHelperRunnerType)) + { + return false; + } + + if (!TryGetType(SymbolNames.TaskTypeName, out var taskType)) + { + return false; + } + + var members = tagHelperRunnerType.GetMembers(SymbolNames.RunAsyncMethodName); + if (members.Length == 0) + { + return false; + } + + var tagHelperRunnerRunAsyncMethod = (IMethodSymbol)members[0]; + + symbolCache = new SymbolCache(tagHelperRunnerRunAsyncMethod, taskType); + return true; + + bool TryGetType(string typeName, out INamedTypeSymbol typeSymbol) + { + typeSymbol = compilation.GetTypeByMetadataName(typeName); + return typeSymbol != null && typeSymbol.TypeKind != TypeKind.Error; + } + } + } + } +} diff --git a/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj b/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj index ab2cabb576..1854d54a9d 100644 --- a/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj +++ b/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj @@ -16,6 +16,7 @@ + diff --git a/src/Mvc/Mvc.Analyzers/test/TagHelpersInCodeBlocksAnalyzerTest.cs b/src/Mvc/Mvc.Analyzers/test/TagHelpersInCodeBlocksAnalyzerTest.cs new file mode 100644 index 0000000000..44eea09663 --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TagHelpersInCodeBlocksAnalyzerTest.cs @@ -0,0 +1,93 @@ +// 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. + +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Analyzer.Testing; +using Microsoft.CodeAnalysis; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public class TagHelpersInCodeBlocksAnalyzerTest + { + private readonly DiagnosticDescriptor DiagnosticDescriptor = DiagnosticDescriptors.MVC1006_FunctionsContainingTagHelpersMustBeAsyncAndReturnTask; + + private MvcDiagnosticAnalyzerRunner Executor { get; } = new MvcDiagnosticAnalyzerRunner(new TagHelpersInCodeBlocksAnalyzer()); + + [Fact] + public Task DiagnosticsAreReturned_ForUseOfTagHelpersInActions() + => VerifyDefault(ReadTestSource()); + + [Fact] + public Task DiagnosticsAreReturned_ForUseOfTagHelpersInNonAsyncFunc() + => VerifyDefault(ReadTestSource()); + + [Fact] + public Task DiagnosticsAreReturned_ForUseOfTagHelpersInVoidClassMethods() + => VerifyDefault(ReadTestSource()); + + [Fact] + public Task DiagnosticsAreReturned_ForUseOfTagHelpersInVoidDelegates() + => VerifyDefault(ReadTestSource()); + + [Fact] + public Task DiagnosticsAreReturned_ForUseOfTagHelpersInVoidLocalFunctions() + => VerifyDefault(ReadTestSource()); + + [Fact] + public Task NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncClassMethods() + => VerifyNoDiagnosticsAreReturned(ReadTestSource()); + + [Fact] + public Task NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncDelegates() + => VerifyNoDiagnosticsAreReturned(ReadTestSource()); + + [Fact] + public Task NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncFuncs() + => VerifyNoDiagnosticsAreReturned(ReadTestSource()); + + [Fact] + public Task NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncLocalFunctions() + => VerifyNoDiagnosticsAreReturned(ReadTestSource()); + + [Fact] + public Task SingleDiagnosticIsReturned_ForMultipleTagHelpersInVoidMethod() + => VerifyDefault(ReadTestSource()); + + private async Task VerifyNoDiagnosticsAreReturned(TestSource source) + { + // Act + var result = await Executor.GetDiagnosticsAsync(source.Source); + + // Assert + Assert.Empty(result); + } + + private async Task VerifyDefault(TestSource testSource) + { + // Arrange + var expectedLocation = testSource.DefaultMarkerLocation; + + // Act + var result = await Executor.GetDiagnosticsAsync(testSource.Source); + + // Assert + // We want to ignore C# diagnostics because they'll include diagnostics for not awaiting bits correctly. The purpose of this analyzer is to + // improve on those error messages but not remove them. + var filteredDiagnostics = result.Where(diagnostic => diagnostic.Id.StartsWith("MVC")); + Assert.Collection( + filteredDiagnostics, + diagnostic => + { + Assert.Equal(DiagnosticDescriptor.Id, diagnostic.Id); + Assert.Same(DiagnosticDescriptor, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(expectedLocation, diagnostic.Location); + }); + } + + private static TestSource ReadTestSource([CallerMemberName] string testMethod = "") => + MvcTestSource.Read(nameof(TagHelpersInCodeBlocksAnalyzerTest), testMethod); + } +} diff --git a/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInActions.cs b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInActions.cs new file mode 100644 index 0000000000..da8f2aba00 --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInActions.cs @@ -0,0 +1,80 @@ +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class DiagnosticsAreReturned_ForUseOfTagHelpersInActions : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #line hidden + #pragma warning disable 0169 + private string __tagHelperStringValueBuffer; + #pragma warning restore 0169 + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner(); + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager + { + get + { + if (__backed__tagHelperScopeManager == null) + { + __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope); + } + return __backed__tagHelperScopeManager; + } + } + private global::Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + + Action sometMethod = /*MM*/() => + { + + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "d946c1cd0bbc2f1bde41a0f3eb6596ec7dca5c342925", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + }; + + sometMethod(); + + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInNonAsyncFunc.cs b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInNonAsyncFunc.cs new file mode 100644 index 0000000000..4b58c585c0 --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInNonAsyncFunc.cs @@ -0,0 +1,80 @@ +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class DiagnosticsAreReturned_ForUseOfTagHelpersInNonAsyncFunc : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #line hidden + #pragma warning disable 0169 + private string __tagHelperStringValueBuffer; + #pragma warning restore 0169 + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner(); + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager + { + get + { + if (__backed__tagHelperScopeManager == null) + { + __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope); + } + return __backed__tagHelperScopeManager; + } + } + private global::Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + + Func sometMethod = /*MM*/() => + { + + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "452e9bab960ded6307b3903ebf73278bb1b2bec32959", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + }; + + sometMethod(); + + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInVoidClassMethods.cs b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInVoidClassMethods.cs new file mode 100644 index 0000000000..9197b31eea --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInVoidClassMethods.cs @@ -0,0 +1,82 @@ +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"186d75f4b59675515143af9ff43784abaabd24a9", @"/DiagnosticsAreReturned_ForUseOfTagHelpersInVoidClassMethods.cshtml")] + public class DiagnosticsAreReturned_ForUseOfTagHelpersInVoidClassMethods : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #line hidden + #pragma warning disable 0169 + private string __tagHelperStringValueBuffer; + #pragma warning restore 0169 + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner(); + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager + { + get + { + if (__backed__tagHelperScopeManager == null) + { + __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope); + } + return __backed__tagHelperScopeManager; + } + } + private global::Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + + SometMethod(); + + WriteLiteral("\r\n"); + } + #pragma warning restore 1998 + + /*MM*/void SometMethod() + { + + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "186d75f4b59675515143af9ff43784abaabd24a93243", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + } + + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInVoidDelegates.cs b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInVoidDelegates.cs new file mode 100644 index 0000000000..05bbcdca2a --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInVoidDelegates.cs @@ -0,0 +1,84 @@ +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class DiagnosticsAreReturned_ForUseOfTagHelpersInVoidDelegates : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #line hidden + #pragma warning disable 0169 + private string __tagHelperStringValueBuffer; + #pragma warning restore 0169 + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner(); + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager + { + get + { + if (__backed__tagHelperScopeManager == null) + { + __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope); + } + return __backed__tagHelperScopeManager; + } + } + private global::Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + + TestDelegate sometMethod = /*MM*/delegate () + { + + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "c63f59d4d7a4db461bc9f052a7833885a8d13dcf2972", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + }; + + sometMethod(); + + WriteLiteral("\r\n"); + } + #pragma warning restore 1998 + + delegate void TestDelegate(); + + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInVoidLocalFunctions.cs b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInVoidLocalFunctions.cs new file mode 100644 index 0000000000..ecbb70c6fb --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/DiagnosticsAreReturned_ForUseOfTagHelpersInVoidLocalFunctions.cs @@ -0,0 +1,79 @@ +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class DiagnosticsAreReturned_ForUseOfTagHelpersInVoidLocalFunctions : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #line hidden + #pragma warning disable 0169 + private string __tagHelperStringValueBuffer; + #pragma warning restore 0169 + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner(); + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager + { + get + { + if (__backed__tagHelperScopeManager == null) + { + __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope); + } + return __backed__tagHelperScopeManager; + } + } + private global::Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + + /*MM*/void SometMethod() + { + + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "5a4c42fadc056422c6be6ab14a6bd877e2fa382d2948", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + } + + SometMethod(); + + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncClassMethods.cs b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncClassMethods.cs new file mode 100644 index 0000000000..96e5d17d40 --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncClassMethods.cs @@ -0,0 +1,81 @@ +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncClassMethods_ : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #line hidden + #pragma warning disable 0169 + private string __tagHelperStringValueBuffer; + #pragma warning restore 0169 + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner(); + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager + { + get + { + if (__backed__tagHelperScopeManager == null) + { + __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope); + } + return __backed__tagHelperScopeManager; + } + } + private global::Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + + await SometMethod(); + + WriteLiteral("\r\n"); + } + #pragma warning restore 1998 + + /*MM*/async Task SometMethod() + { + + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "8a14df240fb31e930618408064cdb1e343ff38f43283", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + } + + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncDelegates.cs b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncDelegates.cs new file mode 100644 index 0000000000..4088f69d6d --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncDelegates.cs @@ -0,0 +1,84 @@ +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncDelegates_ : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #line hidden + #pragma warning disable 0169 + private string __tagHelperStringValueBuffer; + #pragma warning restore 0169 + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner(); + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager + { + get + { + if (__backed__tagHelperScopeManager == null) + { + __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope); + } + return __backed__tagHelperScopeManager; + } + } + private global::Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + + TestDelegate sometMethod = /*MM*/async delegate () + { + + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "028e6be2d2e1a766b4ea9e3949a9e9797bb524083002", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + }; + + await sometMethod(); + + WriteLiteral("\r\n"); + } + #pragma warning restore 1998 + + delegate Task TestDelegate(); + + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncFuncs.cs b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncFuncs.cs new file mode 100644 index 0000000000..fafb854956 --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncFuncs.cs @@ -0,0 +1,81 @@ +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"9b77957037efb63a0af38698af1c7de6dc41c4be", @"/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncFuncs.cshtml")] + public class NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncFuncs : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #line hidden + #pragma warning disable 0169 + private string __tagHelperStringValueBuffer; + #pragma warning restore 0169 + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner(); + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager + { + get + { + if (__backed__tagHelperScopeManager == null) + { + __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope); + } + return __backed__tagHelperScopeManager; + } + } + private global::Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + WriteLiteral("\r\n"); + + Func sometMethod = /*MM*/async () => + { + + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "9b77957037efb63a0af38698af1c7de6dc41c4be2965", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + }; + + await sometMethod(); + + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncLocalFunctions.cs b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncLocalFunctions.cs new file mode 100644 index 0000000000..1c06958dbd --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncLocalFunctions.cs @@ -0,0 +1,84 @@ +#pragma checksum "C:\Users\nimullen\Documents\Projects\AnalyzerTest\NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncLocalFunctions..cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d5d5a28106f24c1bb31f07635157a3503dfdcb2d" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncLocalFunctions_), @"mvc.1.0.view", @"/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncLocalFunctions..cshtml")] +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d5d5a28106f24c1bb31f07635157a3503dfdcb2d", @"/NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncLocalFunctions..cshtml")] + public class NoDiagnosticsAreReturned_ForUseOfTagHelpersInAsyncLocalFunctions_ : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #line hidden + #pragma warning disable 0169 + private string __tagHelperStringValueBuffer; + #pragma warning restore 0169 + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner(); + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager + { + get + { + if (__backed__tagHelperScopeManager == null) + { + __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope); + } + return __backed__tagHelperScopeManager; + } + } + private global::Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + + /*MM*/async Task SometMethod() + { + + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "d5d5a28106f24c1bb31f07635157a3503dfdcb2d2978", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + } + + await SometMethod(); + + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591 diff --git a/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/SingleDiagnosticIsReturned_ForMultipleTagHelpersInVoidMethod.cs b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/SingleDiagnosticIsReturned_ForMultipleTagHelpersInVoidMethod.cs new file mode 100644 index 0000000000..bd589eba68 --- /dev/null +++ b/src/Mvc/Mvc.Analyzers/test/TestFiles/TagHelpersInCodeBlocksAnalyzerTest/SingleDiagnosticIsReturned_ForMultipleTagHelpersInVoidMethod.cs @@ -0,0 +1,123 @@ +namespace AspNetCore +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class SingleDiagnosticIsReturned_ForMultipleTagHelpersInVoidMethod : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #line hidden + #pragma warning disable 0169 + private string __tagHelperStringValueBuffer; + #pragma warning restore 0169 + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner(); + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null; + private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager + { + get + { + if (__backed__tagHelperScopeManager == null) + { + __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope); + } + return __backed__tagHelperScopeManager; + } + } + private global::Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + WriteLiteral("\r\n"); + + SometMethod(); + + WriteLiteral("\r\n"); + } + #pragma warning restore 1998 + + /*MM*/void SometMethod() + { + + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "a49ad3383d0802d134e8f9ec401bad4c2f47d14d3250", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "a49ad3383d0802d134e8f9ec401bad4c2f47d14d4821", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + WriteLiteral(" "); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("cache", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "a49ad3383d0802d134e8f9ec401bad4c2f47d14d6392", async() => { + WriteLiteral("\r\n

The current time is "); + Write(DateTime.Now); + + WriteLiteral("

\r\n "); + } + ); + __Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_CacheTagHelper); + BeginWriteTagHelperAttribute(); + __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); + __tagHelperExecutionContext.AddHtmlAttribute("asp-vary-by-user", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized); + await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + if (!__tagHelperExecutionContext.Output.IsContentModified) + { + await __tagHelperExecutionContext.SetOutputContentAsync(); + } + Write(__tagHelperExecutionContext.Output); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + WriteLiteral("\r\n"); + } + + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} +#pragma warning restore 1591