Search in sources :

Example 26 with PsiBuilder

use of com.intellij.lang.PsiBuilder in project intellij-community by JetBrains.

the class DeclarationParser method parseListElement.

@Nullable
private PsiBuilder.Marker parseListElement(PsiBuilder builder, boolean typed, boolean ellipsis, boolean disjunctiveType, boolean resource) {
    PsiBuilder.Marker param = builder.mark();
    Pair<PsiBuilder.Marker, Boolean> modListInfo = parseModifierList(builder);
    ReferenceParser.TypeInfo typeInfo = null;
    if (typed) {
        int flags = ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD;
        if (ellipsis)
            flags |= ReferenceParser.ELLIPSIS;
        if (disjunctiveType)
            flags |= ReferenceParser.DISJUNCTIONS;
        typeInfo = myParser.getReferenceParser().parseTypeInfo(builder, flags);
        if (typeInfo == null) {
            if (Boolean.TRUE.equals(modListInfo.second)) {
                param.rollbackTo();
                return null;
            } else {
                error(builder, JavaErrorMessages.message("expected.type"));
                emptyElement(builder, JavaElementType.TYPE);
            }
        }
    }
    if (typed) {
        IElementType tokenType = builder.getTokenType();
        if (tokenType == JavaTokenType.THIS_KEYWORD || tokenType == JavaTokenType.IDENTIFIER && builder.lookAhead(1) == JavaTokenType.DOT) {
            PsiBuilder.Marker mark = builder.mark();
            PsiBuilder.Marker expr = myParser.getExpressionParser().parse(builder);
            if (expr != null && exprType(expr) == JavaElementType.THIS_EXPRESSION) {
                mark.drop();
                done(param, JavaElementType.RECEIVER_PARAMETER);
                return param;
            }
            mark.rollbackTo();
        }
    }
    if (expect(builder, JavaTokenType.IDENTIFIER)) {
        if (!resource) {
            eatBrackets(builder, typeInfo != null && typeInfo.isVarArg ? "expected.rparen" : null);
            done(param, JavaElementType.PARAMETER);
            return param;
        }
    } else {
        error(builder, JavaErrorMessages.message("expected.identifier"));
        param.drop();
        return modListInfo.first;
    }
    if (expectOrError(builder, JavaTokenType.EQ, "expected.eq")) {
        if (myParser.getExpressionParser().parse(builder) == null) {
            error(builder, JavaErrorMessages.message("expected.expression"));
        }
    }
    done(param, JavaElementType.RESOURCE_VARIABLE);
    return param;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) PsiBuilder(com.intellij.lang.PsiBuilder) Nullable(org.jetbrains.annotations.Nullable)

Example 27 with PsiBuilder

use of com.intellij.lang.PsiBuilder in project intellij-community by JetBrains.

the class DeclarationParser method parseFieldOrLocalVariable.

