private static async Task <InvocationContext> GetInvocation(Document document, LinePosition linePosition, CancellationToken cancellationToken) { var text = await document.GetTextAsync(cancellationToken); var position = Math.Max(text.Lines.GetPosition(linePosition.ToCodeAnalysisLinePosition()) - 1, 0); // backtrack into the actual invocation var tree = await document.GetSyntaxTreeAsync(cancellationToken); var root = await tree.GetRootAsync(cancellationToken); var node = root.FindToken(position).Parent; // Walk up until we find a node that we're interested in. while (node is not null) { if (node is InvocationExpressionSyntax invocation && invocation.ArgumentList.Span.Contains(position)) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); return(new InvocationContext(semanticModel, position, invocation.Expression, invocation.ArgumentList, invocation.IsInStaticContext())); } if (node is ObjectCreationExpressionSyntax objectCreation && objectCreation.ArgumentList.Span.Contains(position)) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); return(new InvocationContext(semanticModel, position, objectCreation, objectCreation.ArgumentList, objectCreation.IsInStaticContext())); } if (node is AttributeSyntax attributeSyntax && attributeSyntax.ArgumentList.Span.Contains(position)) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); return(new InvocationContext(semanticModel, position, attributeSyntax, attributeSyntax.ArgumentList, attributeSyntax.IsInStaticContext())); } node = node.Parent; } return(null); }