Exemple #1
0
            public override Tuple <IParseTree, int> VisitLexerRule([NotNull] AbstractGrammarParser.LexerRuleContext context)
            {
                if (context.name == null)
                {
                    return(null);
                }

                if (ParseTrees.GetTerminalNodeType(targetElement) == GrammarParser.AT)
                {
                    return(Tuple.Create <IParseTree, int>(context, 0));
                }

                if (context.COLON() != null)
                {
                    if (ParseTrees.StartsBeforeStartOf(context.COLON(), targetElement))
                    {
                        switch (ParseTrees.GetTerminalNodeType(targetElement))
                        {
                        case GrammarParser.SEMI:
                        case GrammarParser.OR:
                            return(Tuple.Create <IParseTree, int>(context.COLON(), 0));

                        default:
                            return(Tuple.Create <IParseTree, int>(context.COLON(), _indentSize));
                        }
                    }
                }

                return(Tuple.Create <IParseTree, int>(context, _indentSize));
            }
 public override void EnterTokensSpec([NotNull] AbstractGrammarParser.TokensSpecContext context)
 {
     foreach (GrammarParser.IdContext id in context.id())
     {
         AddNavigationTarget(id, ParseTrees.GetStartNode(id), _navigationSource._lexerRuleNavigationType, _navigationSource._lexerRuleGlyph);
     }
 }
Exemple #3
0
            public override Tuple <IParseTree, int> VisitActionBlock([NotNull] AbstractGrammarParser.ActionBlockContext context)
            {
                if (context.ChildCount == 0 || targetElement == context.GetChild(0))
                {
                    return(null);
                }

                if (ParseTrees.GetTerminalNodeType(targetElement) == GrammarParser.RBRACE)
                {
                    return(Tuple.Create <IParseTree, int>(context, 0));
                }

                // align to the previous element
                for (int i = priorSiblings.Count - 2; i >= 0; i--)
                {
                    IParseTree sibling = priorSiblings[i];
                    // stop at the first id rule, index 0 is the BEGIN_ACTION terminal itself
                    if (i == 1 || ParseTrees.ElementStartsLine(sibling))
                    {
                        return(Tuple.Create(sibling, 0));
                    }
                }

                return(Tuple.Create <IParseTree, int>(context, _indentSize));
            }
Exemple #4
0
            private Tuple <IParseTree, int> VisitElements()
            {
                // the non-terminals under these rules are straightforward
                int firstElementIndex = -1;

                for (int i = 0; i < priorSiblings.Count; i++)
                {
                    IParseTree sibling = priorSiblings[i];
                    if (sibling is IRuleNode)
                    {
                        firstElementIndex = i;
                        break;
                    }
                }

                for (int i = priorSiblings.Count - 2; i >= 0; i--)
                {
                    IParseTree sibling = priorSiblings[i];
                    if (!(sibling is IRuleNode))
                    {
                        continue;
                    }

                    if (i == firstElementIndex || ParseTrees.ElementStartsLine(sibling))
                    {
                        return(Tuple.Create(sibling, 0));
                    }
                }

                // handle at the parent
                return(null);
            }
Exemple #5
0
            public override Tuple <IParseTree, int> VisitLabeledAlt([NotNull] AbstractGrammarParser.LabeledAltContext context)
            {
                Debug.Assert(ParseTrees.GetTerminalNodeType(targetElement) == GrammarParser.POUND);
                if (context.alternative() == null)
                {
                    return(null);
                }

                return(Tuple.Create <IParseTree, int>(context.alternative(), 0));
            }
Exemple #6
0
            public override Tuple <IParseTree, int> VisitLexerAlt([NotNull] AbstractGrammarParser.LexerAltContext context)
            {
                Debug.Assert(context.lexerCommands() != null && ParseTrees.IsAncestorOf(context.lexerCommands(), targetElement));
                if (context.lexerElements() == null)
                {
                    return(null);
                }

                return(Tuple.Create <IParseTree, int>(context.lexerElements(), 0));
            }
Exemple #7
0
            private void ExitAnchor(ParserRuleContext context, int anchorId)
            {
                int              start          = _anchorPositions.Pop();
                Interval         sourceInterval = ParseTrees.GetSourceInterval(context);
                int              stop           = sourceInterval.b + 1;
                SpanTrackingMode trackingMode   = context.Stop != null ? SpanTrackingMode.EdgeExclusive : SpanTrackingMode.EdgePositive;

                if (stop >= start)
                {
                    _anchors.Add(CreateAnchor(context, start, stop, trackingMode, anchorId));
                }
            }
