提交 d78715f5 编写于 作者: A AlekseyTs

Rationalize behavior of GetSymbolInfo/GetTypeInfo/ClassifyConversion for...

Rationalize behavior of GetSymbolInfo/GetTypeInfo/ClassifyConversion for DeclarationExpressionSyntax

Since DeclarationExpressionSyntax represents a declaration, all these APIs should return no information for it.

Fixes #13989.
上级 f0b85030
......@@ -97,7 +97,8 @@ internal static bool CanGetSemanticInfo(CSharpSyntaxNode node, bool allowNamedAr
case SyntaxKind.OmittedTypeArgument:
case SyntaxKind.RefExpression:
// There are just placeholders and are not separately meaningful.
case SyntaxKind.DeclarationExpression:
// These are just placeholders and are not separately meaningful.
return false;
default:
......@@ -2465,6 +2466,12 @@ public Conversion ClassifyConversion(int position, ExpressionSyntax expression,
var cdestination = destination.EnsureCSharpSymbolOrNull<ITypeSymbol, TypeSymbol>("destination");
if (expression.Kind() == SyntaxKind.DeclarationExpression)
{
// Conversion from a declaration is unspecified.
return Conversion.NoConversion;
}
if (isExplicitInSource)
{
return ClassifyConversionForCast(position, expression, cdestination);
......
......@@ -348,6 +348,12 @@ private static Binder AdjustBinderForPositionWithinStatement(int position, Binde
var csdestination = destination.EnsureCSharpSymbolOrNull<ITypeSymbol, TypeSymbol>("destination");
if (expression.Kind() == SyntaxKind.DeclarationExpression)
{
// Conversion from a declaration is unspecified.
return Conversion.NoConversion;
}
// Special Case: We have to treat anonymous functions differently, because of the way
// they are cached in the syntax-to-bound node map. Specifically, UnboundLambda nodes
// never appear in the map - they are converted to BoundLambdas, even in error scenarios.
......
......@@ -488,6 +488,12 @@ public override Conversion ClassifyConversion(ExpressionSyntax expression, IType
{
var csdestination = destination.EnsureCSharpSymbolOrNull<ITypeSymbol, TypeSymbol>("destination");
if (expression.Kind() == SyntaxKind.DeclarationExpression)
{
// Conversion from a declaration is unspecified.
return Conversion.NoConversion;
}
if (isExplicitInSource)
{
return ClassifyConversionForCast(expression, csdestination);
......
......@@ -882,9 +882,7 @@ private static void VerifyModelForOutVarInNotExecutableCode(SemanticModel model,
Assert.Equal(local.Type, model.GetSymbolInfo(typeSyntax).Symbol);
}
Assert.Same(symbol, model.GetSymbolInfo(decl).Symbol);
Assert.Equal(local.Type, model.GetTypeInfo(decl).Type);
Assert.Null(model.GetDeclaredSymbol(decl));
AssertInfoForDeclarationExpressionSyntax(model, decl);
foreach (var reference in references)
{
......@@ -900,6 +898,32 @@ private static void VerifyModelForOutVarInNotExecutableCode(SemanticModel model,
}
}
private static void AssertInfoForDeclarationExpressionSyntax(SemanticModel model, DeclarationExpressionSyntax decl)
{
var symbolInfo = model.GetSymbolInfo(decl);
Assert.Null(symbolInfo.Symbol);
Assert.Empty(symbolInfo.CandidateSymbols);
Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
Assert.Equal(symbolInfo, ((CSharpSemanticModel)model).GetSymbolInfo(decl));
var typeInfo = model.GetTypeInfo(decl);
Assert.Null(typeInfo.Type);
Assert.Null(typeInfo.ConvertedType);
Assert.Equal(typeInfo, ((CSharpSemanticModel)model).GetTypeInfo(decl));
var conversion = model.ClassifyConversion(decl, model.Compilation.ObjectType, false);
Assert.False(conversion.Exists);
Assert.Equal(conversion, model.ClassifyConversion(decl, model.Compilation.ObjectType, true));
Assert.Equal(conversion, ((CSharpSemanticModel)model).ClassifyConversion(decl, model.Compilation.ObjectType, false));
Assert.Equal(conversion, ((CSharpSemanticModel)model).ClassifyConversion(decl, model.Compilation.ObjectType, true));
Assert.Equal(conversion, model.ClassifyConversion(decl.Position, decl, model.Compilation.ObjectType, false));
Assert.Equal(conversion, model.ClassifyConversion(decl.Position, decl, model.Compilation.ObjectType, true));
Assert.Equal(conversion, ((CSharpSemanticModel)model).ClassifyConversion(decl.Position, decl, model.Compilation.ObjectType, false));
Assert.Equal(conversion, ((CSharpSemanticModel)model).ClassifyConversion(decl.Position, decl, model.Compilation.ObjectType, true));
Assert.Null(model.GetDeclaredSymbol(decl));
}
private static void VerifyDataFlow(SemanticModel model, DeclarationExpressionSyntax decl, bool isDelegateCreation, bool isExecutableCode, IdentifierNameSyntax[] references, ISymbol symbol)
{
var dataFlowParent = decl.Parent.Parent.Parent as ExpressionSyntax;
......@@ -19733,9 +19757,8 @@ static bool TakeOutParam(object y, out int x)
Assert.False(model.LookupNames(decl.SpanStart).Contains(identifierText));
Assert.Null(model.GetSymbolInfo(decl.Type()).Symbol);
Assert.Null(model.GetSymbolInfo(decl).Symbol);
Assert.Null(model.GetTypeInfo(decl).Type);
Assert.Null(model.GetDeclaredSymbol(decl));
AssertInfoForDeclarationExpressionSyntax(model, decl);
VerifyModelNotSupported(model, references);
}
......@@ -27016,18 +27039,8 @@ public static bool TakeOutParam<T>(T y, out T x)
var declarator = decl.Ancestors().OfType<VariableDeclaratorSyntax>().FirstOrDefault();
var inFieldDeclaratorArgumentlist = declarator != null && declarator.Parent.Parent.Kind() != SyntaxKind.LocalDeclarationStatement &&
(declarator.ArgumentList?.Contains(decl)).GetValueOrDefault();
if (inFieldDeclaratorArgumentlist)
{
Assert.Null(model.GetSymbolInfo(decl).Symbol);
Assert.Null(model.GetSymbolInfo(decl).Symbol);
}
else
{
Assert.Same(symbol, model.GetSymbolInfo(decl).Symbol);
Assert.Same(symbol, model.GetSymbolInfo(decl).Symbol);
}
Assert.Null(model.GetDeclaredSymbol(decl));
AssertInfoForDeclarationExpressionSyntax(model, decl);
foreach (var reference in references)
{
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册