Search in sources :

Example 6 with ILazyParseableElementType

use of com.intellij.psi.tree.ILazyParseableElementType in project intellij-community by JetBrains.

the class StatementParser method parseStatement.

@Nullable
public PsiBuilder.Marker parseStatement(final PsiBuilder builder) {
    final IElementType tokenType = builder.getTokenType();
    if (tokenType == JavaTokenType.IF_KEYWORD) {
        return parseIfStatement(builder);
    } else if (tokenType == JavaTokenType.WHILE_KEYWORD) {
        return parseWhileStatement(builder);
    } else if (tokenType == JavaTokenType.FOR_KEYWORD) {
        return parseForStatement(builder);
    } else if (tokenType == JavaTokenType.DO_KEYWORD) {
        return parseDoWhileStatement(builder);
    } else if (tokenType == JavaTokenType.SWITCH_KEYWORD) {
        return parseSwitchStatement(builder);
    } else if (tokenType == JavaTokenType.CASE_KEYWORD || tokenType == JavaTokenType.DEFAULT_KEYWORD) {
        return parseSwitchLabelStatement(builder);
    } else if (tokenType == JavaTokenType.BREAK_KEYWORD) {
        return parseBreakStatement(builder);
    } else if (tokenType == JavaTokenType.CONTINUE_KEYWORD) {
        return parseContinueStatement(builder);
    } else if (tokenType == JavaTokenType.RETURN_KEYWORD) {
        return parseReturnStatement(builder);
    } else if (tokenType == JavaTokenType.THROW_KEYWORD) {
        return parseThrowStatement(builder);
    } else if (tokenType == JavaTokenType.SYNCHRONIZED_KEYWORD) {
        return parseSynchronizedStatement(builder);
    } else if (tokenType == JavaTokenType.TRY_KEYWORD) {
        return parseTryStatement(builder);
    } else if (tokenType == JavaTokenType.ASSERT_KEYWORD) {
        return parseAssertStatement(builder);
    } else if (tokenType == JavaTokenType.LBRACE) {
        return parseBlockStatement(builder);
    } else if (tokenType instanceof ILazyParseableElementType) {
        builder.advanceLexer();
        return null;
    } else if (tokenType == JavaTokenType.SEMICOLON) {
        final PsiBuilder.Marker empty = builder.mark();
        builder.advanceLexer();
        done(empty, JavaElementType.EMPTY_STATEMENT);
        return empty;
    } else if (tokenType == JavaTokenType.IDENTIFIER || tokenType == JavaTokenType.AT) {
        final PsiBuilder.Marker refPos = builder.mark();
        myParser.getDeclarationParser().parseAnnotations(builder);
        skipQualifiedName(builder);
        final IElementType suspectedLT = builder.getTokenType(), next = builder.lookAhead(1);
        refPos.rollbackTo();
        if (suspectedLT == JavaTokenType.LT || suspectedLT == JavaTokenType.DOT && next == JavaTokenType.AT) {
            final PsiBuilder.Marker declStatement = builder.mark();
            final PsiBuilder.Marker decl = myParser.getDeclarationParser().parse(builder, DeclarationParser.Context.CODE_BLOCK);
            if (decl == null) {
                PsiBuilder.Marker marker = myParser.getReferenceParser().parseType(builder, 0);
                error(builder, JavaErrorMessages.message("expected.identifier"));
                if (marker == null)
                    builder.advanceLexer();
            }
            done(declStatement, JavaElementType.DECLARATION_STATEMENT);
            return declStatement;
        }
    }
    final PsiBuilder.Marker pos = builder.mark();
    final PsiBuilder.Marker expr = myParser.getExpressionParser().parse(builder);
    if (expr != null) {
        int count = 1;
        final PsiBuilder.Marker list = expr.precede();
        final PsiBuilder.Marker statement = list.precede();
        while (builder.getTokenType() == JavaTokenType.COMMA) {
            final PsiBuilder.Marker commaPos = builder.mark();
            builder.advanceLexer();
            final PsiBuilder.Marker expr1 = myParser.getExpressionParser().parse(builder);
            if (expr1 == null) {
                commaPos.rollbackTo();
                break;
            }
            commaPos.drop();
            count++;
        }
        if (count > 1) {
            pos.drop();
            done(list, JavaElementType.EXPRESSION_LIST);
            semicolon(builder);
            done(statement, JavaElementType.EXPRESSION_LIST_STATEMENT);
            return statement;
        }
        if (exprType(expr) != JavaElementType.REFERENCE_EXPRESSION) {
            drop(list, pos);
            semicolon(builder);
            done(statement, JavaElementType.EXPRESSION_STATEMENT);
            return statement;
        }
        pos.rollbackTo();
    } else {
        pos.drop();
    }
    final PsiBuilder.Marker decl = myParser.getDeclarationParser().parse(builder, DeclarationParser.Context.CODE_BLOCK);
    if (decl != null) {
        final PsiBuilder.Marker statement = decl.precede();
        done(statement, JavaElementType.DECLARATION_STATEMENT);
        return statement;
    }
    if (builder.getTokenType() == JavaTokenType.IDENTIFIER && builder.lookAhead(1) == JavaTokenType.COLON) {
        final PsiBuilder.Marker statement = builder.mark();
        advance(builder, 2);
        parseStatement(builder);
        done(statement, JavaElementType.LABELED_STATEMENT);
        return statement;
    }
    if (expr != null) {
        final PsiBuilder.Marker statement = builder.mark();
        myParser.getExpressionParser().parse(builder);
        semicolon(builder);
        done(statement, JavaElementType.EXPRESSION_STATEMENT);
        return statement;
    }
    return null;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) ILazyParseableElementType(com.intellij.psi.tree.ILazyParseableElementType) PsiBuilder(com.intellij.lang.PsiBuilder) Nullable(org.jetbrains.annotations.Nullable)

