Move API convention analyzers to Microsoft.AspNetCore.Mvc.Api.Analyzers

Fixes #8153
This commit is contained in:
Pranav K 2018-08-02 11:08:39 -07:00
parent 6d9aa281c5
commit 5a20037965
No known key found for this signature in database
GPG Key ID: 1963DA6D96C3057A
90 changed files with 362 additions and 184 deletions

View File

@ -1,4 +1,5 @@
Microsoft Visual Studio Solution File, Format Version 12.00

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 15.0.26730.03
@ -114,7 +115,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mvc.Analyzers.Test", "test\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Views.TestCommon", "test\Microsoft.AspNetCore.Mvc.Views.TestCommon\Microsoft.AspNetCore.Mvc.Views.TestCommon.csproj", "{0772E545-A674-4165-9469-E3D79D88A4A8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Mvc.Testing", "src\Microsoft.AspNetCore.Mvc.Testing\Microsoft.AspNetCore.Mvc.Testing.csproj", "{92D959F2-66B8-490A-BA33-DA4421EBC948}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Testing", "src\Microsoft.AspNetCore.Mvc.Testing\Microsoft.AspNetCore.Mvc.Testing.csproj", "{92D959F2-66B8-490A-BA33-DA4421EBC948}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Api.Analyzers", "src\Microsoft.AspNetCore.Mvc.Api.Analyzers\Microsoft.AspNetCore.Mvc.Api.Analyzers.csproj", "{1B398182-9EAE-400B-A2BD-EFFAC0168A36}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mvc.Api.Analyzers.Test", "test\Mvc.Api.Analyzers.Test\Mvc.Api.Analyzers.Test.csproj", "{71C626FC-6408-494B-A127-38CB64F71324}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -574,6 +579,30 @@ Global
{92D959F2-66B8-490A-BA33-DA4421EBC948}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{92D959F2-66B8-490A-BA33-DA4421EBC948}.Release|x86.ActiveCfg = Release|Any CPU
{92D959F2-66B8-490A-BA33-DA4421EBC948}.Release|x86.Build.0 = Release|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Debug|x86.ActiveCfg = Debug|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Debug|x86.Build.0 = Debug|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Release|Any CPU.Build.0 = Release|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Release|x86.ActiveCfg = Release|Any CPU
{1B398182-9EAE-400B-A2BD-EFFAC0168A36}.Release|x86.Build.0 = Release|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Debug|Any CPU.Build.0 = Debug|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Debug|x86.ActiveCfg = Debug|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Debug|x86.Build.0 = Debug|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Release|Any CPU.ActiveCfg = Release|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Release|Any CPU.Build.0 = Release|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Release|x86.ActiveCfg = Release|Any CPU
{71C626FC-6408-494B-A127-38CB64F71324}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -618,6 +647,8 @@ Global
{829D9A67-2D07-4CE6-86C0-59F2549B0CFA} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{0772E545-A674-4165-9469-E3D79D88A4A8} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{92D959F2-66B8-490A-BA33-DA4421EBC948} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{1B398182-9EAE-400B-A2BD-EFFAC0168A36} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{71C626FC-6408-494B-A127-38CB64F71324} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D003597F-372F-4068-A2F0-353BE3C3B39A}

15
Mvc.sln
View File

