提交 1fd082e1 编写于 作者: C CyrusNajmabadi

Do not offer to use an explicit type for 'var' when it's an anonymous type.

上级 bf475922
......@@ -238,6 +238,63 @@ void Method()
}", options: ExplicitTypeEverywhere());
}
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitType)]
public async Task NotOnForEachVarWithAnonymousType()
{
await TestMissingAsync(
@"using System;
using System.Linq;
class Program
{
void Method()
{
var values = Enumerable.Range(1, 5).Select(i => new { Value = i });
foreach ([|var|] value in values)
{
Console.WriteLine(value.Value);
}
}
}", options: ExplicitTypeEverywhere());
}
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitType)]
public async Task OnForEachVarWithExplicitType()
{
await TestAsync(
@"using System;
using System.Linq;
class Program
{
void Method()
{
var values = Enumerable.Range(1, 5);
foreach ([|var|] value in values)
{
Console.WriteLine(value.Value);
}
}
}",
@"using System;
using System.Linq;
class Program
{
void Method()
{
var values = Enumerable.Range(1, 5);
foreach (int value in values)
{
Console.WriteLine(value.Value);
}
}
}", options: ExplicitTypeEverywhere());
}
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitType)]
public async Task NotOnAnonymousType()
{
......
......@@ -75,7 +75,7 @@ private void Initialize(SyntaxNode declaration, SemanticModel semanticModel, Opt
private bool IsTypeApparentInDeclaration(VariableDeclarationSyntax variableDeclaration, SemanticModel semanticModel, TypeStylePreference stylePreferences, CancellationToken cancellationToken)
{
var initializer = variableDeclaration.Variables.Single().Initializer;
var initializerExpression = GetInitializerExpression(initializer);
var initializerExpression = GetInitializerExpression(initializer.Value);
var declaredTypeSymbol = semanticModel.GetTypeInfo(variableDeclaration.Type, cancellationToken).Type;
return TypeStyleHelper.IsTypeApparentInAssignmentExpression(stylePreferences, initializerExpression, semanticModel,cancellationToken, declaredTypeSymbol);
}
......
......@@ -58,12 +58,12 @@ public override void Initialize(AnalysisContext context)
protected abstract bool IsStylePreferred(SemanticModel semanticModel, OptionSet optionSet, State state, CancellationToken cancellationToken);
protected abstract bool TryAnalyzeVariableDeclaration(TypeSyntax typeName, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken, out TextSpan issueSpan);
protected abstract bool AssignmentSupportsStylePreference(SyntaxToken identifier, TypeSyntax typeName, EqualsValueClauseSyntax initializer, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken);
protected abstract bool AssignmentSupportsStylePreference(SyntaxToken identifier, TypeSyntax typeName, ExpressionSyntax initializer, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken);
protected static ExpressionSyntax GetInitializerExpression(EqualsValueClauseSyntax initializer) =>
initializer.Value is CheckedExpressionSyntax
? ((CheckedExpressionSyntax)initializer.Value).Expression.WalkDownParentheses()
: initializer.Value.WalkDownParentheses();
protected static ExpressionSyntax GetInitializerExpression(ExpressionSyntax initializer) =>
initializer is CheckedExpressionSyntax
? ((CheckedExpressionSyntax)initializer).Expression.WalkDownParentheses()
: initializer.WalkDownParentheses();
private void HandleVariableDeclaration(SyntaxNodeAnalysisContext context)
{
......
......@@ -64,12 +64,26 @@ protected override bool TryAnalyzeVariableDeclaration(TypeSyntax typeName, Seman
return false;
}
var isForeachDecl = typeName.Parent.IsKind(SyntaxKind.ForEachStatement);
if (typeName.Parent.IsKind(SyntaxKind.VariableDeclaration) &&
typeName.Parent.Parent.IsKind(SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement, SyntaxKind.UsingStatement))
{
// check assignment for variable declarations.
var variable = ((VariableDeclarationSyntax)typeName.Parent).Variables.First();
if (!AssignmentSupportsStylePreference(variable.Identifier, typeName, variable.Initializer, semanticModel, optionSet, cancellationToken))
if (!AssignmentSupportsStylePreference(
variable.Identifier, typeName, variable.Initializer.Value,
semanticModel, optionSet, cancellationToken))
{
return false;
}
}
else if (typeName.Parent.IsKind(SyntaxKind.ForEachStatement))
{
var foreachStatement = (ForEachStatementSyntax)typeName.Parent;
if (!AssignmentSupportsStylePreference(
foreachStatement.Identifier, typeName, foreachStatement.Expression,
semanticModel, optionSet, cancellationToken))
{
return false;
}
......@@ -86,7 +100,13 @@ protected override bool TryAnalyzeVariableDeclaration(TypeSyntax typeName, Seman
/// false, if explicit typing cannot be used.
/// true, otherwise.
/// </returns>
protected override bool AssignmentSupportsStylePreference(SyntaxToken identifier, TypeSyntax typeName, EqualsValueClauseSyntax initializer, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken)
protected override bool AssignmentSupportsStylePreference(
SyntaxToken identifier,
TypeSyntax typeName,
ExpressionSyntax initializer,
SemanticModel semanticModel,
OptionSet optionSet,
CancellationToken cancellationToken)
{
// is or contains an anonymous type
// cases :
......@@ -99,7 +119,7 @@ protected override bool AssignmentSupportsStylePreference(SyntaxToken identifier
}
// cannot find type if initializer resolves to an ErrorTypeSymbol
var initializerTypeInfo = semanticModel.GetTypeInfo(initializer.Value, cancellationToken);
var initializerTypeInfo = semanticModel.GetTypeInfo(initializer, cancellationToken);
return !initializerTypeInfo.Type.IsErrorType();
}
}
......
......@@ -87,7 +87,9 @@ protected override bool TryAnalyzeVariableDeclaration(TypeSyntax typeName, Seman
}
var variable = variableDeclaration.Variables.Single();
if (AssignmentSupportsStylePreference(variable.Identifier, typeName, variable.Initializer, semanticModel, optionSet, cancellationToken))
if (AssignmentSupportsStylePreference(
variable.Identifier, typeName, variable.Initializer.Value,
semanticModel, optionSet, cancellationToken))
{
issueSpan = candidateIssueSpan;
return true;
......@@ -110,7 +112,13 @@ protected override bool TryAnalyzeVariableDeclaration(TypeSyntax typeName, Seman
/// false, if implicit typing cannot be used.
/// true, otherwise.
/// </returns>
protected override bool AssignmentSupportsStylePreference(SyntaxToken identifier, TypeSyntax typeName, EqualsValueClauseSyntax initializer, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken)
protected override bool AssignmentSupportsStylePreference(
SyntaxToken identifier,
TypeSyntax typeName,
ExpressionSyntax initializer,
SemanticModel semanticModel,
OptionSet optionSet,
CancellationToken cancellationToken)
{
var expression = GetInitializerExpression(initializer);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册