Beispiel #1
0
        private static CompletionContext TrySpecialCompletions(ReverseExpressionParser parser, Span loc)
        {
            if (parser.Tokens.Count > 0)
            {
                // Check for context-sensitive intellisense
                var lastClass = parser.Tokens[parser.Tokens.Count - 1];

                if (lastClass.ClassificationType == parser.Classifier.Provider.Comment)
                {
                    // No completions in comments
                    return(EmptyCompletionContext);
                }
                else if (lastClass.ClassificationType == parser.Classifier.Provider.StringLiteral)
                {
                    // String completion
                    return(new StringLiteralCompletionContext(lastClass.Span.GetText(), loc.Start, parser.Span, parser.Buffer));
                }

                // Import completions
                var first = parser.Tokens[0];
                if (IsKeyword(first, "import"))
                {
                    return(ImportCompletionContext.Make(first, lastClass, loc, parser.Snapshot, parser.Span, parser.Buffer, IsSpaceCompletion(parser, loc)));
                }
                else if (IsKeyword(first, "from"))
                {
                    return(FromImportCompletionContext.Make(parser.Tokens, first, loc, parser.Snapshot, parser.Span, parser.Buffer, IsSpaceCompletion(parser, loc)));
                }
                return(null);
            }

            return(EmptyCompletionContext);
        }
Beispiel #2
0
        public static CompletionContext GetSignatureContext(ITextSnapshot snapshot, ITextBuffer buffer, ITrackingSpan span)
        {
            ReverseExpressionParser parser = new ReverseExpressionParser(snapshot, buffer, span);

            var loc = parser.Span.GetSpan(parser.Snapshot.Version);

            int paramIndex;
            var exprRange = parser.GetExpressionRange(1, out paramIndex);

            if (exprRange == null)
            {
                return(EmptyCompletionContext);
            }
            var text = exprRange.Value.GetText();

            var applicableSpan = parser.Snapshot.CreateTrackingSpan(
                exprRange.Value.Span,
                SpanTrackingMode.EdgeExclusive
                );

            return(new NormalCompletionContext(
                       text,
                       loc.Start,
                       parser.Snapshot,
                       applicableSpan,
                       parser.Buffer,
                       paramIndex
                       ));
        }
        private static CompletionAnalysis GetNormalCompletionContext(ReverseExpressionParser parser, Span loc, bool intersectMembers = true, bool hideAdvancedMembers = false)
        {
            var exprRange = parser.GetExpressionRange();

            if (exprRange == null)
            {
                return(CompletionAnalysis.EmptyCompletionContext);
            }
            if (IsSpaceCompletion(parser, loc))
            {
                return(CompletionAnalysis.EmptyCompletionContext);
            }

            var text = exprRange.Value.GetText();

            var applicableSpan = parser.Snapshot.CreateTrackingSpan(
                exprRange.Value.Span,
                SpanTrackingMode.EdgeExclusive
                );

            return(new NormalCompletionAnalysis(
                       text,
                       loc.Start,
                       parser.Snapshot,
                       applicableSpan,
                       parser.Buffer,
                       -1,
                       intersectMembers,
                       hideAdvancedMembers
                       ));
        }
Beispiel #4
0
        /// <summary>
        /// Gets a CompletionContext providing a list of possible members the user can dot through.
        /// </summary>
        public static CompletionContext GetMemberCompletionContext(ITextSnapshot snapshot, ITextBuffer buffer, ITrackingSpan span)
        {
            ReverseExpressionParser parser = new ReverseExpressionParser(snapshot, buffer, span);

            var loc       = parser.Span.GetSpan(parser.Snapshot.Version);
            var line      = parser.Snapshot.GetLineFromPosition(loc.Start);
            var lineStart = line.Start;

            var textLen = loc.End - lineStart.Position;

            if (textLen <= 0)
            {
                // Ctrl-Space on an empty line, we just want to get global vars
                return(new NormalCompletionContext(String.Empty, loc.Start, parser.Snapshot, parser.Span, parser.Buffer, 0));
            }

            return(TrySpecialCompletions(parser, loc) ??
                   GetNormalCompletionContext(parser, loc));
        }