@Nullable
private PsiBuilder.Marker parseFieldOrLocalVariable(PsiBuilder builder, PsiBuilder.Marker declaration, int declarationStart, Context context) {
    final IElementType varType;
    if (context == Context.CLASS || context == Context.ANNOTATION_INTERFACE) {
        varType = JavaElementType.FIELD;
    } else if (context == Context.CODE_BLOCK) {
        varType = JavaElementType.LOCAL_VARIABLE;
    } else {
        declaration.drop();
        assert false : "Unexpected context: " + context;
        return null;
    }
    PsiBuilder.Marker variable = declaration;
    boolean unclosed = false;
    boolean eatSemicolon = true;
    boolean shouldRollback;
    boolean openMarker = true;
    while (true) {
        shouldRollback = true;
        if (!eatBrackets(builder, null)) {
            unclosed = true;
        }
        if (expect(builder, JavaTokenType.EQ)) {
            final PsiBuilder.Marker expr = myParser.getExpressionParser().parse(builder);
            if (expr != null) {
                shouldRollback = false;
            } else {
                error(builder, JavaErrorMessages.message("expected.expression"));
                unclosed = true;
                break;
            }
        }
        if (builder.getTokenType() != JavaTokenType.COMMA)
            break;
        done(variable, varType);
        builder.advanceLexer();
        if (builder.getTokenType() != JavaTokenType.IDENTIFIER) {
            error(builder, JavaErrorMessages.message("expected.identifier"));
            unclosed = true;
            eatSemicolon = false;
            openMarker = false;
            break;
        }
        variable = builder.mark();
        builder.advanceLexer();
    }
    if (builder.getTokenType() == JavaTokenType.SEMICOLON && eatSemicolon) {
        builder.advanceLexer();
    } else {
        // special treatment (see DeclarationParserTest.testMultiLineUnclosed())
        if (!builder.eof() && shouldRollback) {
            final CharSequence text = builder.getOriginalText();
            final int spaceEnd = builder.getCurrentOffset();
            final int spaceStart = CharArrayUtil.shiftBackward(text, spaceEnd - 1, WHITESPACES);
            final int lineStart = CharArrayUtil.shiftBackwardUntil(text, spaceEnd, LINE_ENDS);
            if (declarationStart < lineStart && lineStart < spaceStart) {
                final int newBufferEnd = CharArrayUtil.shiftForward(text, lineStart, WHITESPACES);
                declaration.rollbackTo();
                return parse(stoppingBuilder(builder, newBufferEnd), context);
            }
        }
        if (!unclosed) {
            error(builder, JavaErrorMessages.message("expected.semicolon"));
        }
    }
    if (openMarker) {
        done(variable, varType);
    }
    return declaration;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) PsiBuilder(com.intellij.lang.PsiBuilder) Nullable(org.jetbrains.annotations.Nullable)

Example 28 with PsiBuilder

use of com.intellij.lang.PsiBuilder in project intellij-community by JetBrains.

the class DeclarationParser method parseClassFromKeyword.

@Nullable
private PsiBuilder.Marker parseClassFromKeyword(PsiBuilder builder, PsiBuilder.Marker declaration, boolean isAnnotation, Context context) {
    final IElementType keywordTokenType = builder.getTokenType();
    assert ElementType.CLASS_KEYWORD_BIT_SET.contains(keywordTokenType) : keywordTokenType;
    builder.advanceLexer();
    final boolean isEnum = (keywordTokenType == JavaTokenType.ENUM_KEYWORD);
    if (!expect(builder, JavaTokenType.IDENTIFIER)) {
        error(builder, JavaErrorMessages.message("expected.identifier"));
        declaration.drop();
        return null;
    }
    final ReferenceParser refParser = myParser.getReferenceParser();
    refParser.parseTypeParameters(builder);
    refParser.parseReferenceList(builder, JavaTokenType.EXTENDS_KEYWORD, JavaElementType.EXTENDS_LIST, JavaTokenType.COMMA);
    refParser.parseReferenceList(builder, JavaTokenType.IMPLEMENTS_KEYWORD, JavaElementType.IMPLEMENTS_LIST, JavaTokenType.COMMA);
    //noinspection Duplicates
    if (builder.getTokenType() != JavaTokenType.LBRACE) {
        final PsiBuilder.Marker error = builder.mark();
        while (BEFORE_LBRACE_ELEMENTS_SET.contains(builder.getTokenType())) {
            builder.advanceLexer();
        }
        error.error(JavaErrorMessages.message("expected.lbrace"));
    }
    if (builder.getTokenType() == JavaTokenType.LBRACE) {
        parseClassBodyWithBraces(builder, isAnnotation, isEnum);
    }
    if (context == Context.FILE) {
        boolean declarationsAfterEnd = false;
        while (builder.getTokenType() != null && builder.getTokenType() != JavaTokenType.RBRACE) {
            final PsiBuilder.Marker position = builder.mark();
            final PsiBuilder.Marker extra = parse(builder, Context.CLASS);
            if (extra != null && AFTER_END_DECLARATION_SET.contains(exprType(extra))) {
                if (!declarationsAfterEnd) {
                    error(builder, JavaErrorMessages.message("expected.class.or.interface"), extra);
                }
                declarationsAfterEnd = true;
                position.drop();
            } else {
                position.rollbackTo();
                break;
            }
        }
        if (declarationsAfterEnd) {
            expectOrError(builder, JavaTokenType.RBRACE, "expected.rbrace");
        }
    }
    done(declaration, JavaElementType.CLASS);
    return declaration;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) PsiBuilder(com.intellij.lang.PsiBuilder) Nullable(org.jetbrains.annotations.Nullable)

