Skip to content

Commit 0f69fed

Browse files
committed
Improve duplicate symbol detection
1 parent 33163e0 commit 0f69fed

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

GenericSymbolWithSyntax.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ CancellationToken cancellationToken
114114
/// <summary>
115115
/// Gets a new instance representing the given syntax node and its associated generic symbol.
116116
/// </summary>
117+
/// <remarks>
118+
/// <para>
119+
/// Generic method invocations with an explicit type argument list will produce both a
120+
/// <see cref="InvocationExpressionSyntax"/> and a descendant <see cref="GenericNameSyntax"/>. In this case, only the
121+
/// <see cref="InvocationExpressionSyntax"/> node is supported by this method; the <see cref="GenericNameSyntax"/> will
122+
/// return <see langword="null"/>.
123+
/// </para>
124+
/// </remarks>
117125
/// <param name="syntaxNode">The syntax node to associate with a generic symbol.</param>
118126
/// <param name="semanticModel">
119127
/// The <see cref="SemanticModel"/> used to get a <see cref="ISymbol">symbolic reference</see> to
@@ -147,13 +155,22 @@ private static ISymbol? GetSymbol
147155
CancellationToken cancellationToken
148156
)
149157
{
150-
if ((genericNameSyntax.Parent is InvocationExpressionSyntax) ||
151-
((genericNameSyntax.Parent is MemberAccessExpressionSyntax memberAccessExpressionSyntax) &&
152-
(memberAccessExpressionSyntax.Parent is InvocationExpressionSyntax)))
158+
var syntaxNode = genericNameSyntax.Parent;
159+
for ( ; syntaxNode is MemberAccessExpressionSyntax; syntaxNode = syntaxNode.Parent) { }
160+
if (syntaxNode is InvocationExpressionSyntax)
153161
{
154-
// generic method invocations with an explicit type argument list produce a GenericNameSyntax node
155-
// this node is already added to the tree via the (grand)parent InvocationExpressionSyntax node
156-
return null;
162+
var invocationOperation = semanticModel.GetOperation(syntaxNode, cancellationToken) as IInvocationOperation;
163+
var methodSymbol = invocationOperation?.TargetMethod;
164+
if ((methodSymbol is not null) && (genericNameSyntax.Arity == methodSymbol.Arity) &&
165+
(genericNameSyntax.Identifier.Text == methodSymbol.Name))
166+
{
167+
var genericNameSymbol = semanticModel.GetSymbolInfo(genericNameSyntax, cancellationToken).Symbol;
168+
if (SymbolEqualityComparer.Default.Equals(genericNameSymbol, methodSymbol))
169+
{
170+
return null;
171+
}
172+
return genericNameSymbol;
173+
}
157174
}
158175
return semanticModel.GetSymbolInfo(genericNameSyntax, cancellationToken).Symbol;
159176
}

0 commit comments

Comments
 (0)