Beispiel #5
0
        /// <summary>
        /// Gets a CompletionContext for the expression at the provided span.  If the span is in
        /// part of an identifier then the expression is extended to complete the identifier.
        /// </summary>
        public static CompletionContext GetExpressionContext(ITextSnapshot snapshot, ITextBuffer buffer, ITrackingSpan span)
        {
            ReverseExpressionParser parser = new ReverseExpressionParser(snapshot, buffer, span);

            var loc       = parser.Span.GetSpan(parser.Snapshot.Version);
            var exprRange = parser.GetExpressionRange();

            if (exprRange == null)
            {
                return(EmptyCompletionContext);
            }

            // extend right for any partial expression the user is hovering on, for example:
            // "x.Baz" where the user is hovering over the B in baz we want the complete
            // expression.
            var text       = exprRange.Value.GetText();
            var endingLine = exprRange.Value.End.GetContainingLine();
            var endText    = snapshot.GetText(exprRange.Value.End.Position, endingLine.End.Position - exprRange.Value.End.Position);

            for (int i = 0; i < endText.Length; i++)
            {
                if (!Char.IsLetterOrDigit(endText[i]) && endText[i] != '_')
                {
                    text += endText.Substring(0, i);
                    break;
                }
            }

            var applicableSpan = parser.Snapshot.CreateTrackingSpan(
                exprRange.Value.Span,
                SpanTrackingMode.EdgeExclusive
                );

            return(new NormalCompletionContext(
                       text,
                       loc.Start,
                       parser.Snapshot,
                       applicableSpan,
                       parser.Buffer,
                       -1
                       ));
        }
Beispiel #6
0
        /// <summary>
        /// Gets a CompletionContext for the expression at the provided span.  If the span is in
        /// part of an identifier then the expression is extended to complete the identifier.
        /// </summary>
        public static CompletionContext GetExpressionContext(ITextSnapshot snapshot, ITextBuffer buffer, ITrackingSpan span)
        {
            ReverseExpressionParser parser = new ReverseExpressionParser(snapshot, buffer, span);

            var loc = parser.Span.GetSpan(parser.Snapshot.Version);
            var exprRange = parser.GetExpressionRange();
            if (exprRange == null) {
                return EmptyCompletionContext;
            }

            // extend right for any partial expression the user is hovering on, for example:
            // "x.Baz" where the user is hovering over the B in baz we want the complete
            // expression.
            var text = exprRange.Value.GetText();
            var endingLine = exprRange.Value.End.GetContainingLine();
            var endText = snapshot.GetText(exprRange.Value.End.Position, endingLine.End.Position - exprRange.Value.End.Position);
            for (int i = 0; i < endText.Length; i++) {
                if (!Char.IsLetterOrDigit(endText[i]) && endText[i] != '_') {
                    text += endText.Substring(0, i);
                    break;
                }
            }

            var applicableSpan = parser.Snapshot.CreateTrackingSpan(
                exprRange.Value.Span,
                SpanTrackingMode.EdgeExclusive
            );

            return new NormalCompletionContext(
                text,
                loc.Start,
                parser.Snapshot,
                applicableSpan,
                parser.Buffer,
                -1
            );
        }
Beispiel #7
0
        private static CompletionContext GetNormalCompletionContext(ReverseExpressionParser parser, Span loc)
        {
            var exprRange = parser.GetExpressionRange();

            if (exprRange == null)
            {
                return(EmptyCompletionContext);
            }
            var text = exprRange.Value.GetText();

            var applicableSpan = parser.Snapshot.CreateTrackingSpan(
                exprRange.Value.Span,
                SpanTrackingMode.EdgeExclusive
                );

            return(new NormalCompletionContext(
                       text,
                       loc.Start,
                       parser.Snapshot,
                       applicableSpan,
                       parser.Buffer,
                       -1
                       ));
        }