Example 29 with PsiBuilder

use of com.intellij.lang.PsiBuilder in project intellij-community by JetBrains.

the class DeclarationParser method parse.

@Nullable
public PsiBuilder.Marker parse(final PsiBuilder builder, final Context context) {
    final IElementType tokenType = builder.getTokenType();
    if (tokenType == null)
        return null;
    if (tokenType == JavaTokenType.LBRACE) {
        if (context == Context.FILE || context == Context.CODE_BLOCK)
            return null;
    } else if (tokenType == JavaTokenType.IDENTIFIER || ElementType.PRIMITIVE_TYPE_BIT_SET.contains(tokenType)) {
        if (context == Context.FILE)
            return null;
    } else if (tokenType instanceof ILazyParseableElementType) {
        builder.advanceLexer();
        return null;
    } else if (!ElementType.MODIFIER_BIT_SET.contains(tokenType) && !ElementType.CLASS_KEYWORD_BIT_SET.contains(tokenType) && tokenType != JavaTokenType.AT && (context == Context.CODE_BLOCK || tokenType != JavaTokenType.LT)) {
        return null;
    }
    final PsiBuilder.Marker declaration = builder.mark();
    final int declarationStart = builder.getCurrentOffset();
    final Pair<PsiBuilder.Marker, Boolean> modListInfo = parseModifierList(builder);
    final PsiBuilder.Marker modList = modListInfo.first;
    if (expect(builder, JavaTokenType.AT)) {
        if (builder.getTokenType() == JavaTokenType.INTERFACE_KEYWORD) {
            final PsiBuilder.Marker result = parseClassFromKeyword(builder, declaration, true, context);
            return result != null ? result : modList;
        } else {
            declaration.rollbackTo();
            return null;
        }
    } else if (ElementType.CLASS_KEYWORD_BIT_SET.contains(builder.getTokenType())) {
        final PsiBuilder.Marker result = parseClassFromKeyword(builder, declaration, false, context);
        return result != null ? result : modList;
    }
    PsiBuilder.Marker typeParams = null;
    if (builder.getTokenType() == JavaTokenType.LT) {
        typeParams = myParser.getReferenceParser().parseTypeParameters(builder);
    }
    if (context == Context.FILE) {
        error(builder, JavaErrorMessages.message("expected.class.or.interface"), typeParams);
        declaration.drop();
        return modList;
    }
    if (builder.getTokenType() == JavaTokenType.LBRACE) {
        if (context == Context.CODE_BLOCK) {
            error(builder, JavaErrorMessages.message("expected.identifier.or.type"), typeParams);
            declaration.drop();
            return modList;
        }
        PsiBuilder.Marker codeBlock = myParser.getStatementParser().parseCodeBlock(builder);
        assert codeBlock != null : builder.getOriginalText();
        if (typeParams != null) {
            PsiBuilder.Marker error = typeParams.precede();
            error.errorBefore(JavaErrorMessages.message("unexpected.token"), codeBlock);
        }
        done(declaration, JavaElementType.CLASS_INITIALIZER);
        return declaration;
    }
    PsiBuilder.Marker type = null;
    if (TYPE_START.contains(builder.getTokenType())) {
        PsiBuilder.Marker pos = builder.mark();
        type = myParser.getReferenceParser().parseType(builder, ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD);
        if (type == null) {
            pos.rollbackTo();
        } else if (builder.getTokenType() == JavaTokenType.LPARENTH) {
            // constructor
            if (context == Context.CODE_BLOCK) {
                declaration.rollbackTo();
                return null;
            }
            pos.rollbackTo();
            if (typeParams == null) {
                emptyElement(builder, JavaElementType.TYPE_PARAMETER_LIST);
            }
            parseAnnotations(builder);
            if (!expect(builder, JavaTokenType.IDENTIFIER)) {
                PsiBuilder.Marker primitive = builder.mark();
                builder.advanceLexer();
                primitive.error(JavaErrorMessages.message("expected.identifier"));
            }
            if (builder.getTokenType() == JavaTokenType.LPARENTH) {
                return parseMethodFromLeftParenth(builder, declaration, false, true);
            } else {
                declaration.rollbackTo();
                return null;
            }
        } else {
            pos.drop();
        }
    }
    if (type == null) {
        PsiBuilder.Marker error = typeParams != null ? typeParams.precede() : builder.mark();
        error.error(JavaErrorMessages.message("expected.identifier.or.type"));
        declaration.drop();
        return modList;
    }
    if (!expect(builder, JavaTokenType.IDENTIFIER)) {
        if ((context == Context.CODE_BLOCK) && Boolean.TRUE.equals(modListInfo.second)) {
            declaration.rollbackTo();
            return null;
        } else {
            if (typeParams != null) {
                typeParams.precede().errorBefore(JavaErrorMessages.message("unexpected.token"), type);
            }
            builder.error(JavaErrorMessages.message("expected.identifier"));
            declaration.drop();
            return modList;
        }
    }
    if (builder.getTokenType() == JavaTokenType.LPARENTH) {
        if (context == Context.CLASS || context == Context.ANNOTATION_INTERFACE) {
            // method
            if (typeParams == null) {
                emptyElement(type, JavaElementType.TYPE_PARAMETER_LIST);
            }
            return parseMethodFromLeftParenth(builder, declaration, (context == Context.ANNOTATION_INTERFACE), false);
        }
    }
    if (typeParams != null) {
        typeParams.precede().errorBefore(JavaErrorMessages.message("unexpected.token"), type);
    }
    return parseFieldOrLocalVariable(builder, declaration, declarationStart, context);
}
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 30 with PsiBuilder

