Merge pull request #7575 from aspnet/release/2.1

Add an analyzer to warn against the use of IHtmlHelper.Partial and IH…
This commit is contained in:
Pranav K 2018-03-29 21:26:17 -07:00 committed by GitHub
commit 4b15ad60b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 944 additions and 81 deletions

View File

@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2020
VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 15.0.26730.03
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
EndProject
@ -104,9 +104,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{44546170-35BF-448F-88F5-4331AE67AEAE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers", "src\Microsoft.AspNetCore.Mvc.Analyzers\Microsoft.AspNetCore.Mvc.Analyzers.csproj", "{29454949-4AE0-4B3B-9157-BFC28B7ECD97}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers.Experimental.Test", "test\Microsoft.AspNetCore.Mvc.Analyzers.Experimental.Test\Microsoft.AspNetCore.Mvc.Analyzers.Experimental.Test.csproj", "{2E6CDE10-8F96-4B75-B0D9-808F6A01B8BD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers.Test", "test\Microsoft.AspNetCore.Mvc.Analyzers.Test\Microsoft.AspNetCore.Mvc.Analyzers.Test.csproj", "{2E6CDE10-8F96-4B75-B0D9-808F6A01B8BD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers", "src\Microsoft.AspNetCore.Mvc.Analyzers\Microsoft.AspNetCore.Mvc.Analyzers.csproj", "{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers.Experimental", "src\Microsoft.AspNetCore.Mvc.Analyzers.Experimental\Microsoft.AspNetCore.Mvc.Analyzers.Experimental.csproj", "{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers.Test", "test\Microsoft.AspNetCore.Mvc.Analyzers.Test\Microsoft.AspNetCore.Mvc.Analyzers.Test.csproj", "{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -494,18 +498,6 @@ Global
{28D4DA20-6E13-47F9-80AE-D6AA7699CC35}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{28D4DA20-6E13-47F9-80AE-D6AA7699CC35}.Release|x86.ActiveCfg = Release|Any CPU
{28D4DA20-6E13-47F9-80AE-D6AA7699CC35}.Release|x86.Build.0 = Release|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Debug|x86.ActiveCfg = Debug|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Debug|x86.Build.0 = Debug|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Release|Any CPU.Build.0 = Release|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Release|x86.ActiveCfg = Release|Any CPU
{29454949-4AE0-4B3B-9157-BFC28B7ECD97}.Release|x86.Build.0 = Release|Any CPU
{2E6CDE10-8F96-4B75-B0D9-808F6A01B8BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E6CDE10-8F96-4B75-B0D9-808F6A01B8BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E6CDE10-8F96-4B75-B0D9-808F6A01B8BD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@ -518,6 +510,42 @@ Global
{2E6CDE10-8F96-4B75-B0D9-808F6A01B8BD}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{2E6CDE10-8F96-4B75-B0D9-808F6A01B8BD}.Release|x86.ActiveCfg = Release|Any CPU
{2E6CDE10-8F96-4B75-B0D9-808F6A01B8BD}.Release|x86.Build.0 = Release|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Debug|x86.ActiveCfg = Debug|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Debug|x86.Build.0 = Debug|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Release|Any CPU.Build.0 = Release|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Release|x86.ActiveCfg = Release|Any CPU
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3}.Release|x86.Build.0 = Release|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Debug|x86.ActiveCfg = Debug|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Debug|x86.Build.0 = Debug|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Release|Any CPU.Build.0 = Release|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Release|x86.ActiveCfg = Release|Any CPU
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754}.Release|x86.Build.0 = Release|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Debug|x86.ActiveCfg = Debug|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Debug|x86.Build.0 = Debug|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Release|Any CPU.Build.0 = Release|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Release|x86.ActiveCfg = Release|Any CPU
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -556,8 +584,10 @@ Global
{CF322BE1-E1FE-4CFD-8FCA-16A14B905D53} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{0AB46520-F441-4E01-B444-08F4D23F8B1B} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{28D4DA20-6E13-47F9-80AE-D6AA7699CC35} = {44546170-35BF-448F-88F5-4331AE67AEAE}
{29454949-4AE0-4B3B-9157-BFC28B7ECD97} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{2E6CDE10-8F96-4B75-B0D9-808F6A01B8BD} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{30862895-C1FA-49F5-B69A-B0F9F2ECD0F3} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{F8FD2D6A-DCD1-4A7B-B599-B728A12A1754} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D003597F-372F-4068-A2F0-353BE3C3B39A}

45
Mvc.sln
View File

@ -1,6 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26831.3000
VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 15.0.26730.03
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
EndProject
@ -153,15 +154,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{FDC66952-A3EA-4074-899E-C29816BF7C1F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorBuildWebSite", "test\WebSites\RazorBuildWebSite\RazorBuildWebSite.csproj", "{BF8A3392-C3D2-4813-855A-E906564600E1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorBuildWebSite", "test\WebSites\RazorBuildWebSite\RazorBuildWebSite.csproj", "{BF8A3392-C3D2-4813-855A-E906564600E1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorBuildWebSite.PrecompiledViews", "test\WebSites\RazorBuildWebSite.PrecompiledViews\RazorBuildWebSite.PrecompiledViews.csproj", "{856D7E25-E033-477D-9ABD-0B50CF428C80}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorBuildWebSite.PrecompiledViews", "test\WebSites\RazorBuildWebSite.PrecompiledViews\RazorBuildWebSite.PrecompiledViews.csproj", "{856D7E25-E033-477D-9ABD-0B50CF428C80}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorBuildWebSite.Views", "test\WebSites\RazorBuildWebSite.Views\RazorBuildWebSite.Views.csproj", "{8916DDCA-EC2A-4193-B9F3-78CAA1A96D5A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorBuildWebSite.Views", "test\WebSites\RazorBuildWebSite.Views\RazorBuildWebSite.Views.csproj", "{8916DDCA-EC2A-4193-B9F3-78CAA1A96D5A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Mvc.Analyzers", "src\Microsoft.AspNetCore.Mvc.Analyzers\Microsoft.AspNetCore.Mvc.Analyzers.csproj", "{87A3E227-C45E-4141-A59F-402908E651FD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers", "src\Microsoft.AspNetCore.Mvc.Analyzers\Microsoft.AspNetCore.Mvc.Analyzers.csproj", "{87A3E227-C45E-4141-A59F-402908E651FD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Mvc.Analyzers.Test", "test\Microsoft.AspNetCore.Mvc.Analyzers.Test\Microsoft.AspNetCore.Mvc.Analyzers.Test.csproj", "{E3E09D2F-1FCF-4396-9B09-5A62CA8CC831}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers.Test", "test\Microsoft.AspNetCore.Mvc.Analyzers.Test\Microsoft.AspNetCore.Mvc.Analyzers.Test.csproj", "{E3E09D2F-1FCF-4396-9B09-5A62CA8CC831}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers.Experimental", "src\Microsoft.AspNetCore.Mvc.Analyzers.Experimental\Microsoft.AspNetCore.Mvc.Analyzers.Experimental.csproj", "{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers.Experimental.Test", "test\Microsoft.AspNetCore.Mvc.Analyzers.Experimental.Test\Microsoft.AspNetCore.Mvc.Analyzers.Experimental.Test.csproj", "{E83D3745-9BCF-40E8-8D34-AFBA604C2439}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -849,6 +854,30 @@ Global
{E3E09D2F-1FCF-4396-9B09-5A62CA8CC831}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E3E09D2F-1FCF-4396-9B09-5A62CA8CC831}.Release|x86.ActiveCfg = Release|Any CPU
{E3E09D2F-1FCF-4396-9B09-5A62CA8CC831}.Release|x86.Build.0 = Release|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Debug|x86.ActiveCfg = Debug|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Debug|x86.Build.0 = Debug|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Release|Any CPU.Build.0 = Release|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Release|x86.ActiveCfg = Release|Any CPU
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61}.Release|x86.Build.0 = Release|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Debug|x86.ActiveCfg = Debug|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Debug|x86.Build.0 = Debug|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Release|Any CPU.Build.0 = Release|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Release|x86.ActiveCfg = Release|Any CPU
{E83D3745-9BCF-40E8-8D34-AFBA604C2439}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -915,6 +944,8 @@ Global
{8916DDCA-EC2A-4193-B9F3-78CAA1A96D5A} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{87A3E227-C45E-4141-A59F-402908E651FD} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{E3E09D2F-1FCF-4396-9B09-5A62CA8CC831} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{CBF23034-2249-4FE5-BD48-5F3CEAC0DF61} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{E83D3745-9BCF-40E8-8D34-AFBA604C2439} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {63D344F6-F86D-40E6-85B9-0AABBE338C4A}

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
public static readonly string ReturnTypeKey = "ReturnType";
public ActionsMustNotBeAsyncVoidAnalyzer()
: base(DiagnosticDescriptors.MVC1003_ActionsMustNotBeAsyncVoid)
: base(DiagnosticDescriptors.MVC7003_ActionsMustNotBeAsyncVoid)
{
}

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
public class ActionsMustNotBeAsyncVoidFixProvider : CodeFixProvider
{
public sealed override ImmutableArray<string> FixableDiagnosticIds =>
ImmutableArray.Create(DiagnosticDescriptors.MVC1003_ActionsMustNotBeAsyncVoid.Id);
ImmutableArray.Create(DiagnosticDescriptors.MVC7003_ActionsMustNotBeAsyncVoid.Id);
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
internal const string MethodNameKey = "MethodName";
public ApiActionsAreAttributeRoutedAnalyzer()
: base(DiagnosticDescriptors.MVC1000_ApiActionsMustBeAttributeRouted)
: base(DiagnosticDescriptors.MVC7000_ApiActionsMustBeAttributeRouted)
{
}

View File

@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
};
public sealed override ImmutableArray<string> FixableDiagnosticIds =>
ImmutableArray.Create(DiagnosticDescriptors.MVC1000_ApiActionsMustBeAttributeRouted.Id);
ImmutableArray.Create(DiagnosticDescriptors.MVC7000_ApiActionsMustBeAttributeRouted.Id);
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
public class ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzer : ApiControllerAnalyzerBase
{
public ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzer()
: base(DiagnosticDescriptors.MVC1001_ApiActionsHaveBadModelStateFilter)
: base(DiagnosticDescriptors.MVC7001_ApiActionsHaveBadModelStateFilter)
{
}

View File

@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
public class ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProvider : CodeFixProvider
{
public sealed override ImmutableArray<string> FixableDiagnosticIds =>
ImmutableArray.Create(DiagnosticDescriptors.MVC1001_ApiActionsHaveBadModelStateFilter.Id);
ImmutableArray.Create(DiagnosticDescriptors.MVC7001_ApiActionsHaveBadModelStateFilter.Id);
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;

View File

@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
public static readonly string ReturnTypeKey = "ReturnType";
public ApiActionsShouldUseActionResultOfTAnalyzer()
: base(DiagnosticDescriptors.MVC1002_ApiActionsShouldReturnActionResultOf)
: base(DiagnosticDescriptors.MVC7002_ApiActionsShouldReturnActionResultOf)
{
}

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
public class ApiActionsShouldUseActionResultOfTCodeFixProvider : CodeFixProvider
{
public sealed override ImmutableArray<string> FixableDiagnosticIds =>
ImmutableArray.Create(DiagnosticDescriptors.MVC1002_ApiActionsShouldReturnActionResultOf.Id);
ImmutableArray.Create(DiagnosticDescriptors.MVC7002_ApiActionsShouldReturnActionResultOf.Id);
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;

View File

@ -0,0 +1,46 @@
// 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 Microsoft.CodeAnalysis;
namespace Microsoft.AspNetCore.Mvc.Analyzers
{
public static class DiagnosticDescriptors
{
public static readonly DiagnosticDescriptor MVC7000_ApiActionsMustBeAttributeRouted =
new DiagnosticDescriptor(
"MVC7000",
"Actions on types annotated with ApiControllerAttribute must be attribute routed.",
"Actions on types annotated with ApiControllerAttribute must be attribute routed.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor MVC7001_ApiActionsHaveBadModelStateFilter =
new DiagnosticDescriptor(
"MVC7001",
"Actions on types annotated with ApiControllerAttribute do not require explicit ModelState validity check.",
"Actions on types annotated with ApiControllerAttribute do not require explicit ModelState validity check.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor MVC7002_ApiActionsShouldReturnActionResultOf =
new DiagnosticDescriptor(
"MVC7002",
"Actions on types annotated with ApiControllerAttribute should return ActionResult<T>.",
"Actions on types annotated with ApiControllerAttribute should return ActionResult<T>.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor MVC7003_ActionsMustNotBeAsyncVoid =
new DiagnosticDescriptor(
"MVC7003",
"Controller actions must not have async void signature.",
"Controller actions must not have async void signature.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
}
}

View File

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>CSharp Analyzers for ASP.NET Core MVC.</Description>
<PackageTags>aspnetcore;aspnetcoremvc</PackageTags>
<VerifyVersion>false</VerifyVersion>
<VersionPrefix>$(ExperimentalVersionPrefix)</VersionPrefix>
<VersionSuffix>$(ExperimentalVersionSuffix)</VersionSuffix>
<PackageVersion>$(ExperimentalPackageVersion)</PackageVersion>
<TargetFramework>netstandard2.0</TargetFramework>
<IncludeBuildOutput>false</IncludeBuildOutput>
<EnableApiCheck>false</EnableApiCheck>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion)" />
</ItemGroup>
<ItemGroup>
<None Include="$(OutputPath)$(AssemblyName).dll" Pack="true" PackagePath="analyzers\dotnet\cs\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,54 @@
// 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;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Microsoft.AspNetCore.Mvc.Analyzers
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class AvoidHtmlPartialAnalyzer : ViewFeatureAnalyzerBase
{
public AvoidHtmlPartialAnalyzer()
: base(DiagnosticDescriptors.MVC1000_HtmlHelperPartialShouldBeAvoided)
{
}
protected override void InitializeWorker(ViewFeaturesAnalyzerContext analyzerContext)
{
analyzerContext.Context.RegisterSyntaxNodeAction(context =>
{
var invocationExpression = (InvocationExpressionSyntax)context.Node;
var symbol = context.SemanticModel.GetSymbolInfo(invocationExpression, context.CancellationToken).Symbol;
if (symbol == null || symbol.Kind != SymbolKind.Method)
{
return;
}
var method = (IMethodSymbol)symbol;
if (!analyzerContext.IsHtmlHelperExtensionMethod(method))
{
return;
}
if (string.Equals(SymbolNames.PartialMethod, method.Name, StringComparison.Ordinal))
{
context.ReportDiagnostic(Diagnostic.Create(
SupportedDiagnostic,
invocationExpression.GetLocation(),
new[] { SymbolNames.PartialMethod }));
}
else if (string.Equals(SymbolNames.RenderPartialMethod, method.Name, StringComparison.Ordinal))
{
context.ReportDiagnostic(Diagnostic.Create(
SupportedDiagnostic,
invocationExpression.GetLocation(),
new[] { SymbolNames.RenderPartialMethod }));
}
}, SyntaxKind.InvocationExpression);
}
}
}

View File

@ -7,38 +7,11 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
{
public static class DiagnosticDescriptors
{
public static readonly DiagnosticDescriptor MVC1000_ApiActionsMustBeAttributeRouted =
public static readonly DiagnosticDescriptor MVC1000_HtmlHelperPartialShouldBeAvoided =
new DiagnosticDescriptor(
"MVC1000",
"Actions on types annotated with ApiControllerAttribute must be attribute routed.",
"Actions on types annotated with ApiControllerAttribute must be attribute routed.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor MVC1001_ApiActionsHaveBadModelStateFilter =
new DiagnosticDescriptor(
"MVC1001",
"Actions on types annotated with ApiControllerAttribute do not require explicit ModelState validity check.",
"Actions on types annotated with ApiControllerAttribute do not require explicit ModelState validity check.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor MVC1002_ApiActionsShouldReturnActionResultOf =
new DiagnosticDescriptor(
"MVC1002",
"Actions on types annotated with ApiControllerAttribute should return ActionResult<T>.",
"Actions on types annotated with ApiControllerAttribute should return ActionResult<T>.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor MVC1003_ActionsMustNotBeAsyncVoid =
new DiagnosticDescriptor(
"MVC2001",
"Controller actions must not have async void signature.",
"Controller actions must not have async void signature.",
"Use of IHtmlHelper.{0} should be avoided.",
"Use of IHtmlHelper.{0} may result in application deadlocks. Consider using <partial> Tag Helper or IHtmlHelper.{0}Async.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);

View File

@ -3,11 +3,6 @@
<Description>CSharp Analyzers for ASP.NET Core MVC.</Description>
<PackageTags>aspnetcore;aspnetcoremvc</PackageTags>
<VerifyVersion>false</VerifyVersion>
<VersionPrefix>$(ExperimentalVersionPrefix)</VersionPrefix>
<VersionSuffix>$(ExperimentalVersionSuffix)</VersionSuffix>
<PackageVersion>$(ExperimentalPackageVersion)</PackageVersion>
<TargetFramework>netstandard2.0</TargetFramework>
<IncludeBuildOutput>false</IncludeBuildOutput>
<EnableApiCheck>false</EnableApiCheck>

View File

@ -0,0 +1,16 @@
// 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.
namespace Microsoft.AspNetCore.Mvc.Analyzers
{
internal static class SymbolNames
{
public const string IHtmlHelperType = "Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper";
public const string HtmlHelperPartialExtensionsType = "Microsoft.AspNetCore.Mvc.Rendering.HtmlHelperPartialExtensions";
public const string PartialMethod = "Partial";
public const string RenderPartialMethod = "RenderPartial";
}
}

View File

@ -0,0 +1,40 @@
// 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.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Microsoft.AspNetCore.Mvc.Analyzers
{
public abstract class ViewFeatureAnalyzerBase : DiagnosticAnalyzer
{
public ViewFeatureAnalyzerBase(DiagnosticDescriptor diagnosticDescriptor)
{
SupportedDiagnostic = diagnosticDescriptor;
SupportedDiagnostics = ImmutableArray.Create(new[] { SupportedDiagnostic });
}
protected DiagnosticDescriptor SupportedDiagnostic { get; }
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }
public sealed override void Initialize(AnalysisContext context)
{
context.RegisterCompilationStartAction(compilationContext =>
{
var analyzerContext = new ViewFeaturesAnalyzerContext(compilationContext);
// Only do work if we can locate IHtmlHelper.
if (analyzerContext.HtmlHelperType == null)
{
return;
}
InitializeWorker(analyzerContext);
});
}
protected abstract void InitializeWorker(ViewFeaturesAnalyzerContext analyzerContext);
}
}

View File

@ -0,0 +1,48 @@
// 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 Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Microsoft.AspNetCore.Mvc.Analyzers
{
public class ViewFeaturesAnalyzerContext
{
#pragma warning disable RS1012 // Start action has no registered actions.
public ViewFeaturesAnalyzerContext(CompilationStartAnalysisContext context)
#pragma warning restore RS1012 // Start action has no registered actions.
{
Context = context;
HtmlHelperType = GetType(SymbolNames.IHtmlHelperType);
HtmlHelperPartialExtensionsType = GetType(SymbolNames.HtmlHelperPartialExtensionsType);
}
public CompilationStartAnalysisContext Context { get; }
public INamedTypeSymbol HtmlHelperType { get; }
public INamedTypeSymbol HtmlHelperPartialExtensionsType { get; }
private INamedTypeSymbol GetType(string name) => Context.Compilation.GetTypeByMetadataName(name);
public bool IsHtmlHelperExtensionMethod(IMethodSymbol method)
{
if (!method.IsExtensionMethod)
{
return false;
}
if (method.ReceiverType != HtmlHelperType)
{
return false;
}
if (method.ContainingType != HtmlHelperPartialExtensionsType)
{
return false;
}
return true;
}
}
}

View File

@ -59,7 +59,7 @@ public class UserViewModel
// Arrange
var expectedDiagnostic = new DiagnosticResult
{
Id = "MVC2001",
Id = "MVC7003",
Message = "Controller actions must not have async void signature.",
Severity = DiagnosticSeverity.Warning,
Locations = new[] { new DiagnosticResultLocation("Test.cs", 7, 18) }
@ -103,7 +103,7 @@ public class HomeController : Controller
// Arrange
var expectedDiagnostic = new DiagnosticResult
{
Id = "MVC2001",
Id = "MVC7003",
Message = "Controller actions must not have async void signature.",
Severity = DiagnosticSeverity.Warning,
Locations = new[] { new DiagnosticResultLocation("Test.cs", 7, 18) }
@ -141,7 +141,7 @@ public class HomeController : Controller
// Arrange
var expectedDiagnostic = new DiagnosticResult
{
Id = "MVC2001",
Id = "MVC7003",
Message = "Controller actions must not have async void signature.",
Severity = DiagnosticSeverity.Warning,
Locations = new[] { new DiagnosticResultLocation("Test.cs", 6, 18) }

View File

@ -204,7 +204,7 @@ public class PetController : ControllerBase
// Arrange
var expectedDiagnostic = new DiagnosticResult
{
Id = "MVC1001",
Id = "MVC7001",
Message = "Actions on types annotated with ApiControllerAttribute do not require explicit ModelState validity check.",
Severity = DiagnosticSeverity.Warning,
Locations = new[] { new DiagnosticResultLocation("Test.cs", 9, 9) }
@ -236,7 +236,7 @@ public class PetController : ControllerBase
// Arrange
var expectedDiagnostic = new DiagnosticResult
{
Id = "MVC1001",
Id = "MVC7001",
Message = "Actions on types annotated with ApiControllerAttribute do not require explicit ModelState validity check.",
Severity = DiagnosticSeverity.Warning,
Locations = new[] { new DiagnosticResultLocation("Test.cs", 13, 9) }
@ -295,7 +295,7 @@ public class PetController : ControllerBase
// Arrange
var expectedDiagnostic = new DiagnosticResult
{
Id = "MVC1001",
Id = "MVC7001",
Message = "Actions on types annotated with ApiControllerAttribute do not require explicit ModelState validity check.",
Severity = DiagnosticSeverity.Warning,
Locations = new[] { new DiagnosticResultLocation("Test.cs", 15, 13) }

View File

@ -130,7 +130,7 @@ public class PetController : Controller
// Arrange
var expectedDiagnostic = new DiagnosticResult
{
Id = "MVC1000",
Id = "MVC7000",
Message = "Actions on types annotated with ApiControllerAttribute must be attribute routed.",
Severity = DiagnosticSeverity.Warning,
Locations = new[] { new DiagnosticResultLocation("Test.cs", 8, 16) }

View File

@ -158,7 +158,7 @@ public class PetController: ControllerBase
// Arrange
var expectedDiagnostic = new DiagnosticResult
{
Id = "MVC1002",
Id = "MVC7002",
Message = "Actions on types annotated with ApiControllerAttribute should return ActionResult<T>.",
Severity = DiagnosticSeverity.Warning,
Locations = new[] { new DiagnosticResultLocation("Test.cs", 9, 12) }
@ -207,7 +207,7 @@ public class PetController: ControllerBase
// Arrange
var expectedDiagnostic = new DiagnosticResult
{
Id = "MVC1002",
Id = "MVC7002",
Message = "Actions on types annotated with ApiControllerAttribute should return ActionResult<T>.",
Severity = DiagnosticSeverity.Warning,
Locations = new[] { new DiagnosticResultLocation("Test.cs", 8, 18) }

View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>
<ItemGroup>
<None Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
<Compile Include="..\Microsoft.AspNetCore.Mvc.Analyzers.Test\Infrastructure\*.cs" Link="Infrastructure\%(FileName)%(Extension)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc\Microsoft.AspNetCore.Mvc.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc.Analyzers.Experimental\Microsoft.AspNetCore.Mvc.Analyzers.Experimental.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,3 @@
{
"shadowCopy": false
}

View File

@ -0,0 +1,202 @@
// 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.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Analyzers
{
public class AvoidHtmlPartialAnalyzerTest : AnalyzerTestBase
{
private static DiagnosticDescriptor DiagnosticDescriptor = DiagnosticDescriptors.MVC1000_HtmlHelperPartialShouldBeAvoided;
protected override DiagnosticAnalyzer DiagnosticAnalyzer { get; } = new AvoidHtmlPartialAnalyzer();
[Fact]
public async Task NoDiagnosticsAreReturned_FoEmptyScenarios()
{
// Arrange
var project = CreateProject(source: string.Empty);
// Act
var result = await GetDiagnosticAsync(project);
// Assert
Assert.Empty(result);
}
[Fact]
public async Task NoDiagnosticsAreReturned_ForNonUseOfHtmlPartial()
{
// Arrange
var project = CreateProjectFromFile();
// Act
var result = await GetDiagnosticAsync(project);
// Assert
Assert.Empty(result);
}
[Fact]
public async Task NoDiagnosticsAreReturned_ForUseOfHtmlPartialAsync()
{
// Arrange
var project = CreateProjectFromFile();
// Act
var result = await GetDiagnosticAsync(project);
// Assert
Assert.Empty(result);
}
[Fact]
public async Task DiagnosticsAreReturned_ForUseOfHtmlPartial()
{
// Arrange
var project = CreateProjectFromFile();
var expectedLocation = DefaultMarkerLocation.Value;
// Act
var result = await GetDiagnosticAsync(project);
// Assert
Assert.Collection(
result,
diagnostic =>
{
Assert.Equal(DiagnosticDescriptor.Id, diagnostic.Id);
Assert.Same(DiagnosticDescriptor, diagnostic.Descriptor);
Assert.DiagnosticLocation(expectedLocation, diagnostic.Location);
});
}
[Fact]
public async Task DiagnosticsAreReturned_ForUseOfHtmlPartial_WithAdditionalParameters()
{
// Arrange
var project = CreateProjectFromFile();
var expectedLocation = DefaultMarkerLocation.Value;
// Act
var result = await GetDiagnosticAsync(project);
// Assert
Assert.Collection(
result,
diagnostic =>
{
Assert.Equal(DiagnosticDescriptor.Id, diagnostic.Id);
Assert.Same(DiagnosticDescriptor, diagnostic.Descriptor);
Assert.DiagnosticLocation(expectedLocation, diagnostic.Location);
});
}
[Fact]
public async Task DiagnosticsAreReturned_ForUseOfHtmlPartial_InSections()
{
// Arrange
var project = CreateProjectFromFile();
var expectedLocation = DefaultMarkerLocation.Value;
// Act
var result = await GetDiagnosticAsync(project);
// Assert
Assert.Collection(
result,
diagnostic =>
{
Assert.Equal(DiagnosticDescriptor.Id, diagnostic.Id);
Assert.Same(DiagnosticDescriptor, diagnostic.Descriptor);
Assert.DiagnosticLocation(expectedLocation, diagnostic.Location);
});
}
[Fact]
public async Task NoDiagnosticsAreReturned_ForUseOfRenderPartialAsync()
{
// Arrange
var project = CreateProjectFromFile();
// Act
var result = await GetDiagnosticAsync(project);
// Assert
Assert.Empty(result);
}
[Fact]
public async Task DiagnosticsAreReturned_ForUseOfRenderPartial()
{
// Arrange
var project = CreateProjectFromFile();
var expectedLocation = DefaultMarkerLocation.Value;
// Act
var result = await GetDiagnosticAsync(project);
// Assert
Assert.Collection(
result,
diagnostic =>
{
Assert.Equal(DiagnosticDescriptor.Id, diagnostic.Id);
Assert.Same(DiagnosticDescriptor, diagnostic.Descriptor);
Assert.DiagnosticLocation(expectedLocation, diagnostic.Location);
});
}
[Fact]
public async Task DiagnosticsAreReturned_ForUseOfRenderPartial_WithAdditionalParameters()
{
// Arrange
var project = CreateProjectFromFile();
var expectedLocation = DefaultMarkerLocation.Value;
// Act
var result = await GetDiagnosticAsync(project);
// Assert
Assert.Collection(
result,
diagnostic =>
{
Assert.Equal(DiagnosticDescriptor.Id, diagnostic.Id);
Assert.Same(DiagnosticDescriptor, diagnostic.Descriptor);
Assert.DiagnosticLocation(expectedLocation, diagnostic.Location);
});
}
[Fact]
public async Task DiagnosticsAreReturned_ForUseOfRenderPartial_InSections()
{
// Arrange
var project = CreateProjectFromFile();
var expectedLocation = DefaultMarkerLocation.Value;
// Act
var result = await GetDiagnosticAsync(project);
// Assert
Assert.Collection(
result,
diagnostic =>
{
Assert.Equal(DiagnosticDescriptor.Id, diagnostic.Id);
Assert.Same(DiagnosticDescriptor, diagnostic.Descriptor);
Assert.DiagnosticLocation(expectedLocation, diagnostic.Location);
});
}
}
}

View File

@ -4,9 +4,12 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Testing;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
@ -27,6 +30,51 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure
protected virtual CodeFixProvider CodeFixProvider { get; }
public IDictionary<string, DiagnosticResultLocation> MarkerLocations { get; } = new Dictionary<string, DiagnosticResultLocation>();
public DiagnosticResultLocation? DefaultMarkerLocation { get; private set; }
protected Project CreateProjectFromFile([CallerMemberName] string fileName = "")
{
var solutionDirectory = TestPathUtilities.GetSolutionRootDirectory("Mvc");
var projectDirectory = Path.Combine(solutionDirectory, "test", GetType().Assembly.GetName().Name);
var filePath = Path.Combine(projectDirectory, "TestFiles", fileName + ".cs");
if (!File.Exists(filePath))
{
throw new FileNotFoundException($"TestFile {fileName} could not be found at {filePath}.", filePath);
}
const string MarkerStart = "/*MM";
const string MarkerEnd = "*/";
var lines = File.ReadAllLines(filePath);
for (var i = 0; i < lines.Length; i++)
{
var line = lines[i];
var markerStartIndex = line.IndexOf(MarkerStart, StringComparison.Ordinal);
if (markerStartIndex != -1)
{
var markerEndIndex = line.IndexOf(MarkerEnd, markerStartIndex, StringComparison.Ordinal);
var markerName = line.Substring(markerStartIndex + 2, markerEndIndex - markerStartIndex - 2);
var resultLocation = new DiagnosticResultLocation(i + 1, markerStartIndex + 1); ;
if (DefaultMarkerLocation == null)
{
DefaultMarkerLocation = resultLocation;
}
MarkerLocations[markerName] = resultLocation;
line = line.Substring(0, markerStartIndex) + line.Substring(markerEndIndex + MarkerEnd.Length);
}
lines[i] = line;
}
var inputSource = string.Join(Environment.NewLine, lines);
return CreateProject(inputSource);
}
protected Project CreateProject(string source)
{
var projectId = ProjectId.CreateNewId(debugName: "TestProject");

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
}
else
{
VerifyDiagnosticLocation(expectedItem, actualItem);
VerifyLocation(expectedItem, actualItem);
}
if (actualItem.Id != expectedItem.Id)
@ -71,9 +71,21 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
}
}
private static void VerifyDiagnosticLocation(DiagnosticResult expected, Diagnostic actual)
private static void VerifyLocation(DiagnosticResult expected, Diagnostic actual)
{
var actualSpan = actual.Location.GetLineSpan();
if (expected.Locations.Length == 0)
{
return;
}
var expectedLocation = expected.Locations[0];
Assert.DiagnosticLocation(expectedLocation, actual.Location);
}
public static void DiagnosticLocation(DiagnosticResultLocation expected, Location actual)
{
var actualSpan = actual.GetLineSpan();
var actualLinePosition = actualSpan.StartLinePosition;
// Only check line position if there is an actual line in the real diagnostic
@ -81,7 +93,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
{
if (actualLinePosition.Line + 1 != expected.Line)
{
throw new DiagnosticAssertException(
throw new DiagnosticLocationAssertException(
expected,
actual,
$"Expected diagnostic to be on line \"{expected.Line}\" was actually on line \"{actualLinePosition.Line + 1}\"");
@ -93,7 +105,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
{
if (actualLinePosition.Character + 1 != expected.Column)
{
throw new DiagnosticAssertException(
throw new DiagnosticLocationAssertException(
expected,
actual,
$"Expected diagnostic to start at column \"{expected.Column}\" was actually on line \"{actualLinePosition.Character + 1}\"");
@ -164,5 +176,19 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
public override string Message { get; }
}
private class DiagnosticLocationAssertException : Xunit.Sdk.EqualException
{
public DiagnosticLocationAssertException(
DiagnosticResultLocation expected,
Location actual,
string message)
: base(expected, actual)
{
Message = message;
}
public override string Message { get; }
}
}
}

View File

@ -11,6 +11,11 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure
/// </summary>
public struct DiagnosticResultLocation
{
public DiagnosticResultLocation(int line, int column)
: this("Test.cs", line, column)
{
}
public DiagnosticResultLocation(string path, int line, int column)
{
if (line < -1)

View File

@ -10,8 +10,8 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc.Analyzers\Microsoft.AspNetCore.Mvc.Analyzers.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc\Microsoft.AspNetCore.Mvc.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc.Analyzers\Microsoft.AspNetCore.Mvc.Analyzers.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
</ItemGroup>

View File

@ -0,0 +1,33 @@
namespace AspNetCore
{
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_ForUseOfHtmlPartial : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(0, 25, true);
Write(/*MM*/Html.Partial("Some-Partial"));
EndContext();
EndContext();
}
#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<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,35 @@
namespace AspNetCore
{
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_ForUseOfHtmlPartial_InSections : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(0, 25, true);
DefineSection("name", async () => {
Write(/*MM*/Html.Partial("Test"));
});
EndContext();
EndContext();
}
#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<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,33 @@
namespace AspNetCore
{
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_ForUseOfHtmlPartial_WithAdditionalParameters : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(0, 25, true);
Write(/*MM*/Html.Partial("Some-Partial", new object()));
EndContext();
EndContext();
}
#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<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,33 @@
namespace AspNetCore
{
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_ForUseOfRenderPartial : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(0, 25, true);
/*MM1*/Html.RenderPartial("Some-Partial");
EndContext();
EndContext();
}
#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<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,35 @@
namespace AspNetCore
{
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_ForUseOfHtmlRenderPartial_InSections : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(0, 25, true);
DefineSection("name", async () => {
/*MM*/Html.RenderPartial("Test");
});
EndContext();
EndContext();
}
#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<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,33 @@
namespace AspNetCore
{
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_ForUseOfRenderPartial_WithAdditionalParameters : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(0, 25, true);
/*MM*/Html.RenderPartial("Some-Partial", new object());
EndContext();
EndContext();
}
#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<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,33 @@
namespace AspNetCore
{
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_ForNonUseOfHtmlPartial : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(0, 25, true);
WriteLiteral("Hello world");
EndContext();
EndContext();
}
#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<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,33 @@
namespace AspNetCore
{
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_ForUseOfHtmlPartialAsync : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(0, 25, true);
await Html.PartialAsync("Some-Partial");
EndContext();
EndContext();
}
#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<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,33 @@
namespace AspNetCore
{
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_ForUseOfRenderPartialAsync : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(0, 25, true);
await Html.RenderPartialAsync("Some-Partial");
EndContext();
EndContext();
}
#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<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591