Exemple #8
0
            public override Tuple <IParseTree, int> VisitRules([NotNull] AbstractGrammarParser.RulesContext context)
            {
                for (int i = priorSiblings.Count - 2; i >= 0; i--)
                {
                    IParseTree sibling = priorSiblings[i];
                    if (i == 0 || ParseTrees.ElementStartsLine(sibling))
                    {
                        return(Tuple.Create(sibling, 0));
                    }
                }

                return(null);
            }
Exemple #9
0
            public override Tuple <IParseTree, int> VisitOptionsSpec([NotNull] AbstractGrammarParser.OptionsSpecContext context)
            {
                // use previous option if any, otherwise use the block.
                // special handling for closing }
                if (targetElement == context.RBRACE())
                {
                    return(Tuple.Create <IParseTree, int>(context, 0));
                }

                int firstOptionIndex = -1;

                for (int i = 0; i < priorSiblings.Count; i++)
                {
                    IRuleNode sibling = priorSiblings[i] as IRuleNode;
                    if (sibling == null)
                    {
                        continue;
                    }

                    if (sibling.RuleContext.RuleIndex == GrammarParser.RULE_option)
                    {
                        firstOptionIndex = i;
                        break;
                    }
                }

                bool semi = ParseTrees.GetTerminalNodeType(targetElement) == GrammarParser.SEMI;

                for (int i = priorSiblings.Count - 2; i >= 0; i--)
                {
                    IRuleNode sibling = priorSiblings[i] as IRuleNode;
                    if (sibling == null)
                    {
                        continue;
                    }

                    RuleContext ruleContext = sibling.RuleContext;
                    if (ruleContext.RuleIndex == GrammarParser.RULE_option)
                    {
                        if (i == firstOptionIndex || ParseTrees.ElementStartsLine(sibling))
                        {
                            return(Tuple.Create <IParseTree, int>(sibling, semi ? _indentSize : 0));
                        }
                    }
                }

                return(Tuple.Create <IParseTree, int>(context, _indentSize));
            }
Exemple #10
0
        protected virtual ITerminalNode FindFirstNodeAfterOffset(IParseTree parseTree, int offset)
        {
            ITerminalNode lastNode = ParseTrees.GetStopNode(parseTree);

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

            ICaretToken caretToken = lastNode.Symbol as ICaretToken;

            if (caretToken != null)
            {
                throw new NotImplementedException();
            }
            else if (lastNode.Symbol.StartIndex < offset)
            {
                return(null);
            }

            lastNode = parseTree as ITerminalNode;
            if (lastNode != null)
            {
                return(lastNode);
            }

            for (int i = 0; i < parseTree.ChildCount; i++)
            {
                ITerminalNode node = FindFirstNodeAfterOffset(parseTree.GetChild(i), offset);
                if (node != null)
                {
                    return(node);
                }
            }

            return(null);
        }
Exemple #11
0
        protected virtual int?GetIndent(KeyValuePair <RuleContext, CaretReachedException> parseTree, IParseTree firstNodeOnLine, SnapshotPoint lineStart)
        {
            for (IParseTree ancestor = firstNodeOnLine; ancestor != null; ancestor = ancestor.Parent)
            {
                AlignmentRequirements requirements = GetAlignmentRequirement(parseTree, firstNodeOnLine, ancestor);
                if ((requirements & AlignmentRequirements.UseAncestor) != 0)
                {
                    continue;
                }

                if ((requirements & AlignmentRequirements.IgnoreTree) != 0)
                {
                    return(null);
                }

                IList <IParseTree> siblings = null;
                if ((requirements & AlignmentRequirements.PriorSibling) != 0)
                {
                    int childCount = ancestor.ChildCount;
                    siblings = new List <IParseTree>(childCount);
                    for (int i = 0; i < childCount; i++)
                    {
                        IParseTree child = ancestor.GetChild(i);
                        siblings.Add(child);
                        if (ParseTrees.IsAncestorOf(child, firstNodeOnLine))
                        {
                            break;
                        }
                    }
                }

                Tuple <IParseTree, int> alignmentElement = GetAlignmentElement(parseTree, firstNodeOnLine, ancestor, siblings);
                if (alignmentElement == null)
                {
                    continue;
                }

                IToken startToken          = ParseTrees.GetStartSymbol(alignmentElement.Item1);
                string beginningOfLineText = startToken.TokenSource.InputStream.GetText(new Interval(startToken.StartIndex - startToken.Column, startToken.StartIndex - 1));
                int    elementIndent       = 0;
                for (int i = 0; i < beginningOfLineText.Length; i++)
                {
                    if (beginningOfLineText[i] == '\t')
                    {
                        elementIndent += TabSize;
                        elementIndent -= (elementIndent % TabSize);
                    }
                    else
                    {
                        elementIndent++;
                    }
                }

                var diagnosticsPane = DiagnosticsPane;
                if (diagnosticsPane != null)
                {
                    if (ParseTrees.GetStartSymbol(firstNodeOnLine) == startToken)
                    {
                        diagnosticsPane.WriteLine("Attempting to indent a line relative to an element on that line.");
                    }

                    diagnosticsPane.WriteLine(string.Format("Indent {0} relative to {1} (offset {2}) => {3}", firstNodeOnLine, alignmentElement.Item1, alignmentElement.Item2, elementIndent + alignmentElement.Item2));
                }

                return(elementIndent + alignmentElement.Item2);
            }

            return(null);
        }
Exemple #12
0
            private Tuple <IParseTree, int> VisitGenericBlock(ParserRuleContext container)
            {
                if (targetElement == ParseTrees.GetStartNode(container))
                {
                    return(null);
                }

                if (ParseTrees.GetTerminalNodeType(targetElement) == GrammarParser.RPAREN)
                {
                    return(Tuple.Create <IParseTree, int>(container, 0));
                }

                // OR lines up with previous OR
                bool orNode = ParseTrees.GetTerminalNodeType(targetElement) == GrammarParser.OR;

                if (orNode)
                {
                    for (int i = priorSiblings.Count - 2; i >= 0; i--)
                    {
                        ITerminalNode sibling = priorSiblings[i] as ITerminalNode;
                        if (sibling == null)
                        {
                            continue;
                        }

                        if (i == 0 || ParseTrees.ElementStartsLine(sibling))
                        {
                            return(Tuple.Create <IParseTree, int>(sibling, 0));
                        }
                    }

                    if (ParseTrees.GetTerminalNodeType(ParseTrees.GetStartNode(container)) != GrammarParser.LPAREN)
                    {
                        // handle at the parent so it aligns at the (
                        return(null);
                    }

                    return(Tuple.Create <IParseTree, int>(container, 0));
                }

                // the non-terminals under these rules are straightforward
                int firstRuleIndex = -1;

                for (int i = 0; i < priorSiblings.Count; i++)
                {
                    IParseTree sibling = priorSiblings[i];
                    if (sibling is IRuleNode)
                    {
                        firstRuleIndex = i;
                        break;
                    }
                }

                for (int i = priorSiblings.Count - 2; i >= 0; i--)
                {
                    IRuleNode sibling = priorSiblings[i] as IRuleNode;
                    if (sibling == null)
                    {
                        continue;
                    }

                    if (i == firstRuleIndex || ParseTrees.ElementStartsLine(sibling))
                    {
                        return(Tuple.Create <IParseTree, int>(sibling, 0));
                    }
                }

                // handle at the parent
                return(null);
            }
Exemple #13
0
        protected override AlignmentRequirements GetAlignmentRequirement(KeyValuePair <RuleContext, CaretReachedException> parseTree, IParseTree targetElement, IParseTree ancestor)
        {
            if (ancestor == targetElement && !(targetElement is ITerminalNode))
            {
                // special handling for predicted tokens that don't actually exist yet
                CaretReachedException ex = parseTree.Value;
                if (ex != null && ex.Transitions != null)
                {
                    bool validTransition = false;
                    bool selfTransition  = false;

                    // examine transitions for predictions that don't actually exist yet
                    foreach (KeyValuePair <ATNConfig, IList <Transition> > entry in ex.Transitions)
                    {
                        if (entry.Value == null)
                        {
                            continue;
                        }

                        foreach (Transition transition in entry.Value)
                        {
                            IntervalSet label = transition.Label;
                            if (label == null)
                            {
                                continue;
                            }

                            bool containsInvalid =
                                label.Contains(GrammarParser.OR) ||
                                label.Contains(GrammarParser.RPAREN) ||
                                label.Contains(GrammarParser.RBRACE) ||
                                label.Contains(GrammarParser.END_ACTION) ||
                                label.Contains(GrammarParser.END_ARG_ACTION) ||
                                label.Contains(GrammarParser.OPTIONS) ||
                                label.Contains(GrammarParser.AT) ||
                                label.Contains(GrammarParser.ASSIGN) ||
                                label.Contains(GrammarParser.SEMI) ||
                                label.Contains(GrammarParser.COMMA) ||
                                label.Contains(GrammarParser.MODE) ||
                                label.Contains(GrammarParser.RARROW) ||
                                label.Contains(GrammarParser.POUND);
                            bool containsInvalidSelf =
                                label.Contains(GrammarParser.LPAREN) ||
                                label.Contains(GrammarParser.BEGIN_ACTION) ||
                                label.Contains(GrammarParser.BEGIN_ARG_ACTION);

                            if (transition is NotSetTransition)
                            {
                                containsInvalid     = !containsInvalid;
                                containsInvalidSelf = !containsInvalidSelf;
                            }

                            validTransition |= !containsInvalid;
                            selfTransition  |= !containsInvalidSelf;
                        }
                    }

                    if (!validTransition)
                    {
                        return(AlignmentRequirements.IgnoreTree);
                    }
                    else if (!selfTransition)
                    {
                        return(AlignmentRequirements.UseAncestor);
                    }
                }
            }

            IRuleNode ruleNode = ancestor as IRuleNode;

            if (ruleNode == null)
            {
                return(AlignmentRequirements.UseAncestor);
            }

            RuleContext ruleContext = ruleNode.RuleContext;

            switch (ruleContext.RuleIndex)
            {
            case GrammarParser.RULE_parserRuleSpec:
                if (((GrammarParser.ParserRuleSpecContext)ruleContext).RULE_REF() == null)
                {
                    return(AlignmentRequirements.UseAncestor);
                }

                return(AlignmentRequirements.PriorSibling);

            case GrammarParser.RULE_lexerRule:
                if (((GrammarParser.LexerRuleContext)ruleContext).TOKEN_REF() == null)
                {
                    return(AlignmentRequirements.UseAncestor);
                }

                return(AlignmentRequirements.PriorSibling);

            case GrammarParser.RULE_ruleAltList:
            case GrammarParser.RULE_lexerAltList:
            case GrammarParser.RULE_altList:
            case GrammarParser.RULE_blockSet:
            case GrammarParser.RULE_lexerBlock:
            case GrammarParser.RULE_block:
            case GrammarParser.RULE_optionsSpec:
            case GrammarParser.RULE_tokensSpec:
            case GrammarParser.RULE_channelsSpec:
            case GrammarParser.RULE_modeSpec:
            case GrammarParser.RULE_delegateGrammars:
            case GrammarParser.RULE_actionBlock:
            case GrammarParser.RULE_elements:
            case GrammarParser.RULE_lexerElements:
            case GrammarParser.RULE_rules:
                //case GrammarParser.RULE_lexerCommands:
                return(AlignmentRequirements.PriorSibling);

            case GrammarParser.RULE_lexerAlt:
                GrammarParser.LexerAltContext lexerAltContext = ParseTrees.GetTypedRuleContext <GrammarParser.LexerAltContext>(ancestor);
                if (lexerAltContext != null && lexerAltContext.lexerCommands() != null && ParseTrees.IsAncestorOf(lexerAltContext.lexerCommands(), targetElement))
                {
                    return(AlignmentRequirements.PriorSibling);
                }
                else
                {
                    return(AlignmentRequirements.UseAncestor);
                }

            case GrammarParser.RULE_labeledAlt:
                if (ParseTrees.GetTerminalNodeType(targetElement) == GrammarParser.POUND)
                {
                    return(AlignmentRequirements.PriorSibling);
                }
                else
                {
                    return(AlignmentRequirements.UseAncestor);
                }

            case GrammarParser.RULE_delegateGrammar:
                return(AlignmentRequirements.None);

            default:
                return(AlignmentRequirements.UseAncestor);
            }
        }