use of com.intellij.lang.PsiBuilder in project intellij-community by JetBrains.

the class DeclarationParser method doParseAnnotationValue.

@Nullable
private PsiBuilder.Marker doParseAnnotationValue(PsiBuilder builder) {
    PsiBuilder.Marker result;
    final IElementType tokenType = builder.getTokenType();
    if (tokenType == JavaTokenType.AT) {
        result = parseAnnotation(builder);
    } else if (tokenType == JavaTokenType.LBRACE) {
        result = parseAnnotationArrayInitializer(builder);
    } else {
        result = myParser.getExpressionParser().parseConditional(builder);
    }
    return result;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) PsiBuilder(com.intellij.lang.PsiBuilder) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

PsiBuilder (com.intellij.lang.PsiBuilder)104 IElementType (com.intellij.psi.tree.IElementType)78 Nullable (org.jetbrains.annotations.Nullable)18 NotNull (org.jetbrains.annotations.NotNull)16 Project (com.intellij.openapi.project.Project)5 GroovyElementType (org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType)5 Language (com.intellij.lang.Language)3 ASTNode (com.intellij.lang.ASTNode)2 ILazyParseableElementType (com.intellij.psi.tree.ILazyParseableElementType)2 ParsingContext (com.jetbrains.python.parsing.ParsingContext)2 StatementParsing (com.jetbrains.python.parsing.StatementParsing)2 ParserDefinition (com.intellij.lang.ParserDefinition)1 HtmlParsing (com.intellij.lang.html.HtmlParsing)1 Lexer (com.intellij.lexer.Lexer)1 VirtualFile (com.intellij.openapi.vfs.VirtualFile)1 PsiElement (com.intellij.psi.PsiElement)1 PsiFile (com.intellij.psi.PsiFile)1 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)1 SmartList (com.intellij.util.SmartList)1 Stack (com.intellij.util.containers.Stack)1