Beispiel #8
0
        private static bool IsSpaceCompletion(ReverseExpressionParser parser, Span loc)
        {
            var keySpan = new SnapshotSpan(parser.Snapshot, loc.Start - 1, 1);

            return(keySpan.GetText() == " ");
        }
        /// <summary>
        /// Gets a list of signatuers available for the expression at the provided location in the snapshot.
        /// </summary>
        public SignatureAnalysis GetSignatures(ITextSnapshot snapshot, ITextBuffer buffer, ITrackingSpan span)
        {
            ReverseExpressionParser parser = new ReverseExpressionParser(snapshot, buffer, span);

            var loc = parser.Span.GetSpan(parser.Snapshot.Version);

            int           paramIndex;
            SnapshotPoint?sigStart;
            var           exprRange = parser.GetExpressionRange(1, out paramIndex, out sigStart);

            if (exprRange == null || sigStart == null)
            {
                return(new SignatureAnalysis("", 0, new ISignature[0]));
            }

            Debug.Assert(sigStart != null);
            var text = new SnapshotSpan(exprRange.Value.Snapshot, new Span(exprRange.Value.Start, sigStart.Value.Position - exprRange.Value.Start)).GetText();
            //var text = exprRange.Value.GetText();
            var applicableSpan = parser.Snapshot.CreateTrackingSpan(exprRange.Value.Span, SpanTrackingMode.EdgeInclusive);

            var liveSigs = TryGetLiveSignatures(snapshot, paramIndex, text, applicableSpan);

            if (liveSigs != null)
            {
                return(liveSigs);
            }

            var start = Stopwatch.ElapsedMilliseconds;

            var analysisItem = buffer.GetAnalysis();

            if (analysisItem != null)
            {
                var analysis = ((IPythonProjectEntry)analysisItem).Analysis;
                if (analysis != null)
                {
                    var lineNo = parser.Snapshot.GetLineNumberFromPosition(loc.Start);

                    var sigs = analysis.GetSignatures(text, lineNo + 1);
                    var end  = Stopwatch.ElapsedMilliseconds;

                    if (/*Logging &&*/ (end - start) > CompletionAnalysis.TooMuchTime)
                    {
                        Trace.WriteLine(String.Format("{0} lookup time {1} for signatures", text, end - start));
                    }

                    var result = new List <ISignature>();
                    foreach (var sig in sigs)
                    {
                        result.Add(new PythonSignature(applicableSpan, sig, paramIndex));
                    }

                    return(new SignatureAnalysis(
                               text,
                               paramIndex,
                               result
                               ));
                }
            }
            return(new SignatureAnalysis(text, paramIndex, new ISignature[0]));
        }
        /// <summary>
        /// Gets a ExpressionAnalysis for the expression at the provided span.  If the span is in
        /// part of an identifier then the expression is extended to complete the identifier.
        /// </summary>
        public ExpressionAnalysis AnalyzeExpression(ITextSnapshot snapshot, ITextBuffer buffer, ITrackingSpan span)
        {
            ReverseExpressionParser parser = new ReverseExpressionParser(snapshot, buffer, span);

            var loc       = parser.Span.GetSpan(parser.Snapshot.Version);
            var exprRange = parser.GetExpressionRange();

            if (exprRange == null)
            {
                return(ExpressionAnalysis.Empty);
            }

            // extend right for any partial expression the user is hovering on, for example:
            // "x.Baz" where the user is hovering over the B in baz we want the complete
            // expression.
            var text       = exprRange.Value.GetText();
            var endingLine = exprRange.Value.End.GetContainingLine();

            if (endingLine.End.Position - exprRange.Value.End.Position < 0)
            {
                return(ExpressionAnalysis.Empty);
            }
            var  endText  = snapshot.GetText(exprRange.Value.End.Position, endingLine.End.Position - exprRange.Value.End.Position);
            bool allChars = true;

            for (int i = 0; i < endText.Length; i++)
            {
                if (!Char.IsLetterOrDigit(endText[i]) && endText[i] != '_')
                {
                    text    += endText.Substring(0, i);
                    allChars = false;
                    break;
                }
            }
            if (allChars)
            {
                text += endText;
            }

            var applicableSpan = parser.Snapshot.CreateTrackingSpan(
                exprRange.Value.Span,
                SpanTrackingMode.EdgeExclusive
                );

            IProjectEntry analysisItem;

            if (buffer.TryGetAnalysis(out analysisItem))
            {
                var analysis = ((IPythonProjectEntry)analysisItem).Analysis;
                if (analysis != null && text.Length > 0)
                {
                    var lineNo = parser.Snapshot.GetLineNumberFromPosition(loc.Start);
                    return(new ExpressionAnalysis(
                               text,
                               analysis,
                               lineNo + 1,
                               applicableSpan));
                }
            }

            return(ExpressionAnalysis.Empty);
        }