Example 7 with ILazyParseableElementType

use of com.intellij.psi.tree.ILazyParseableElementType in project intellij-community by JetBrains.

the class HtmlParsing method parseTag.

private void parseTag() {
    assert token() == XmlTokenType.XML_START_TAG_START : "Tag start expected";
    String originalTagName;
    PsiBuilder.Marker xmlText = null;
    while (!eof()) {
        final IElementType tt = token();
        if (tt == XmlTokenType.XML_START_TAG_START) {
            xmlText = terminateText(xmlText);
            final PsiBuilder.Marker tag = mark();
            // Start tag header
            advance();
            if (token() != XmlTokenType.XML_NAME) {
                error(XmlErrorMessages.message("xml.parsing.tag.name.expected"));
                originalTagName = "";
            } else {
                originalTagName = myBuilder.getTokenText();
                advance();
            }
            String tagName = StringUtil.toLowerCase(originalTagName);
            while (childTerminatesParentInStack(tagName)) {
                PsiBuilder.Marker top = closeTag();
                top.doneBefore(XmlElementType.HTML_TAG, tag);
            }
            myTagMarkersStack.push(tag);
            myTagNamesStack.push(tagName);
            myOriginalTagNamesStack.push(originalTagName);
            parseHeader(tagName);
            if (token() == XmlTokenType.XML_EMPTY_ELEMENT_END) {
                advance();
                doneTag(tag);
                continue;
            }
            if (token() == XmlTokenType.XML_TAG_END) {
                advance();
            } else {
                error(XmlErrorMessages.message("tag.start.is.not.closed"));
                doneTag(tag);
                continue;
            }
            if (HtmlUtil.isSingleHtmlTagL(tagName)) {
                final PsiBuilder.Marker footer = mark();
                if (token() == XmlTokenType.XML_END_TAG_START) {
                    advance();
                    if (token() == XmlTokenType.XML_NAME) {
                        if (tagName.equalsIgnoreCase(myBuilder.getTokenText())) {
                            advance();
                            footer.drop();
                            if (token() == XmlTokenType.XML_TAG_END) {
                                advance();
                            }
                            doneTag(tag);
                            continue;
                        }
                    }
                }
                footer.rollbackTo();
                doneTag(tag);
            }
        } else if (tt == XmlTokenType.XML_PI_START) {
            xmlText = terminateText(xmlText);
            parseProcessingInstruction();
        } else if (tt == XmlTokenType.XML_ENTITY_REF_TOKEN || tt == XmlTokenType.XML_CHAR_ENTITY_REF) {
            xmlText = startText(xmlText);
            parseReference();
        } else if (tt == XmlTokenType.XML_CDATA_START) {
            xmlText = startText(xmlText);
            parseCData();
        } else if (tt == XmlTokenType.XML_COMMENT_START) {
            xmlText = startText(xmlText);
            parseComment();
        } else if (tt == XmlTokenType.XML_BAD_CHARACTER) {
            xmlText = startText(xmlText);
            final PsiBuilder.Marker error = mark();
            advance();
            error.error(XmlErrorMessages.message("unescaped.ampersand.or.nonterminated.character.entity.reference"));
        } else if (tt instanceof ICustomParsingType || tt instanceof ILazyParseableElementType) {
            xmlText = terminateText(xmlText);
            advance();
        } else if (token() == XmlTokenType.XML_END_TAG_START) {
            xmlText = terminateText(xmlText);
            final PsiBuilder.Marker footer = mark();
            advance();
            if (token() == XmlTokenType.XML_NAME) {
                String endName = StringUtil.toLowerCase(myBuilder.getTokenText());
                final String parentTagName = !myTagNamesStack.isEmpty() ? myTagNamesStack.peek() : "";
                if (!parentTagName.equals(endName) && !endName.endsWith(COMPLETION_NAME)) {
                    final boolean isOptionalTagEnd = HtmlUtil.isOptionalEndForHtmlTagL(parentTagName);
                    final boolean hasChancesToMatch = HtmlUtil.isOptionalEndForHtmlTagL(endName) ? childTerminatesParentInStack(endName) : myTagNamesStack.contains(endName);
                    if (hasChancesToMatch) {
                        footer.rollbackTo();
                        if (isOptionalTagEnd) {
                            doneTag(myTagMarkersStack.peek());
                        } else {
                            error(XmlErrorMessages.message("named.element.is.not.closed", myOriginalTagNamesStack.peek()));
                            doneTag(myTagMarkersStack.peek());
                        }
                        continue;
                    } else {
                        advance();
                        if (token() == XmlTokenType.XML_TAG_END)
                            advance();
                        footer.error(XmlErrorMessages.message("xml.parsing.closing.tag.matches.nothing"));
                        continue;
                    }
                }
                advance();
                while (token() != XmlTokenType.XML_TAG_END && token() != XmlTokenType.XML_START_TAG_START && token() != XmlTokenType.XML_END_TAG_START && !eof()) {
                    error(XmlErrorMessages.message("xml.parsing.unexpected.token"));
                    advance();
                }
            } else {
                error(XmlErrorMessages.message("xml.parsing.closing.tag.name.missing"));
            }
            footer.drop();
            if (token() == XmlTokenType.XML_TAG_END) {
                advance();
            } else {
                error(XmlErrorMessages.message("xml.parsing.closing.tag.is.not.done"));
            }
            if (hasTags())
                doneTag(myTagMarkersStack.peek());
        } else if ((token() == XmlTokenType.XML_REAL_WHITE_SPACE || token() == XmlTokenType.XML_DATA_CHARACTERS) && !hasTags()) {
            xmlText = terminateText(xmlText);
            advance();
        } else {
            xmlText = startText(xmlText);
            advance();
        }
    }
    terminateText(xmlText);
    while (hasTags()) {
        final String tagName = myTagNamesStack.peek();
        if (!HtmlUtil.isOptionalEndForHtmlTagL(tagName) && !"html".equals(tagName) && !"body".equals(tagName)) {
            error(XmlErrorMessages.message("named.element.is.not.closed", myOriginalTagNamesStack.peek()));
        }
        doneTag(myTagMarkersStack.peek());
    }
}
Also used : IElementType(com.intellij.psi.tree.IElementType) ILazyParseableElementType(com.intellij.psi.tree.ILazyParseableElementType) PsiBuilder(com.intellij.lang.PsiBuilder) ICustomParsingType(com.intellij.psi.tree.ICustomParsingType)

Aggregations

ILazyParseableElementType (com.intellij.psi.tree.ILazyParseableElementType)7 IElementType (com.intellij.psi.tree.IElementType)6 PsiBuilder (com.intellij.lang.PsiBuilder)4 ICustomParsingType (com.intellij.psi.tree.ICustomParsingType)2 Nullable (org.jetbrains.annotations.Nullable)2 Language (com.intellij.lang.Language)1 EditorEx (com.intellij.openapi.editor.ex.EditorEx)1 HighlighterIteratorWrapper (com.intellij.openapi.editor.ex.util.HighlighterIteratorWrapper)1 LexerEditorHighlighter (com.intellij.openapi.editor.ex.util.LexerEditorHighlighter)1 SyntaxHighlighter (com.intellij.openapi.fileTypes.SyntaxHighlighter)1 TextRange (com.intellij.openapi.util.TextRange)1 PsiElement (com.intellij.psi.PsiElement)1 IFileElementType (com.intellij.psi.tree.IFileElementType)1 LightweightHint (com.intellij.ui.LightweightHint)1 NotNull (org.jetbrains.annotations.NotNull)1