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;
}
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;
}
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;
}
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);
}
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;
}
Aggregations