Beispiel #11
0
        private static CompletionContext TrySpecialCompletions(ReverseExpressionParser parser, Span loc)
        {
            if (parser.Tokens.Count > 0) {
                // Check for context-sensitive intellisense
                var lastClass = parser.Tokens[parser.Tokens.Count - 1];

                if (lastClass.ClassificationType == parser.Classifier.Provider.Comment) {
                    // No completions in comments
                    return EmptyCompletionContext;
                } else if (lastClass.ClassificationType == parser.Classifier.Provider.StringLiteral) {
                    // String completion
                    return new StringLiteralCompletionContext(lastClass.Span.GetText(), loc.Start, parser.Span, parser.Buffer);
                }

                // Import completions
                var first = parser.Tokens[0];
                if (IsKeyword(first, "import")) {
                    return ImportCompletionContext.Make(first, lastClass, loc, parser.Snapshot, parser.Span, parser.Buffer, IsSpaceCompletion(parser, loc));
                } else if (IsKeyword(first, "from")) {
                    return FromImportCompletionContext.Make(parser.Tokens, first, loc, parser.Snapshot, parser.Span, parser.Buffer, IsSpaceCompletion(parser, loc));
                }
                return null;
            }

            return EmptyCompletionContext;
        }
Beispiel #12
0
 private static bool IsSpaceCompletion(ReverseExpressionParser parser, Span loc)
 {
     var keySpan = new SnapshotSpan(parser.Snapshot, loc.Start - 1, 1);
     return (keySpan.GetText() == " ");
 }
Beispiel #13
0
        private static CompletionContext GetNormalCompletionContext(ReverseExpressionParser parser, Span loc)
        {
            var exprRange = parser.GetExpressionRange();
            if (exprRange == null) {
                return EmptyCompletionContext;
            }
            var text = exprRange.Value.GetText();

            var applicableSpan = parser.Snapshot.CreateTrackingSpan(
                exprRange.Value.Span,
                SpanTrackingMode.EdgeExclusive
            );

            return new NormalCompletionContext(
                text,
                loc.Start,
                parser.Snapshot,
                applicableSpan,
                parser.Buffer,
                -1
            );
        }
Beispiel #14
0
        public static CompletionContext GetSignatureContext(ITextSnapshot snapshot, ITextBuffer buffer, ITrackingSpan span)
        {
            ReverseExpressionParser parser = new ReverseExpressionParser(snapshot, buffer, span);

            var loc = parser.Span.GetSpan(parser.Snapshot.Version);

            int paramIndex;
            var exprRange = parser.GetExpressionRange(1, out paramIndex);
            if (exprRange == null) {
                return EmptyCompletionContext;
            }
            var text = exprRange.Value.GetText();

            var applicableSpan = parser.Snapshot.CreateTrackingSpan(
                exprRange.Value.Span,
                SpanTrackingMode.EdgeExclusive
            );

            return new NormalCompletionContext(
                text,
                loc.Start,
                parser.Snapshot,
                applicableSpan,
                parser.Buffer,
                paramIndex
            );
        }
Beispiel #15
0
        /// <summary>
        /// Gets a CompletionContext providing a list of possible members the user can dot through.
        /// </summary>
        public static CompletionContext GetMemberCompletionContext(ITextSnapshot snapshot, ITextBuffer buffer, ITrackingSpan span)
        {
            ReverseExpressionParser parser = new ReverseExpressionParser(snapshot, buffer, span);

            var loc = parser.Span.GetSpan(parser.Snapshot.Version);
            var line = parser.Snapshot.GetLineFromPosition(loc.Start);
            var lineStart = line.Start;

            var textLen = loc.End - lineStart.Position;
            if (textLen <= 0) {
                // Ctrl-Space on an empty line, we just want to get global vars
                return new NormalCompletionContext(String.Empty, loc.Start, parser.Snapshot, parser.Span, parser.Buffer, 0);
            }

            return TrySpecialCompletions(parser, loc) ??
                   GetNormalCompletionContext(parser, loc);
        }