Do not return an top lever parameter analyzer warning for some types (#13496)
* Do not return an top lever parameter analyzer warning for some types Fixes https://github.com/aspnet/AspNetCore/issues/6945
This commit is contained in:
parent
8430a30abc
commit
3c05f3a8af
|
|
@ -47,7 +47,8 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
|
|||
new DiagnosticDescriptor(
|
||||
"MVC1004",
|
||||
"Rename model bound parameter.",
|
||||
"Property on type '{0}' has the same name as parameter '{1}'. This may result in incorrect model binding. Consider renaming the parameter or using a model binding attribute to override the name.",
|
||||
"Property on type '{0}' has the same name as parameter '{1}'. This may result in incorrect model binding. " +
|
||||
"Consider renaming the parameter or the property to avoid conflicts. If the type '{0}' has a custom type converter or custom model binder, you can suppress this message.",
|
||||
"Naming",
|
||||
DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true,
|
||||
|
|
|
|||
|
|
@ -89,12 +89,17 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
|
|||
return false;
|
||||
}
|
||||
|
||||
if (SpecifiesModelType(symbolCache, parameter))
|
||||
if (SpecifiesModelType(in symbolCache, parameter))
|
||||
{
|
||||
// Ignore parameters that specify a model type.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsComplexType(parameter.Type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var parameterName = GetName(symbolCache, parameter);
|
||||
|
||||
var type = parameter.Type;
|
||||
|
|
@ -122,6 +127,26 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
|
|||
return false;
|
||||
}
|
||||
|
||||
private static bool IsComplexType(ITypeSymbol type)
|
||||
{
|
||||
// This analyzer should not apply to simple types. In MVC, a simple type is any type that has a type converter that returns true for TypeConverter.CanConvertFrom(typeof(string)).
|
||||
// Unfortunately there isn't a Roslyn way of determining if a TypeConverter exists for a given symbol or if the converter allows string conversions.
|
||||
// https://github.com/dotnet/corefx/blob/v3.0.0-preview8.19405.3/src/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs#L103-L141
|
||||
// provides a list of types that have built-in converters.
|
||||
// We'll use a simpler heuristic in the analyzer: A type is simple if it's a value type or if it's in the "System.*" namespace hierarchy.
|
||||
|
||||
var @namespace = type.ContainingNamespace?.ToString();
|
||||
if (@namespace != null)
|
||||
{
|
||||
// Things in the System.* namespace hierarchy don't count as complex types. This workarounds
|
||||
// the problem of discovering type converters on types in mscorlib.
|
||||
return @namespace != "System" &&
|
||||
!@namespace.StartsWith("System.", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static string GetName(in SymbolCache symbolCache, ISymbol symbol)
|
||||
{
|
||||
foreach (var attribute in symbol.GetAttributes(symbolCache.IModelNameProvider))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Analyzers.TopLevelParameterNameAnalyzerTestFiles
|
||||
{
|
||||
public class IsProblematicParameter_ReturnsFalse_ForSimpleTypes
|
||||
{
|
||||
public void ActionMethod(DateTime date, DateTime? day, Uri absoluteUri, Version majorRevision, DayOfWeek sunday) { }
|
||||
}
|
||||
}
|
||||
|
|
@ -95,6 +95,30 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
|
|||
Assert.False(result);
|
||||
}
|
||||
|
||||
// Test for https://github.com/aspnet/AspNetCore/issues/6945
|
||||
[Fact]
|
||||
public async Task IsProblematicParameter_ReturnsFalse_ForSimpleTypes()
|
||||
{
|
||||
var testName = nameof(IsProblematicParameter_ReturnsFalse_ForSimpleTypes);
|
||||
var testSource = MvcTestSource.Read(GetType().Name, testName);
|
||||
var project = DiagnosticProject.Create(GetType().Assembly, new[] { testSource.Source });
|
||||
|
||||
var compilation = await project.GetCompilationAsync();
|
||||
|
||||
var modelType = compilation.GetTypeByMetadataName($"Microsoft.AspNetCore.Mvc.Analyzers.TopLevelParameterNameAnalyzerTestFiles.{testName}");
|
||||
var method = (IMethodSymbol)modelType.GetMembers("ActionMethod").First();
|
||||
|
||||
Assert.True(TopLevelParameterNameAnalyzer.SymbolCache.TryCreate(compilation, out var symbolCache));
|
||||
|
||||
Assert.Collection(
|
||||
method.Parameters,
|
||||
p => Assert.False(TopLevelParameterNameAnalyzer.IsProblematicParameter(symbolCache, p)),
|
||||
p => Assert.False(TopLevelParameterNameAnalyzer.IsProblematicParameter(symbolCache, p)),
|
||||
p => Assert.False(TopLevelParameterNameAnalyzer.IsProblematicParameter(symbolCache, p)),
|
||||
p => Assert.False(TopLevelParameterNameAnalyzer.IsProblematicParameter(symbolCache, p)),
|
||||
p => Assert.False(TopLevelParameterNameAnalyzer.IsProblematicParameter(symbolCache, p)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IsProblematicParameter_IgnoresStaticProperties()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue