Exemplo n.º 1
0
        private void ParseFeature(PsiBuilder builder)
        {
            var featureMarker = builder.Mark();

            Assertion.Assert(builder.GetTokenType() == GherkinTokenTypes.FEATURE_KEYWORD,
                             "_builder.GetTokenType() == GherkinTokenTypes.FEATURE_KEYWORD");

            int? descMarker   = null;
            bool wasLineBreak = false;

            do
            {
                builder.AdvanceLexer();

                var tokenType = builder.GetTokenType();
                if (tokenType == GherkinTokenTypes.TEXT && descMarker == null)
                {
                    if (wasLineBreak)
                    {
                        descMarker = builder.Mark();
                    }
                }

                if (GherkinTokenTypes.SCENARIOS_KEYWORDS[tokenType] ||
                    tokenType == GherkinTokenTypes.RULE_KEYWORD ||
                    tokenType == GherkinTokenTypes.BACKGROUND_KEYWORD ||
                    tokenType == GherkinTokenTypes.TAG)
                {
                    if (descMarker != null)
                    {
                        builder.DoneBeforeWhitespaces(descMarker.Value, GherkinNodeTypes.FEATURE_HEADER, null);
                        descMarker = null;
                    }

                    ParseFeatureElements(builder);
                }

                wasLineBreak = IsLineBreak(builder);
                if (wasLineBreak)
                {
                    SkipGroupedWhiteSpaces(builder);
                }
            } while (builder.GetTokenType() != GherkinTokenTypes.FEATURE_KEYWORD && !builder.Eof());

            if (descMarker != null)
            {
                builder.DoneBeforeWhitespaces(descMarker.Value, GherkinNodeTypes.FEATURE_HEADER, null);
            }

            builder.DoneBeforeWhitespaces(featureMarker, GherkinNodeTypes.FEATURE, null);
        }
Exemplo n.º 2
0
        private bool ParseHigh(PsiBuilder builder)
        {
            var start = builder.Mark();

            if (!ParseIdent(builder))
            {
                builder.Drop(start);
                return(false);
            }

            if (builder.GetTokenType() == SpringTokenType.HIGH_BINOP)
            {
                AdvanceWithSpaces(builder);
                if (!ParseHigh(builder))
                {
                    builder.Drop(start);
                    return(false);
                }
                builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.HIGH_BINOP, null);
                return(true);
            }

            builder.Drop(start);
            return(true);
        }
Exemplo n.º 3
0
        private bool ParseMedium(PsiBuilder builder)
        {
            var start = builder.Mark();

            if (!ParseHigh(builder))
            {
                builder.Drop(start);
                return(false);
            }

            while (builder.GetTokenType() == SpringTokenType.MEDIUM_BINOP)
            {
                AdvanceWithSpaces(builder);

                if (!ParseHigh(builder))
                {
                    builder.Drop(start);
                    return(false);
                }

                builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.MEDIUM_BINOP, null);
                builder.Precede(start);
            }

            builder.Drop(start);
            return(true);
        }
Exemplo n.º 4
0
        private bool ParseAssign(PsiBuilder builder)
        {
            var start = builder.Mark();

            if (builder.GetTokenType() != SpringTokenType.IDENT)
            {
                builder.Drop(start);
                builder.Error("Missing variable");
                return(false);
            }

            AdvanceWithSpaces(builder);

            if (builder.GetTokenType() != SpringTokenType.ASSIGN)
            {
                builder.Drop(start);
                builder.Error("Missing ':='");
                return(false);
            }

            AdvanceWithSpaces(builder);

            if (!ParseLogic(builder))
            {
                builder.Drop(start);
                return(false);
            }

            builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.ASSIGN, null);
            return(true);
        }
Exemplo n.º 5
0
        private void ParseComments(PsiBuilder builder)
        {
            while (builder.GetTokenType() == GherkinTokenTypes.COMMENT)
            {
                var commentMarker = builder.Mark();
                var commentText   = builder.GetTokenText();
                builder.AdvanceLexer();
                var match = LanguagePattern.Match(commentText);
                if (match.Success)
                {
                    _lang = match.Groups["lang"].Value;
                    builder.DoneBeforeWhitespaces(commentMarker, GherkinNodeTypes.LANGUAGE_COMMENT, _lang);
                }
                else
                {
                    builder.Drop(commentMarker);
                }

                if (builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE ||
                    builder.GetTokenType() == GherkinTokenTypes.NEW_LINE)
                {
                    builder.AdvanceLexer();
                }
            }
        }
