public override async Task <CheckResult> ShouldProvideCompletion(Document document, int position)
        {
            if (!document.SupportsSyntaxTree || !document.SupportsSemanticModel)
            {
                return(CheckResult.False());
            }

            var syntaxRoot = await document.GetSyntaxRootAsync();

            if (syntaxRoot == null)
            {
                return(CheckResult.False());
            }

            var semanticModel = await document.GetSemanticModelAsync();

            if (semanticModel == null)
            {
                return(CheckResult.False());
            }

            // Walk up and save literal expression if present (we can autocomplete literals).
            var currentToken      = syntaxRoot.FindToken(position - 1);
            var currentNode       = currentToken.Parent;
            var literalExpression = RoslynUtils.WalkUpStringSyntaxOnce(ref currentNode, ref position);

            // Walk up parenthesis because the inference service doesn't handle that.
            currentToken = syntaxRoot.FindToken(position - 1);
            currentNode  = currentToken.Parent;
            if (currentToken.Kind() != SyntaxKind.CloseParenToken)
            {
                RoslynUtils.WalkUpParenthesisExpressions(ref currentNode, ref position);
            }

            var inferredTypes = RoslynUtils.InferTypes(semanticModel, position, null, CancellationToken.None);

            if (inferredTypes.Any(RoslynUtils.TypeIsNodePath))
            {
                return(CheckResult.True(literalExpression));
            }

            // Our own custom inference for NodePath

            if (IsPathConstructorArgumentOfNodePath(syntaxRoot, semanticModel, currentNode, position))
            {
                return(CheckResult.True(literalExpression));
            }

            if (IsParenthesizedExprActuallyCastToNodePath(semanticModel, currentNode))
            {
                return(CheckResult.True(literalExpression));
            }

            return(CheckResult.False());
        }
示例#2
0
        public override async Task <CheckResult> ShouldProvideCompletion(Document document, int position)
        {
            if (!document.SupportsSyntaxTree || !document.SupportsSemanticModel)
            {
                return(CheckResult.False());
            }

            var syntaxRoot = await document.GetSyntaxRootAsync();

            if (syntaxRoot == null)
            {
                return(CheckResult.False());
            }

            var semanticModel = await document.GetSemanticModelAsync();

            if (semanticModel == null)
            {
                return(CheckResult.False());
            }

            // Walk up and save literal expression if present (we can autocomplete literals).
            var currentToken      = syntaxRoot.FindToken(position - 1);
            var currentNode       = currentToken.Parent;
            var literalExpression = RoslynUtils.WalkUpStringSyntaxOnce(ref currentNode, ref position);

            // Walk up parenthesis because the inference service doesn't handle that.
            currentToken = syntaxRoot.FindToken(position - 1);
            currentNode  = currentToken.Parent;
            if (currentToken.Kind() != SyntaxKind.CloseParenToken)
            {
                RoslynUtils.WalkUpParenthesisExpressions(ref currentNode, ref position);
            }

            if (!(currentNode is ArgumentListSyntax argumentList && currentNode.Parent is InvocationExpressionSyntax invocation))
            {
                return(CheckResult.False());
            }

            var previousToken = syntaxRoot.FindToken(position - 1);

            if (previousToken != argumentList.OpenParenToken && previousToken.Kind() != SyntaxKind.CommaToken)
            {
                return(CheckResult.False());
            }

            if (RoslynUtils.IsExpectedInvocationArgument(semanticModel, previousToken, invocation, argumentList, _expectedInvocations))
            {
                return(CheckResult.True(literalExpression));
            }

            return(CheckResult.False());
        }