Exemple #1
0
        protected virtual int?GetSmartIndentation(ITextSnapshotLine line)
        {
            ITextSnapshot snapshot           = line.Snapshot;
            SnapshotPoint contextEndPosition = line.Start;
            SnapshotPoint endPosition        = line.EndIncludingLineBreak;
            SnapshotPoint endPositionOnLine  = line.End;

            IReferenceAnchors anchors  = FindNearestAnchors(contextEndPosition);
            IAnchor           previous = anchors.Previous;

            int     spanEnd = Math.Min(line.Snapshot.Length, endPosition.Position + 1);
            Span    span;
            IAnchor enclosing = anchors.Enclosing;

            if (enclosing != null)
            {
                span = Span.FromBounds(enclosing.TrackingSpan.GetStartPoint(snapshot).Position, spanEnd);
            }
            else if (previous != null)
            {
                // at least for now, include the previous span due to the way error handling places bounds on an anchor
                span = Span.FromBounds(previous.TrackingSpan.GetStartPoint(snapshot).Position, spanEnd);
            }
            else
            {
                span = Span.FromBounds(0, spanEnd);
            }

            var diagnosticsPane = DiagnosticsPane;

            if (diagnosticsPane != null)
            {
                diagnosticsPane.WriteLine(string.Format("Smart indent from anchor span: {0}", span));
            }

            ITokenSource bufferTokenSource = GetTokenSource(new SnapshotSpan(snapshot, span));
            ITokenSource tokenSource       = new CodeCompletionTokenSource(bufferTokenSource, endPosition);
            ITokenStream tokenStream       = new CommonTokenStream(tokenSource);

            IDictionary <RuleContext, CaretReachedException> parseTrees = GetParseTrees(tokenStream, anchors);

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

            var indentLevels = new SortedDictionary <int, IList <KeyValuePair <RuleContext, CaretReachedException> > >();

            foreach (var parseTree in parseTrees)
            {
                if (parseTree.Value == null)
                {
                    continue;
                }

                IParseTree firstNodeOnLine = FindFirstNodeAfterOffset(parseTree.Key, line.Start.Position);
                if (firstNodeOnLine == null)
                {
                    firstNodeOnLine = parseTree.Value.FinalContext;
                }

                if (firstNodeOnLine == null)
                {
                    continue;
                }

                int?indentationLevel = GetIndent(parseTree, firstNodeOnLine, line.Start);
                if (indentationLevel == null)
                {
                    continue;
                }

                IList <KeyValuePair <RuleContext, CaretReachedException> > indentList;
                if (!indentLevels.TryGetValue(indentationLevel.Value, out indentList))
                {
                    indentList = new List <KeyValuePair <RuleContext, CaretReachedException> >();
                    indentLevels[indentationLevel.Value] = indentList;
                }

                indentList.Add(parseTree);
            }

            if (indentLevels.Count == 0)
            {
                return(null);
            }

            int indentLevel = indentLevels.First().Key;

            if (indentLevels.Count > 1)
            {
                // TODO: resolve multiple possibilities
            }

            return(indentLevel);
        }
 protected abstract IDictionary<RuleContext, CaretReachedException> GetParseTrees(ITokenStream tokens, IReferenceAnchors referenceAnchors);
Exemple #3
0
 protected abstract IDictionary <RuleContext, CaretReachedException> GetParseTrees(ITokenStream tokens, IReferenceAnchors referenceAnchors);
Exemple #4
0
        protected override IDictionary <RuleContext, CaretReachedException> GetParseTrees(ITokenStream tokens, IReferenceAnchors referenceAnchors)
        {
            Antlr4CodeCompletionParser parser = new Antlr4CodeCompletionParser(tokens);

            parser.RemoveErrorListeners();
            parser.BuildParseTree = true;
            parser.ErrorHandler   = new CodeCompletionErrorStrategy();

            Antlr4ForestParser forestParser;

            if (referenceAnchors.Previous != null)
            {
                switch (referenceAnchors.Previous.RuleIndex)
                {
                case GrammarParser.RULE_ruleSpec:
                    forestParser = Antlr4ForestParser.Rules;
                    break;

                default:
                    forestParser = null;
                    break;
                }
            }
            else
            {
                forestParser = Antlr4ForestParser.GrammarSpec;
            }

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

            var originalInterpreter = parser.Interpreter;

            try
            {
                IntervalSet wordlikeTokenTypes = IntervalSet.Of(0, GrammarParser._ATN.maxTokenType);
                parser.Interpreter = new FixedCompletionParserATNSimulator(parser, GrammarParser._ATN, wordlikeTokenTypes);
                return(forestParser.GetParseTrees(parser));
            }
            finally
            {
                parser.Interpreter = originalInterpreter;
            }
        }