Exemplo n.º 6
0
        private static int?ParseRule(PsiBuilder builder, int?ruleMarker)
        {
            if (builder.GetTokenType() == GherkinTokenTypes.RULE_KEYWORD)
            {
                if (ruleMarker != null)
                {
                    builder.DoneBeforeWhitespaces(ruleMarker.Value, GherkinNodeTypes.RULE, null);
                }

                ruleMarker = builder.Mark();
                builder.AdvanceLexer();
                if (builder.GetTokenType() == GherkinTokenTypes.COLON)
                {
                    builder.AdvanceLexer();
                }
                else
                {
                    return(ruleMarker);
                }

                while (builder.GetTokenType() == GherkinTokenTypes.TEXT ||
                       builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE ||
                       builder.GetTokenType() == GherkinTokenTypes.NEW_LINE)
                {
                    builder.AdvanceLexer();
                }
            }

            return(ruleMarker);
        }
Exemplo n.º 7
0
        private bool ParseSeq(PsiBuilder builder)
        {
            var start = builder.Mark();

            if (!ParseStmt(builder))
            {
                builder.Drop(start);
                return(false);
            }

            if (builder.Eof() || builder.GetTokenType() == SpringTokenType.RFBRACKET)
            {
                builder.Drop(start);
                return(true);
            }

            if (!ParseSeq(builder))
            {
                builder.Drop(start);
                return(false);
            }

            builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.SEQ, null);
            return(true);
        }
Exemplo n.º 8
0
        private static void ParseTags(PsiBuilder builder)
        {
            while (builder.GetTokenType() == GherkinTokenTypes.TAG)
            {
                var tagMarker = builder.Mark();
                builder.AdvanceLexer();
                builder.DoneBeforeWhitespaces(tagMarker, GherkinNodeTypes.TAG, null);

                SkipWhitespace(builder);
            }
        }
Exemplo n.º 9
0
        private void ParseStep(PsiBuilder builder)
        {
            var marker      = builder.Mark();
            var keywordText = builder.GetTokenText();

            builder.AdvanceLexer();
            while (builder.GetTokenType() == GherkinTokenTypes.TEXT ||
                   builder.GetTokenType() == GherkinTokenTypes.STEP_PARAMETER_BRACE ||
                   builder.GetTokenType() == GherkinTokenTypes.STEP_PARAMETER_TEXT ||
                   builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE ||
                   builder.GetTokenType() == GherkinTokenTypes.NEW_LINE)
            {
                if (IsLineBreak(builder))
                {
                    break;
                }

                if (!ParseStepParameter(builder))
                {
                    builder.AdvanceLexer();
                }
            }

            SkipGroupedWhiteSpaces(builder);

            var nextToken = builder.GetTokenType(1);

            if (nextToken == GherkinTokenTypes.PIPE)
            {
                builder.AdvanceLexer();
                ParseTable(builder);
            }
            else if (nextToken == GherkinTokenTypes.PYSTRING)
            {
                builder.AdvanceLexer();
                ParsePystring(builder);
            }

            var stepKind          = _keywordProvider.GetStepKind(_lang, keywordText);
            var effectiveStepKind = stepKind;

            if (stepKind == GherkinStepKind.And)
            {
                effectiveStepKind = _lastStepKind;
            }
            else if (stepKind == GherkinStepKind.Given || stepKind == GherkinStepKind.When || stepKind == GherkinStepKind.Then)
            {
                _lastStepKind = effectiveStepKind;
            }
            builder.DoneBeforeWhitespaces(marker, GherkinNodeTypes.STEP, (stepKind, effectiveStepKind));
        }