@ -176,6 +176,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicApi", "benchmarkapps\B
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicViews", "benchmarkapps\BasicViews\BasicViews.csproj", "{E89EB74D-C1CE-456F-B42D-CCF1575E0CFB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mvc.Api.Analyzers.Test", "test\Mvc.Api.Analyzers.Test\Mvc.Api.Analyzers.Test.csproj", "{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -924,6 +926,18 @@ Global
{E89EB74D-C1CE-456F-B42D-CCF1575E0CFB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E89EB74D-C1CE-456F-B42D-CCF1575E0CFB}.Release|x86.ActiveCfg = Release|Any CPU
{E89EB74D-C1CE-456F-B42D-CCF1575E0CFB}.Release|x86.Build.0 = Release|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Debug|x86.ActiveCfg = Debug|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Debug|x86.Build.0 = Debug|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Release|Any CPU.Build.0 = Release|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Release|x86.ActiveCfg = Release|Any CPU
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -995,6 +1009,7 @@ Global
{51E3E785-A9D1-4196-BAFE-A17FF4304B89} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{910F023A-88E3-4CB4-8793-AC4005C7B421} = {2859F266-673A-45A2-9E3C-7B39C6DDD38E}
{E89EB74D-C1CE-456F-B42D-CCF1575E0CFB} = {2859F266-673A-45A2-9E3C-7B39C6DDD38E}
{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {63D344F6-F86D-40E6-85B9-0AABBE338C4A}

View File

@ -4,9 +4,8 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.CodeAnalysis
{
internal static class CodeAnalysisExtensions
{

View File

@ -42,43 +42,5 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor MVC1004_ActionReturnsUndocumentedStatusCode =
new DiagnosticDescriptor(
"MVC1004",
"Action returns undeclared status code.",
"Action method returns undeclared status code '{0}'.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor MVC1005_ActionReturnsUndocumentedSuccessResult =
new DiagnosticDescriptor(
"MVC1005",
"Action returns undeclared success result.",
"Action method returns a success result without a corresponding ProducesResponseType.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor MVC1006_ActionDoesNotReturnDocumentedStatusCode =
new DiagnosticDescriptor(
"MVC1006",
"Action documents status code that is not returned.",
"Action method documents status code '{0}' without a corresponding return type.",
"Usage",
DiagnosticSeverity.Info,
isEnabledByDefault: false);
public static readonly DiagnosticDescriptor MVC1007_ApiActionsDoNotRequireExplicitModelValidationCheck =
new DiagnosticDescriptor(
"MVC1007",
"Action methods on ApiController instances do not require explicit model validation check.",
"Action methods on ApiController instances do not require explicit model validation check.",
"Usage",
DiagnosticSeverity.Info,
isEnabledByDefault: true,
customTags: new[] { WellKnownDiagnosticTags.Unnecessary });
}
}

View File

@ -3,7 +3,7 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
internal readonly struct ActualApiResponseMetadata
{

View File

@ -13,7 +13,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Simplification;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
internal sealed class AddResponseTypeAttributeCodeFixAction : CodeAction
{
@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
private static AttributeSyntax CreateProducesResponseTypeAttribute(int statusCode)
{
return SyntaxFactory.Attribute(
SyntaxFactory.ParseName(SymbolNames.ProducesResponseTypeAttribute)
SyntaxFactory.ParseName(ApiSymbolNames.ProducesResponseTypeAttribute)
.WithAdditionalAnnotations(Simplifier.Annotation),
SyntaxFactory.AttributeArgumentList().AddArguments(
SyntaxFactory.AttributeArgument(
@ -118,7 +118,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
private static AttributeSyntax CreateProducesDefaultResponseTypeAttribute()
{
return SyntaxFactory.Attribute(
SyntaxFactory.ParseName(SymbolNames.ProducesDefaultResponseTypeAttribute)
SyntaxFactory.ParseName(ApiSymbolNames.ProducesDefaultResponseTypeAttribute)
.WithAdditionalAnnotations(Simplifier.Annotation));
}

View File

@ -7,15 +7,15 @@ using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ExportCodeFixProvider(LanguageNames.CSharp)]
[Shared]
public class AddResponseTypeAttributeCodeFixProvider : CodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(
DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode.Id,
DiagnosticDescriptors.MVC1005_ActionReturnsUndocumentedSuccessResult.Id);
ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode.Id,
ApiDiagnosticDescriptors.API1001_ActionReturnsUndocumentedSuccessResult.Id);
public sealed override Task RegisterCodeFixesAsync(CodeFixContext context)
{
@ -25,8 +25,8 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
}
var diagnostic = context.Diagnostics[0];
if ((diagnostic.Descriptor.Id != DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode.Id) &&
(diagnostic.Descriptor.Id != DiagnosticDescriptors.MVC1005_ActionReturnsUndocumentedSuccessResult.Id))
if ((diagnostic.Descriptor.Id != ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode.Id) &&
(diagnostic.Descriptor.Id != ApiDiagnosticDescriptors.API1001_ActionReturnsUndocumentedSuccessResult.Id))
{
return Task.CompletedTask;
}

View File

@ -8,13 +8,13 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(
DiagnosticDescriptors.MVC1007_ApiActionsDoNotRequireExplicitModelValidationCheck);
ApiDiagnosticDescriptors.API1003_ApiActionsDoNotRequireExplicitModelValidationCheck);
public override void Initialize(AnalysisContext context)
{
@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
operationAnalysisContext.ReportDiagnostic(
Diagnostic.Create(
DiagnosticDescriptors.MVC1007_ApiActionsDoNotRequireExplicitModelValidationCheck,
ApiDiagnosticDescriptors.API1003_ApiActionsDoNotRequireExplicitModelValidationCheck,
ifStatement.GetLocation(),
additionalLocations: additionalLocations));
}, OperationKind.Conditional);

View File

@ -11,14 +11,14 @@ using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ExportCodeFixProvider(LanguageNames.CSharp)]
[Shared]
public class ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProvider : CodeFixProvider
{
public sealed override ImmutableArray<string> FixableDiagnosticIds =>
ImmutableArray.Create(DiagnosticDescriptors.MVC1007_ApiActionsDoNotRequireExplicitModelValidationCheck.Id);
ImmutableArray.Create(ApiDiagnosticDescriptors.API1003_ApiActionsDoNotRequireExplicitModelValidationCheck.Id);
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
}
var diagnostic = context.Diagnostics[0];
if (diagnostic.Id != DiagnosticDescriptors.MVC1007_ApiActionsDoNotRequireExplicitModelValidationCheck.Id)
if (diagnostic.Id != ApiDiagnosticDescriptors.API1003_ApiActionsDoNotRequireExplicitModelValidationCheck.Id)
{
return Task.CompletedTask;
}

View File

@ -1,6 +1,9 @@
using Microsoft.CodeAnalysis;
// 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
using Microsoft.CodeAnalysis;
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
internal static class ApiControllerFacts
{

View File

@ -4,35 +4,31 @@
using System;
using Microsoft.CodeAnalysis;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
internal readonly struct ApiControllerSymbolCache
{
public ApiControllerSymbolCache(Compilation compilation)
{
ActionResultOfT = compilation.GetTypeByMetadataName(SymbolNames.ActionResultOfT);
ApiConventionMethodAttribute = compilation.GetTypeByMetadataName(SymbolNames.ApiConventionMethodAttribute);
ApiConventionNameMatchAttribute = compilation.GetTypeByMetadataName(SymbolNames.ApiConventionNameMatchAttribute);
ApiConventionTypeAttribute = compilation.GetTypeByMetadataName(SymbolNames.ApiConventionTypeAttribute);
ApiConventionTypeMatchAttribute = compilation.GetTypeByMetadataName(SymbolNames.ApiConventionTypeMatchAttribute);
ControllerAttribute = compilation.GetTypeByMetadataName(SymbolNames.ControllerAttribute);
DefaultStatusCodeAttribute = compilation.GetTypeByMetadataName(SymbolNames.DefaultStatusCodeAttribute);
IActionResult = compilation.GetTypeByMetadataName(SymbolNames.IActionResult);
IApiBehaviorMetadata = compilation.GetTypeByMetadataName(SymbolNames.IApiBehaviorMetadata);
IConvertToActionResult = compilation.GetTypeByMetadataName(SymbolNames.IConvertToActionResult);
ModelStateDictionary = compilation.GetTypeByMetadataName(SymbolNames.ModelStateDictionary);
NonActionAttribute = compilation.GetTypeByMetadataName(SymbolNames.NonActionAttribute);
NonControllerAttribute = compilation.GetTypeByMetadataName(SymbolNames.NonControllerAttribute);
ProducesDefaultResponseTypeAttribute = compilation.GetTypeByMetadataName(SymbolNames.ProducesDefaultResponseTypeAttribute);
ProducesResponseTypeAttribute = compilation.GetTypeByMetadataName(SymbolNames.ProducesResponseTypeAttribute);
ApiConventionMethodAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.ApiConventionMethodAttribute);
ApiConventionNameMatchAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.ApiConventionNameMatchAttribute);
ApiConventionTypeAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.ApiConventionTypeAttribute);
ApiConventionTypeMatchAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.ApiConventionTypeMatchAttribute);
ControllerAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.ControllerAttribute);
DefaultStatusCodeAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.DefaultStatusCodeAttribute);
IActionResult = compilation.GetTypeByMetadataName(ApiSymbolNames.IActionResult);
IApiBehaviorMetadata = compilation.GetTypeByMetadataName(ApiSymbolNames.IApiBehaviorMetadata);
ModelStateDictionary = compilation.GetTypeByMetadataName(ApiSymbolNames.ModelStateDictionary);
NonActionAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.NonActionAttribute);
NonControllerAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.NonControllerAttribute);
ProducesDefaultResponseTypeAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.ProducesDefaultResponseTypeAttribute);
ProducesResponseTypeAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.ProducesResponseTypeAttribute);
var disposable = compilation.GetSpecialType(SpecialType.System_IDisposable);
var members = disposable.GetMembers(nameof(IDisposable.Dispose));
IDisposableDispose = members.Length == 1 ? (IMethodSymbol)members[0] : null;
}
public INamedTypeSymbol ActionResultOfT { get; }
public INamedTypeSymbol ApiConventionMethodAttribute { get; }
public INamedTypeSymbol ApiConventionNameMatchAttribute { get; }
@ -49,8 +45,6 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
public INamedTypeSymbol IApiBehaviorMetadata { get; }
public INamedTypeSymbol IConvertToActionResult { get; }
public IMethodSymbol IDisposableDispose { get; }
public ITypeSymbol ModelStateDictionary { get; }

