Beispiel #1
0
        public override ISpecificCodeCompletionContext GetCompletionContext(CodeCompletionContext context)
        {
            if (context.SelectedRange.TextRange.Length > 0)
            {
                return(null);
            }

            var fsFile    = (IFSharpFile)context.File;
            var parseTree = fsFile.ParseResults?.Value.ParseTree?.Value;

            if (parseTree == null)
            {
                return(null);
            }

            var caretTreeOffset = context.CaretDocumentOffset;
            var caretOffset     = caretTreeOffset.Offset;

            var token           = fsFile.FindTokenAt(caretTreeOffset);
            var tokenType       = token?.GetTokenType();
            var tokenBefore     = fsFile.FindTokenAt(caretTreeOffset - 1);
            var tokenBeforeType = tokenBefore?.GetTokenType();

            if (tokenType == FSharpTokenType.COLON_COLON || tokenBeforeType == FSharpTokenType.COLON_COLON)
            {
                return(null);
            }

            if (tokenBeforeType == FSharpTokenType.LINE_COMMENT ||
                tokenBeforeType == FSharpTokenType.DEAD_CODE || tokenType == FSharpTokenType.DEAD_CODE ||
                tokenBeforeType != null && (token == tokenBefore || token == null) &&
                (tokenBeforeType.IsComment || tokenBeforeType.IsStringLiteral ||
                 tokenBeforeType.IsConstantLiteral) ||
                tokenBefore.GetDocumentEndOffset() < caretTreeOffset || token.GetDocumentEndOffset() < caretTreeOffset)
            {
                return(null);
            }

            var document = context.Document;
            var completedRangeStartOffset = CanBeIdentifierPart(tokenBeforeType)
          ? tokenBefore.GetDocumentStartOffset().Offset
          : caretOffset;
            var completedRange = new DocumentRange(document, new TextRange(completedRangeStartOffset, caretOffset));
            var defaultRanges  = GetTextLookupRanges(context, completedRange);

            var ranges = CanBeIdentifierPart(token?.GetTokenType())
        ? defaultRanges.WithReplaceRange(new DocumentRange(document, new TextRange(completedRangeStartOffset,
                                                                                   Math.Max(token.GetDocumentEndOffset().Offset, caretOffset))))
        : defaultRanges;

            var coords              = document.GetCoordsByOffset(caretOffset);
            var lineText            = document.GetLineText(coords.Line);
            var partialName         = QuickParse.GetPartialLongNameEx(lineText, (int)coords.Column - 1);
            var fsCompletionContext = UntypedParseImpl.TryGetCompletionContext(coords.ToPos(), parseTree, lineText);

            return(new FSharpCodeCompletionContext(context, fsCompletionContext, ranges, coords, partialName, tokenBefore,
                                                   token, lineText));
        }
        public override ISpecificCodeCompletionContext GetCompletionContext(CodeCompletionContext context)
        {
            var fsFile       = (IFSharpFile)context.File;
            var parseResults = fsFile.ParseResults;

            var caretTreeOffset = context.CaretTreeOffset;
            var caretOffset     = caretTreeOffset.Offset;

            var token           = fsFile.FindTokenAt(caretTreeOffset);
            var tokenBefore     = fsFile.FindTokenAt(caretTreeOffset - 1);
            var tokenBeforeType = tokenBefore?.GetTokenType();

            var parseTree = parseResults?.Value.ParseTree?.Value;

            if (parseTree == null ||
                tokenBeforeType == FSharpTokenType.LINE_COMMENT ||
                tokenBeforeType == FSharpTokenType.DEAD_CODE || token?.GetTokenType() == FSharpTokenType.DEAD_CODE ||
                token == tokenBefore && tokenBeforeType != null &&
                (tokenBeforeType.IsComment || tokenBeforeType.IsStringLiteral ||
                 tokenBeforeType.IsConstantLiteral) ||
                context.SelectedRange.TextRange.Length > 0 ||
                tokenBefore.GetTreeEndOffset() < caretTreeOffset || token.GetTreeEndOffset() < caretTreeOffset)
            {
                var selectedRange = context.SelectedRange;
                return(new FSharpCodeCompletionContext(context, CompletionContext.Invalid,
                                                       new TextLookupRanges(selectedRange, selectedRange), DocumentCoords.Empty, null));
            }

            var document = context.Document;
            var completedRangeStartOffset =
                tokenBeforeType != null && (tokenBeforeType == FSharpTokenType.IDENTIFIER || tokenBeforeType.IsKeyword)
          ? tokenBefore.GetTreeStartOffset().Offset
          : caretOffset;
            var completedRange = new DocumentRange(document, new TextRange(completedRangeStartOffset, caretOffset));
            var defaultRanges  = GetTextLookupRanges(context, completedRange);

            var ranges = ShouldReplace(token)
        ? defaultRanges.WithReplaceRange(new DocumentRange(document, new TextRange(completedRangeStartOffset,
                                                                                   Math.Max(token.GetTreeEndOffset().Offset, caretOffset))))
        : defaultRanges;

            var coords              = document.GetCoordsByOffset(caretOffset);
            var lineText            = document.GetLineText(coords.Line);
            var partialName         = QuickParse.GetPartialLongNameEx(lineText, (int)coords.Column - 1);
            var fsCompletionContext = UntypedParseImpl.TryGetCompletionContext(coords.GetPos(), parseTree, lineText);

            return(new FSharpCodeCompletionContext(context, fsCompletionContext, ranges, coords, partialName, tokenBefore,
                                                   token, lineText));
        }