Exemplo n.º 10
0
        private void ParseScenario(PsiBuilder builder)
        {
            SkipWhitespace(builder);
            var scenarioMarker = builder.Mark();

            ParseTags(builder);

            // scenarios
            var startTokenType = builder.GetTokenType();
            var outline        = startTokenType == GherkinTokenTypes.SCENARIO_OUTLINE_KEYWORD;

            builder.AdvanceLexer();

            while (!AtScenarioEnd(builder))
            {
                SkipWhitespace(builder);
                ParseTags(builder);

                if (ParseStepParameter(builder))
                {
                    continue;
                }

                if (builder.GetTokenType() == GherkinTokenTypes.STEP_KEYWORD)
                {
                    ParseStep(builder);
                }
                else if (builder.GetTokenType() == GherkinTokenTypes.EXAMPLES_KEYWORD)
                {
                    ParseExamplesBlock(builder);
                }
                else
                {
                    builder.AdvanceLexer();
                }
            }

            builder.DoneBeforeWhitespaces(scenarioMarker, outline ? GherkinNodeTypes.SCENARIO_OUTLINE : GherkinNodeTypes.SCENARIO, null);
        }
Exemplo n.º 11
0
        private void ParseFeatureElements(PsiBuilder builder)
        {
            int?ruleMarker = null;

            while (builder.GetTokenType() != GherkinTokenTypes.FEATURE_KEYWORD && !builder.Eof())
            {
                if (builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE ||
                    builder.GetTokenType() == GherkinTokenTypes.NEW_LINE)
                {
                    builder.AdvanceLexer();
                    continue;
                }

                ruleMarker = ParseRule(builder, ruleMarker);
                ParseScenario(builder);
            }

            if (ruleMarker.HasValue)
            {
                builder.DoneBeforeWhitespaces(ruleMarker.Value, GherkinNodeTypes.RULE, null);
            }
        }
Exemplo n.º 12
0
        private static void ParseExamplesBlock(PsiBuilder builder)
        {
            var marker = builder.Mark();

            builder.AdvanceLexer();
            if (builder.GetTokenType() == GherkinTokenTypes.COLON)
            {
                builder.AdvanceLexer();
            }

            while (builder.GetTokenType() == GherkinTokenTypes.TEXT ||
                   builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE ||
                   builder.GetTokenType() == GherkinTokenTypes.NEW_LINE)
            {
                builder.AdvanceLexer();
            }

            if (builder.GetTokenType() == GherkinTokenTypes.PIPE)
            {
                ParseTable(builder);
            }

            builder.DoneBeforeWhitespaces(marker, GherkinNodeTypes.EXAMPLES_BLOCK, null);
        }
Exemplo n.º 13
0
        private bool ParseIdent(PsiBuilder builder)
        {
            var start = builder.Mark();

            if (builder.GetTokenType() == SpringTokenType.READ)
            {
                AdvanceWithSpaces(builder);

                if (builder.GetTokenType() != SpringTokenType.LBRACKET)
                {
                    builder.RollbackTo(start);
                    builder.Error("Missing '('");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (builder.GetTokenType() != SpringTokenType.RBRACKET)
                {
                    builder.RollbackTo(start);
                    builder.Error("Missing ')'");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.READ, null);
                return(true);
            }

            if (builder.GetTokenType() == SpringTokenType.NUMBER)
            {
                AdvanceWithSpaces(builder);
                builder.Done(start, SpringCompositeNodeType.NUMBER, null);
                return(true);
            }

            if (builder.GetTokenType() == SpringTokenType.IDENT)
            {
                AdvanceWithSpaces(builder);
                builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.VARIABLE, null);
                return(true);
            }

            if (builder.GetTokenType() == SpringTokenType.STRING)
            {
                AdvanceWithSpaces(builder);
                builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.STRING, null);
                return(true);
            }

            if (builder.GetTokenType() == SpringTokenType.LBRACKET)
            {
                AdvanceWithSpaces(builder);

                if (!ParseLogic(builder))
                {
                    builder.RollbackTo(start);
                    return(false);
                }

                if (builder.GetTokenType() != SpringTokenType.RBRACKET)
                {
                    builder.RollbackTo(start);
                    builder.Error("Missing ')'");
                    return(false);
                }

                AdvanceWithSpaces(builder);
                builder.Drop(start);
                return(true);
            }

            builder.Drop(start);
            builder.Error("Not ident");
            return(false);
        }