View File

@ -8,15 +8,15 @@ using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class ApiConventionAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(
DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode,
DiagnosticDescriptors.MVC1005_ActionReturnsUndocumentedSuccessResult,
DiagnosticDescriptors.MVC1006_ActionDoesNotReturnDocumentedStatusCode);
ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode,
ApiDiagnosticDescriptors.API1001_ActionReturnsUndocumentedSuccessResult,
ApiDiagnosticDescriptors.API1002_ActionDoesNotReturnDocumentedStatusCode);
public override void Initialize(AnalysisContext context)
{
@ -64,13 +64,13 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
if (actualMetadata.IsDefaultResponse)
{
syntaxNodeContext.ReportDiagnostic(Diagnostic.Create(
DiagnosticDescriptors.MVC1005_ActionReturnsUndocumentedSuccessResult,
ApiDiagnosticDescriptors.API1001_ActionReturnsUndocumentedSuccessResult,
location));
}
else
{
syntaxNodeContext.ReportDiagnostic(Diagnostic.Create(
DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode,
ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode,
location,
actualMetadata.StatusCode));
}
@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
if (!Contains(actualResponseMetadata, declaredMetadata))
{
syntaxNodeContext.ReportDiagnostic(Diagnostic.Create(
DiagnosticDescriptors.MVC1006_ActionDoesNotReturnDocumentedStatusCode,
ApiDiagnosticDescriptors.API1002_ActionDoesNotReturnDocumentedStatusCode,
methodSyntax.Identifier.GetLocation(),
declaredMetadata.StatusCode));
}

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;
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
internal static class ApiDiagnosticDescriptors
{
public static readonly DiagnosticDescriptor API1000_ActionReturnsUndocumentedStatusCode =
new DiagnosticDescriptor(
"API1000",
"Action returns undeclared status code.",
"Action method returns undeclared status code '{0}'.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor API1001_ActionReturnsUndocumentedSuccessResult =
new DiagnosticDescriptor(
"API1001",
"Action returns undeclared success result.",
"Action method returns a success result without a corresponding ProducesResponseType.",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor API1002_ActionDoesNotReturnDocumentedStatusCode =
new DiagnosticDescriptor(
"API1002",
"Action documents status code that is not returned.",
"Action method documents status code '{0}' without a corresponding return type.",
"Usage",
DiagnosticSeverity.Info,
isEnabledByDefault: false);
public static readonly DiagnosticDescriptor API1003_ApiActionsDoNotRequireExplicitModelValidationCheck =
new DiagnosticDescriptor(
"API1003",
"Action methods on ApiController instances do not require explicit model validation check.",
"Action methods on ApiController instances do not require explicit model validation check.",
"Usage",
DiagnosticSeverity.Info,
isEnabledByDefault: true,
customTags: new[] { WellKnownDiagnosticTags.Unnecessary });
}
}

View File

@ -0,0 +1,36 @@
// 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.Api.Analyzers
{
internal static class ApiSymbolNames
{
public const string AllowAnonymousAttribute = "Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute";
public const string ApiConventionMethodAttribute = "Microsoft.AspNetCore.Mvc.ApiConventionMethodAttribute";
public const string ApiConventionNameMatchAttribute = "Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute";
public const string ApiConventionTypeMatchAttribute = "Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute";
public const string ApiConventionTypeAttribute = "Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute";
public const string ControllerAttribute = "Microsoft.AspNetCore.Mvc.ControllerAttribute";
public const string DefaultStatusCodeAttribute = "Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute";
public const string IApiBehaviorMetadata = "Microsoft.AspNetCore.Mvc.Internal.IApiBehaviorMetadata";
public const string IActionResult = "Microsoft.AspNetCore.Mvc.IActionResult";
public const string ModelStateDictionary = "Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary";
public const string NonActionAttribute = "Microsoft.AspNetCore.Mvc.NonActionAttribute";
public const string NonControllerAttribute = "Microsoft.AspNetCore.Mvc.NonControllerAttribute";
public const string ProducesDefaultResponseTypeAttribute = "Microsoft.AspNetCore.Mvc.ProducesDefaultResponseTypeAttribute";
public const string ProducesResponseTypeAttribute = "Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute";
}
}

View File

@ -4,7 +4,7 @@
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
internal readonly struct DeclaredApiResponseMetadata
{

View File

@ -0,0 +1,50 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>CSharp Analyzers for ASP.NET Core MVC.</Description>
<PackageTags>aspnetcore;aspnetcoremvc</PackageTags>
<TargetFramework>netstandard1.3</TargetFramework>
<IncludeBuildOutput>false</IncludeBuildOutput>
<EnableApiCheck>false</EnableApiCheck>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<NuspecFile>$(MSBuildProjectName).nuspec</NuspecFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Microsoft.AspNetCore.Mvc.Analyzers\CodeAnalysisExtensions.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion)" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<SignedPackageFile Include="analyzers/dotnet/cs/$(TargetFileName)" Certificate="$(AssemblySigningCertName)" />
</ItemGroup>
<Target Name="PopulateNuspec" BeforeTargets="GenerateNuspec" DependsOnTargets="Build">
<PropertyGroup>
<!-- Make sure we create a symbols.nupkg. -->
<IncludeSymbols>true</IncludeSymbols>
<NuspecProperties>
id=$(PackageId);
version=$(PackageVersion);
authors=$(Authors);
description=$(Description);
tags=$(PackageTags.Replace(';', ' '));
licenseUrl=$(PackageLicenseUrl);
projectUrl=$(PackageProjectUrl);
iconUrl=$(PackageIconUrl);
repositoryUrl=$(RepositoryUrl);
repositoryCommit=$(RepositoryCommit);
copyright=$(Copyright);
OutputBinary=$(OutputPath)$(AssemblyName).dll;
OutputSymbol=$(OutputPath)$(AssemblyName).pdb;
</NuspecProperties>
</PropertyGroup>
</Target>
</Project>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>$id$</id>
<version>$version$</version>
<authors>$authors$</authors>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<licenseUrl>$licenseUrl$</licenseUrl>
<projectUrl>$projectUrl$</projectUrl>
<iconUrl>$iconUrl$</iconUrl>
<description>$description$</description>
<copyright>$copyright$</copyright>
<tags>$tags$</tags>
<repository type="git" url="$repositoryUrl$" commit="$repositoryCommit$" />
<dependencies>
<group targetFramework=".NETStandard1.3" />
</dependencies>
</metadata>
<files>
<file src="$OutputBinary$" target="analyzers\dotnet\cs\" />
<file src="$OutputSymbol$" target="analyzers\dotnet\cs\" />
</files>
</package>

View File

@ -5,7 +5,7 @@ using System;
using System.Diagnostics;
using Microsoft.CodeAnalysis;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
internal static class MvcFacts
{

View File

@ -0,0 +1,6 @@
// 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.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Mvc.Api.Analyzers.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

View File

@ -5,7 +5,7 @@ using System;
using System.Linq;
using Microsoft.CodeAnalysis;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
internal static class SymbolApiConventionMatcher
{

View File

@ -9,7 +9,7 @@ using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
internal static class SymbolApiResponseMetadataProvider
{

View File

@ -4,7 +4,6 @@
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Xunit;

View File

@ -4,7 +4,6 @@
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Xunit;

View File

@ -5,7 +5,6 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Xunit;

View File

@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure
namespace Microsoft.AspNetCore.Mvc
{
public class MvcDiagnosticAnalyzerRunner : DiagnosticAnalyzerRunner
{

View File

@ -5,7 +5,7 @@ using System.IO;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Testing;
namespace Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure
namespace Microsoft.AspNetCore.Mvc
{
public static class MvcTestSource
{

View File

@ -1,15 +1,13 @@
// 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 System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class AddResponseTypeAttributeCodeFixProviderIntegrationTest
{

View File

@ -4,10 +4,9 @@
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
{
@ -65,7 +64,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
private async Task RunTest([CallerMemberName] string testMethod = "")
{
// Arrange
var descriptor = DiagnosticDescriptors.MVC1007_ApiActionsDoNotRequireExplicitModelValidationCheck;
var descriptor = ApiDiagnosticDescriptors.API1003_ApiActionsDoNotRequireExplicitModelValidationCheck;
var testSource = MvcTestSource.Read(GetType().Name, testMethod);
var expectedLocation = testSource.DefaultMarkerLocation;

View File

@ -4,11 +4,10 @@
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest
{

View File

@ -4,11 +4,10 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class ApiControllerFactsTest
{

View File

@ -5,11 +5,10 @@ using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class ApiConventionAnalyzerIntegrationTest
{
@ -41,55 +40,55 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
[Fact]
public Task DiagnosticsAreReturned_IfMethodWithProducesResponseTypeAttribute_ReturnsUndocumentedStatusCode()
=> RunTest(DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode, 404);
=> RunTest(ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode, 404);
[Fact]
public Task DiagnosticsAreReturned_IfAsyncMethodWithProducesResponseTypeAttribute_ReturnsUndocumentedStatusCode()
=> RunTest(DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode, 404);
=> RunTest(ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode, 404);
[Fact]
public Task DiagnosticsAreReturned_IfAsyncMethodReturningValueTaskWithProducesResponseTypeAttribute_ReturnsUndocumentedStatusCode()
=> RunTest(DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode, 200);
=> RunTest(ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode, 200);
[Fact]
public Task DiagnosticsAreReturned_ForActionResultOfTReturningMethodWithoutAnyAttributes()
=> RunTest(DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode, 404);
=> RunTest(ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode, 404);
[Fact]
public Task DiagnosticsAreReturned_ForActionResultOfTReturningMethodWithoutSomeAttributes()
=> RunTest(DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode, 422);
=> RunTest(ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode, 422);
[Fact]
public Task DiagnosticsAreReturned_IfMethodWithConvention_ReturnsUndocumentedStatusCode()
=> RunTest(DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode, 400);
=> RunTest(ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode, 400);
[Fact]
public Task DiagnosticsAreReturned_IfMethodWithApiConventionMethod_ReturnsUndocumentedStatusCode()
=> RunTest(DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode, 202);
=> RunTest(ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode, 202);
[Fact]
public Task DiagnosticsAreReturned_IfMethodWithAttributeReturnsValue_WithoutDocumentation()
=> RunTest(DiagnosticDescriptors.MVC1005_ActionReturnsUndocumentedSuccessResult);
=> RunTest(ApiDiagnosticDescriptors.API1001_ActionReturnsUndocumentedSuccessResult);
[Fact]
public Task DiagnosticsAreReturned_IfMethodWithAttributeAsynchronouslyReturnsValue_WithoutDocumentation()
=> RunTest(DiagnosticDescriptors.MVC1005_ActionReturnsUndocumentedSuccessResult);
=> RunTest(ApiDiagnosticDescriptors.API1001_ActionReturnsUndocumentedSuccessResult);
[Fact]
public Task DiagnosticsAreReturned_IfMethodWithAttribute_ReturnsDerivedType()
=> RunTest(DiagnosticDescriptors.MVC1005_ActionReturnsUndocumentedSuccessResult);
=> RunTest(ApiDiagnosticDescriptors.API1001_ActionReturnsUndocumentedSuccessResult);
[Fact]
public Task DiagnosticsAreReturned_IfMethodWithProducesResponseTypeAttribute_DoesNotReturnDocumentedStatusCode()
=> RunTest(DiagnosticDescriptors.MVC1006_ActionDoesNotReturnDocumentedStatusCode, 400);
=> RunTest(ApiDiagnosticDescriptors.API1002_ActionDoesNotReturnDocumentedStatusCode, 400);
[Fact]
public Task DiagnosticsAreReturned_IfMethodWithConvention_DoesNotReturnDocumentedStatusCode()
=> RunTest(DiagnosticDescriptors.MVC1006_ActionDoesNotReturnDocumentedStatusCode, 404);
=> RunTest(ApiDiagnosticDescriptors.API1002_ActionDoesNotReturnDocumentedStatusCode, 404);
[Fact]
public Task DiagnosticsAreReturned_IfMethodWithProducesResponseTypeAttribute_DoesNotDocumentSuccessStatusCode()
=> RunTest(DiagnosticDescriptors.MVC1006_ActionDoesNotReturnDocumentedStatusCode, 200);
=> RunTest(ApiDiagnosticDescriptors.API1002_ActionDoesNotReturnDocumentedStatusCode, 200);
private async Task RunNoDiagnosticsAreReturned([CallerMemberName] string testMethod = "")
{
@ -143,7 +142,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
// 10006 is disabled by default. Explicitly enable it so we can correctly validate no diagnostics
// are returned scenarios.
var specificDiagnosticOptions = compilationOptions.SpecificDiagnosticOptions.Add(
DiagnosticDescriptors.MVC1006_ActionDoesNotReturnDocumentedStatusCode.Id,
ApiDiagnosticDescriptors.API1002_ActionDoesNotReturnDocumentedStatusCode.Id,
ReportDiagnostic.Info);
return compilationOptions.WithSpecificDiagnosticOptions(specificDiagnosticOptions);

View File

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
<RootNamespace>Microsoft.AspNetCore.Mvc.Api.Analyzers</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Mvc.Analyzers.Test\Infrastructure\MvcDiagnosticAnalyzerRunner.cs" Link="Infrastructure\MvcDiagnosticAnalyzerRunner.cs" />
<Compile Include="..\Mvc.Analyzers.Test\Infrastructure\MvcTestSource.cs" Link="Infrastructure\MvcTestSource.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc\Microsoft.AspNetCore.Mvc.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc.Api.Analyzers\Microsoft.AspNetCore.Mvc.Api.Analyzers.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Analyzer.Testing" Version="$(MicrosoftAspNetCoreAnalyzerTestingPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion)" />
</ItemGroup>
</Project>

View File

@ -5,11 +5,10 @@ using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class MvcFactsTest
{

View File

@ -5,12 +5,11 @@ using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Xunit;
using static Microsoft.AspNetCore.Mvc.Analyzers.SymbolApiConventionMatcher;
using static Microsoft.AspNetCore.Mvc.Api.Analyzers.SymbolApiConventionMatcher;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class SymbolApiConventionMatcherTest
{

View File

@ -6,12 +6,11 @@ using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Analyzer.Testing;
using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class SymbolApiResponseMetadataProviderTest
{
@ -395,7 +394,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
var source = @"
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class InspectReturnExpression_ReturnsNull_IfReturnExpressionCannotBeFound : ControllerBase

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers._INPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._INPUT_
{
[ApiController]
[Route("[controller]/[action]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers._OUTPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._OUTPUT_
{
[ApiController]
[Route("[controller]/[action]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers._INPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._INPUT_
{
[ApiController]
[Route("[controller]/[action]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers._OUTPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._OUTPUT_
{
[ApiController]
[Route("[controller]/[action]")]

View File

@ -2,7 +2,7 @@
[assembly: ApiConventionType(typeof(DefaultApiConventions))]
namespace Microsoft.AspNetCore.Mvc.Analyzers._INPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._INPUT_
{
[ApiController]
[Route("[controller]/[action]")]

View File

@ -2,7 +2,7 @@
[assembly: ApiConventionType(typeof(DefaultApiConventions))]
namespace Microsoft.AspNetCore.Mvc.Analyzers._OUTPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._OUTPUT_
{
[ApiController]
[Route("[controller]/[action]")]

View File

@ -2,7 +2,7 @@
[assembly: ApiConventionType(typeof(DefaultApiConventions))]
namespace Microsoft.AspNetCore.Mvc.Analyzers._INPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._INPUT_
{
[ApiController]
[Route("[controller]/[action]")]

View File

@ -2,7 +2,7 @@
[assembly: ApiConventionType(typeof(DefaultApiConventions))]
namespace Microsoft.AspNetCore.Mvc.Analyzers._OUTPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._OUTPUT_
{
[ApiController]
[Route("[controller]/[action]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
{
[ApiController]
public class NoDiagnosticsAreReturned_ForApiActionsWithoutModelStateChecks : ControllerBase

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
{
public class NoDiagnosticsAreReturned_ForNonApiController : ControllerBase
{

View File

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckAnalyzerIntegrationTest
{
public class Home : PageModel
{

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._INPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._INPUT_
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._OUTPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._OUTPUT_
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._INPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._INPUT_
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._OUTPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._OUTPUT_
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._INPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._INPUT_
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._OUTPUT_
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers.TestFiles.ApiActionsDoNotRequireExplicitModelValidationCheckCodeFixProviderTest._OUTPUT_
{
[ApiController]
[Route("/api/[controller]")]

View File

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class ApiConventionAnalyzerTest_IndexModel : PageModel
{

View File

@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc;
[assembly: ApiConventionType(typeof(DefaultApiConventions))]
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_ForActionResultOfTReturningMethodWithoutAnyAttributes : ControllerBase

View File

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_ForActionResultOfTReturningMethodWithoutSomeAttributes : ControllerBase

View File

@ -1,11 +1,11 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Analyzers;
using Microsoft.AspNetCore.Mvc.Api.Analyzers;
[assembly: ApiConventionType(typeof(DiagnosticsAreReturned_ForControllerWithCustomConvention))]
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_ForControllerWithCustomConventionController : ControllerBase

View File

@ -1,7 +1,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfAsyncMethodReturningValueTaskWithProducesResponseTypeAttribute_ReturnsUndocumentedStatusCode : ControllerBase

View File

@ -1,7 +1,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfAsyncMethodWithProducesResponseTypeAttribute_ReturnsUndocumentedStatusCode : ControllerBase

View File

@ -2,7 +2,7 @@
[assembly: ApiConventionType(typeof(DefaultApiConventions))]
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfMethodWithApiConventionMethod_ReturnsUndocumentedStatusCode : ControllerBase

View File

@ -1,6 +1,6 @@
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfMethodWithAttributeAsynchronouslyReturnsValue_WithoutDocumentation : ControllerBase

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfMethodWithAttributeReturnsValue_WithoutDocumentation : ControllerBase

View File

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfMethodWithAttribute_ReturnsDerivedType : ControllerBase

View File

@ -2,7 +2,7 @@
[assembly: ApiConventionType(typeof(DefaultApiConventions))]
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfMethodWithConvention_DoesNotReturnDocumentedStatusCode : ControllerBase

View File

@ -1,9 +1,9 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Analyzers;
using Microsoft.AspNetCore.Mvc.Api.Analyzers;
[assembly: ApiConventionType(typeof(DiagnosticsAreReturned_IfMethodWithConvention_ReturnsUndocumentedStatusCodeConvention))]
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfMethodWithConvention_ReturnsUndocumentedStatusCode : ControllerBase

View File

@ -1,6 +1,6 @@
using System;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfMethodWithProducesResponseTypeAttribute_DoesNotDocumentSuccessStatusCode : ControllerBase

View File

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfMethodWithProducesResponseTypeAttribute_DoesNotReturnDocumentedStatusCode : ControllerBase

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class DiagnosticsAreReturned_IfMethodWithProducesResponseTypeAttribute_ReturnsUndocumentedStatusCode : ControllerBase

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class NoDiagnosticsAreReturned_ForApiController_IfStatusCodesCannotBeInferred : ControllerBase

View File

@ -2,7 +2,7 @@
[assembly: ApiConventionType(typeof(DefaultApiConventions))]
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class NoDiagnosticsAreReturned_ForApiController_WithAllDocumentedStatusCodes : ControllerBase

View File

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class NoDiagnosticsAreReturned_ForNonApiController : Controller
{

View File

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class Home : PageModel
{

View File

@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc;
[assembly: ApiConventionType(typeof(DefaultApiConventions))]
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class NoDiagnosticsAreReturned_ForReturnStatementsInLambdas : ControllerBase

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[ApiController]
public class NoDiagnosticsAreReturned_ForReturnStatementsInLocalFunctions : ControllerBase

View File

@ -1,6 +1,6 @@
using System;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public abstract class TestIsControllerActionBase : ControllerBase
{

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public interface ITestController { }

View File

@ -1,7 +1,7 @@
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class Base { }

View File

@ -2,7 +2,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Infrastructure;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
[DefaultStatusCode(StatusCodes.Status412PreconditionFailed)]
public class TestActionResultUsingStatusCodesConstants { }

View File

@ -5,7 +5,7 @@ using System;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Formatters;
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class GetResponseMetadata_ControllerWithoutConvention : ControllerBase
{

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class InspectReturnExpression_ReturnsDefaultResponseMetadata_IfReturnedTypeIsNotActionResult : ControllerBase
{

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNetCore.Mvc.Analyzers
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
{
public class InspectReturnExpression_ReturnsStatusCodeFromDefaultStatusCodeAttributeOnActionResult : ControllerBase
{