提交 afd49c62 编写于 作者: J jmarolf

support GFU inside nameof for C# and VB

***NO_CI***
 (changeset 1371266)
上级 8f241a8d
......@@ -2075,7 +2075,7 @@ public static bool IsLabelContext(this SyntaxTree syntaxTree, int position, Canc
return false;
}
public static bool IsNameOfContext(this SyntaxTree syntaxTree, int position, SemanticModel semanticModelOpt, CancellationToken cancellationToken)
public static bool IsNameOfContext(this SyntaxTree syntaxTree, int position, SemanticModel semanticModelOpt = null, CancellationToken cancellationToken = default(CancellationToken))
{
var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);
token = token.GetPreviousTokenIfTouchingWord(position);
......
......@@ -60,42 +60,42 @@ private static void DecomposeName(ExpressionSyntax expression, out ExpressionSyn
{
switch (expression.CSharpKind())
{
case SyntaxKind.SimpleMemberAccessExpression:
case SyntaxKind.PointerMemberAccessExpression:
var max = (MemberAccessExpressionSyntax)expression;
qualifier = max.Expression;
name = max.Name.Identifier.ValueText;
arity = max.Name.Arity;
break;
case SyntaxKind.QualifiedName:
var qn = (QualifiedNameSyntax)expression;
qualifier = qn.Left;
name = qn.Right.Identifier.ValueText;
arity = qn.Arity;
break;
case SyntaxKind.AliasQualifiedName:
var aq = (AliasQualifiedNameSyntax)expression;
qualifier = aq.Alias;
name = aq.Name.Identifier.ValueText;
arity = aq.Name.Arity;
break;
case SyntaxKind.GenericName:
var gx = (GenericNameSyntax)expression;
qualifier = null;
name = gx.Identifier.ValueText;
arity = gx.Arity;
break;
case SyntaxKind.IdentifierName:
var nx = (IdentifierNameSyntax)expression;
qualifier = null;
name = nx.Identifier.ValueText;
arity = 0;
break;
default:
qualifier = null;
name = null;
arity = 0;
break;
case SyntaxKind.SimpleMemberAccessExpression:
case SyntaxKind.PointerMemberAccessExpression:
var max = (MemberAccessExpressionSyntax)expression;
qualifier = max.Expression;
name = max.Name.Identifier.ValueText;
arity = max.Name.Arity;
break;
case SyntaxKind.QualifiedName:
var qn = (QualifiedNameSyntax)expression;
qualifier = qn.Left;
name = qn.Right.Identifier.ValueText;
arity = qn.Arity;
break;
case SyntaxKind.AliasQualifiedName:
var aq = (AliasQualifiedNameSyntax)expression;
qualifier = aq.Alias;
name = aq.Name.Identifier.ValueText;
arity = aq.Name.Arity;
break;
case SyntaxKind.GenericName:
var gx = (GenericNameSyntax)expression;
qualifier = null;
name = gx.Identifier.ValueText;
arity = gx.Arity;
break;
case SyntaxKind.IdentifierName:
var nx = (IdentifierNameSyntax)expression;
qualifier = null;
name = nx.Identifier.ValueText;
arity = 0;
break;
default:
qualifier = null;
name = null;
arity = 0;
break;
}
}
......@@ -163,9 +163,9 @@ private static bool CanBindToken(SyntaxToken token)
// Add more token kinds if necessary;
switch (token.CSharpKind())
{
case SyntaxKind.CommaToken:
case SyntaxKind.DelegateKeyword:
return false;
case SyntaxKind.CommaToken:
case SyntaxKind.DelegateKeyword:
return false;
}
return true;
......@@ -315,7 +315,10 @@ public static ISet<INamespaceSymbol> GetUsingNamespacesInScope(this SemanticMode
TypeSyntax type,
CancellationToken cancellationToken)
{
type = GetOutermostType(type);
if (type != null)
{
type = GetOutermostType(type);
}
// Interesting cases based on 3.5.4 Accessibility constraints in the language spec.
// If any of the below hold, then we will override the default accessibility if the
......
......@@ -262,5 +262,10 @@ public bool IsAssignableTo(ITypeSymbol fromSymbol, ITypeSymbol toSymbol, Compila
toSymbol != null &&
((CSharpCompilation)compilation).ClassifyConversion(fromSymbol, toSymbol).IsImplicit;
}
public bool IsNameOfContext(SemanticModel semanticModel, int position, CancellationToken cancellationToken)
{
return semanticModel.SyntaxTree.IsNameOfContext(position, semanticModel, cancellationToken);
}
}
}
\ No newline at end of file
......@@ -48,6 +48,7 @@ internal interface ISemanticFactsService : ILanguageService
bool IsGlobalStatementContext(SemanticModel semanticModel, int position, CancellationToken cancellationToken);
bool IsLabelContext(SemanticModel semanticModel, int position, CancellationToken cancellationToken);
bool IsAttributeNameContext(SemanticModel semanticModel, int position, CancellationToken cancellationToken);
bool IsNameOfContext(SemanticModel semanticModel, int position, CancellationToken cancellationToken);
/// <summary>
/// True if a write is performed to the given expression. Note: reads may also be performed
......
......@@ -447,6 +447,26 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery
Return token.IsChildToken(Of SimpleAsClauseSyntax)(Function(asClause) asClause.AsKeyword)
End Function
<Extension()>
Public Function IsNameOfContext(syntaxTree As SyntaxTree, position As Integer, token As SyntaxToken, Optional cancellationToken As CancellationToken = Nothing) As Boolean
' first do quick exit check
If syntaxTree.IsInPreprocessorDirectiveContext(position, cancellationToken) OrElse
syntaxTree.IsInInactiveRegion(position, cancellationToken) OrElse
syntaxTree.IsEntirelyWithinComment(position, cancellationToken) OrElse
syntaxTree.IsEntirelyWithinStringOrCharLiteral(position, cancellationToken) Then
Return False
End If
Contract.Requires(token = syntaxTree.GetTargetToken(position, cancellationToken))
If token.IsChildToken(Of NameOfExpressionSyntax)(Function(importAliasClause) importAliasClause.OpenParenToken) Then
Return True
End If
Return False
End Function
<Extension()>
Friend Function IsSingleLineStatementContext(syntaxTree As SyntaxTree, position As Integer, cancellationToken As CancellationToken) As Boolean
Dim targetToken = syntaxTree.GetTargetToken(position, cancellationToken)
......
......@@ -245,5 +245,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Function IsAssignableTo(fromSymbol As ITypeSymbol, toSymbol As ITypeSymbol, compilation As Compilation) As Boolean Implements ISemanticFactsService.IsAssignableTo
Return fromSymbol IsNot Nothing AndAlso toSymbol IsNot Nothing AndAlso DirectCast(compilation, VisualBasicCompilation).ClassifyConversion(fromSymbol, toSymbol).IsWidening
End Function
Public Function IsNameOfContext(semanticModel As SemanticModel, position As Integer, cancellationToken As CancellationToken) As Boolean Implements ISemanticFactsService.IsNameOfContext
Dim token = semanticModel.SyntaxTree.GetTargetToken(position, cancellationToken)
Return semanticModel.SyntaxTree.IsNameOfContext(position, token, cancellationToken)
End Function
End Class
End Namespace
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册