Exemplo n.º 14
0
        private static void ParseTable(PsiBuilder builder)
        {
            var marker         = builder.Mark();
            var rowMarker      = builder.Mark();
            var headerNodeType = GherkinNodeTypes.TABLE_HEADER_ROW;
            int?cellMarker     = null;

            var wasLineBreak      = false;
            var possibleEmptyCell = false;

            while (builder.GetTokenType() == GherkinTokenTypes.PIPE ||
                   builder.GetTokenType() == GherkinTokenTypes.TABLE_CELL ||
                   builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE ||
                   builder.GetTokenType() == GherkinTokenTypes.NEW_LINE)
            {
                var tokenType = builder.GetTokenType();
                if (tokenType == GherkinTokenTypes.TABLE_CELL && cellMarker == null)
                {
                    cellMarker = builder.Mark();
                }
                else if (tokenType != GherkinTokenTypes.TABLE_CELL && cellMarker != null)
                {
                    builder.DoneBeforeWhitespaces(cellMarker.Value, GherkinNodeTypes.TABLE_CELL, null);
                    cellMarker        = null;
                    possibleEmptyCell = false;
                }

                if (tokenType == GherkinTokenTypes.PIPE)
                {
                    if (wasLineBreak)
                    {
                        possibleEmptyCell = true;
                        builder.DoneBeforeWhitespaces(rowMarker, headerNodeType, null);
                        headerNodeType = GherkinNodeTypes.TABLE_ROW;
                        rowMarker      = builder.Mark();
                    }
                    else
                    {
                        if (possibleEmptyCell)
                        {
                            cellMarker = builder.Mark();
                            builder.DoneBeforeWhitespaces(cellMarker.Value, GherkinNodeTypes.TABLE_CELL, null);
                            cellMarker = null;
                        }

                        possibleEmptyCell = true;
                    }
                }

                wasLineBreak = IsLineBreak(builder);
                if (wasLineBreak)
                {
                    SkipGroupedWhiteSpaces(builder);
                }
                builder.AdvanceLexer();
            }

            if (cellMarker.HasValue)
            {
                builder.DoneBeforeWhitespaces(cellMarker.Value, GherkinNodeTypes.TABLE_CELL, null);
            }

            builder.DoneBeforeWhitespaces(rowMarker, headerNodeType, null);
            builder.DoneBeforeWhitespaces(marker, GherkinNodeTypes.TABLE, null);
        }
Exemplo n.º 15
0
 public override void SyntaxError(TextWriter output, IRecognizer recognizer, IToken offendingSymbol,
                                  int line, int charPositionInLine, string msg, RecognitionException e)
 {
     _builder.ResetCurrentLexeme(offendingSymbol.TokenIndex, offendingSymbol.TokenIndex);
     _builder.DoneBeforeWhitespaces(_builder.Mark(), SpringPsiBuilderErrorElement.NODE_TYPE, new ErrorMsgWithLengthAndType(msg, offendingSymbol.Text.Length));
 }
Exemplo n.º 16
0
        private bool ParseStmt(PsiBuilder builder)
        {
            var start = builder.Mark();

            if (builder.GetTokenType() == SpringTokenType.IF)
            {
                AdvanceWithSpaces(builder);

                if (builder.GetTokenType() != SpringTokenType.LBRACKET)
                {
                    builder.Drop(start);
                    builder.Error("Missing '('");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (!ParseLogic(builder))
                {
                    builder.Drop(start);
                    return(false);
                }

                if (builder.GetTokenType() != SpringTokenType.RBRACKET)
                {
                    builder.Drop(start);
                    builder.Error("Missing ')'");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (builder.GetTokenType() != SpringTokenType.LFBRACKET)
                {
                    builder.Drop(start);
                    builder.Error("Missing '{'");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (!ParseSeq(builder))
                {
                    builder.Drop(start);
                    return(false);
                }

                if (builder.GetTokenType() != SpringTokenType.RFBRACKET)
                {
                    builder.Drop(start);
                    builder.Error("Missing '}'");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (builder.GetTokenType() == SpringTokenType.ELSE)
                {
                    AdvanceWithSpaces(builder);

                    if (builder.GetTokenType() != SpringTokenType.LFBRACKET)
                    {
                        builder.Drop(start);
                        builder.Error("Missing '{'");
                        return(false);
                    }

                    AdvanceWithSpaces(builder);

                    if (!ParseSeq(builder))
                    {
                        builder.Drop(start);
                        return(false);
                    }

                    if (builder.GetTokenType() != SpringTokenType.RFBRACKET)
                    {
                        builder.Drop(start);
                        builder.Error("Missing '}'");
                        return(false);
                    }

                    AdvanceWithSpaces(builder);
                }
                builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.IF, null);
                return(true);
            }

            if (builder.GetTokenType() == SpringTokenType.FOR)
            {
                AdvanceWithSpaces(builder);

                if (builder.GetTokenType() != SpringTokenType.LBRACKET)
                {
                    builder.Drop(start);
                    builder.Error("Missing '('");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (!ParseAssign(builder))
                {
                    builder.Drop(start);
                    return(false);
                }

                if (builder.GetTokenType() != SpringTokenType.SEQ)
                {
                    builder.Drop(start);
                    builder.Error("Missing ';'");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (!ParseLogic(builder))
                {
                    builder.Drop(start);
                    return(false);
                }

                if (builder.GetTokenType() != SpringTokenType.SEQ)
                {
                    builder.Drop(start);
                    builder.Error("Missing ';'");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (!ParseAssign(builder))
                {
                    builder.Drop(start);
                    return(false);
                }

                if (builder.GetTokenType() != SpringTokenType.RBRACKET)
                {
                    builder.Drop(start);
                    builder.Error("Missing ')'");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (builder.GetTokenType() != SpringTokenType.LFBRACKET)
                {
                    builder.Drop(start);
                    builder.Error("Missing '{'");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (!ParseSeq(builder))
                {
                    builder.Drop(start);
                    return(false);
                }

                if (builder.GetTokenType() != SpringTokenType.RFBRACKET)
                {
                    builder.Drop(start);
                    builder.Error("Missing '}'");
                    return(false);
                }

                AdvanceWithSpaces(builder);
                builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.FOR, null);
                return(true);
            }

            if (builder.GetTokenType() == SpringTokenType.WRITE)
            {
                AdvanceWithSpaces(builder);

                if (builder.GetTokenType() != SpringTokenType.LBRACKET)
                {
                    builder.RollbackTo(start);
                    builder.Error("Missing '('");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                if (!ParseLogic(builder))
                {
                    builder.Drop(start);
                    return(false);
                }

                if (builder.GetTokenType() != SpringTokenType.RBRACKET)
                {
                    builder.RollbackTo(start);
                    builder.Error("Missing ')'");
                    return(false);
                }

                AdvanceWithSpaces(builder);

                builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.WRITE, null);

                if (builder.GetTokenType() != SpringTokenType.SEQ)
                {
                    builder.Error("Missing ';'");
                    return(false);
                }

                AdvanceWithSpaces(builder);
                return(true);
            }

            if (!ParseAssign(builder))
            {
                builder.Drop(start);
                return(false);
            }

            if (builder.GetTokenType() != SpringTokenType.SEQ)
            {
                builder.Drop(start);
                builder.Error("Missing ';'");
                return(false);
            }

            AdvanceWithSpaces(builder);
            builder.Drop(start);
            return(true);
        }
Exemplo n.º 17
0
        private bool ParseVariable()
        {
            if (builder.GetTokenType() != SpringTokenType.IDENTIFIER)
            {
                return(false);
            }

            var start = builder.Mark();

            AdvanceLexerSkipNonsemantical();

            if (builder.GetTokenType() == SpringTokenType.SQUARE_LBRACE)
            {
                var subsListMark = builder.Mark();
                AdvanceLexerSkipNonsemantical();
                if (!ParseNonemptyList(tt => tt == SpringTokenType.COMMA, ParseArithExpr, "An arithmetic expression expected"))
                {
                    builder.Error("An arithmetic expression expected");
                }

                if (builder.GetTokenType() != SpringTokenType.SQUARE_RBRACE)
                {
                    builder.Error("A closing bracket expected");
                }
                else
                {
                    AdvanceLexerSkipNonsemantical();
                }

                builder.DoneBeforeWhitespaces(subsListMark, SpringCompositeNodeType.SUBSCRIPT_LIST, null);
                builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.SUBSCRIPTED_VAR, null);
            }
            else
            {
                builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.VAR, null);
            }

            return(true);
        }