mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
New Java parser (work in progress)
This commit is contained in:
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.lang.LighterASTNode;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
@@ -190,7 +191,8 @@ public class DeclarationParser {
|
||||
|
||||
final PsiBuilder.Marker declaration = builder.mark();
|
||||
|
||||
final PsiBuilder.Marker modList = parseModifierList(builder);
|
||||
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) {
|
||||
@@ -255,15 +257,14 @@ public class DeclarationParser {
|
||||
}
|
||||
idPos.rollbackTo();
|
||||
if (typeParams == null) {
|
||||
emptyElement(type, JavaElementType.TYPE_PARAMETER_LIST);
|
||||
emptyElement(builder, JavaElementType.TYPE_PARAMETER_LIST);
|
||||
}
|
||||
builder.advanceLexer();
|
||||
if (builder.getTokenType() != JavaTokenType.LPARENTH) {
|
||||
declaration.drop();
|
||||
declaration.rollbackTo();
|
||||
return null;
|
||||
}
|
||||
parseMethodFromLeftParenth(builder, declaration, false);
|
||||
return declaration;
|
||||
return parseMethodFromLeftParenth(builder, declaration, false);
|
||||
}
|
||||
idPos.drop();
|
||||
}
|
||||
@@ -297,7 +298,7 @@ public class DeclarationParser {
|
||||
}
|
||||
|
||||
if (!expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
if (context == Context.CODE_BLOCK /* todo: && modifierList.getFirstChildNode() == null */) {
|
||||
if (context == Context.CODE_BLOCK && modListInfo.second) {
|
||||
declaration.rollbackTo();
|
||||
return null;
|
||||
}
|
||||
@@ -316,8 +317,7 @@ public class DeclarationParser {
|
||||
if (typeParams == null) {
|
||||
emptyElement(type, JavaElementType.TYPE_PARAMETER_LIST);
|
||||
}
|
||||
parseMethodFromLeftParenth(builder, declaration, (context == Context.ANNOTATION_INTERFACE));
|
||||
return declaration;
|
||||
return parseMethodFromLeftParenth(builder, declaration, (context == Context.ANNOTATION_INTERFACE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,14 +335,16 @@ public class DeclarationParser {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiBuilder.Marker parseModifierList(final PsiBuilder builder) {
|
||||
private static Pair<PsiBuilder.Marker, Boolean> parseModifierList(final PsiBuilder builder) {
|
||||
final PsiBuilder.Marker modList = builder.mark();
|
||||
boolean isEmpty = true;
|
||||
|
||||
while (true) {
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
if (tokenType == null) break;
|
||||
if (ElementType.MODIFIER_BIT_SET.contains(tokenType)) {
|
||||
builder.advanceLexer();
|
||||
isEmpty = false;
|
||||
}
|
||||
else if (tokenType == JavaTokenType.AT) {
|
||||
final PsiBuilder.Marker pos = builder.mark();
|
||||
@@ -353,6 +355,7 @@ public class DeclarationParser {
|
||||
break;
|
||||
}
|
||||
parseAnnotation(builder);
|
||||
isEmpty = false;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
@@ -360,12 +363,149 @@ public class DeclarationParser {
|
||||
}
|
||||
|
||||
modList.done(JavaElementType.MODIFIER_LIST);
|
||||
return modList;
|
||||
return Pair.create(modList, isEmpty);
|
||||
}
|
||||
|
||||
private static void parseMethodFromLeftParenth(final PsiBuilder builder, final PsiBuilder.Marker declaration, final boolean anno) {
|
||||
// todo: implement
|
||||
throw new UnsupportedOperationException(builder.toString() + declaration + anno);
|
||||
private static PsiBuilder.Marker parseMethodFromLeftParenth(final PsiBuilder builder, final PsiBuilder.Marker declaration,
|
||||
final boolean anno) {
|
||||
parseParameterList(builder);
|
||||
|
||||
eatBrackets(builder);
|
||||
|
||||
if (areTypeAnnotationsSupported(builder)) {
|
||||
final PsiBuilder.Marker receiver = builder.mark();
|
||||
final PsiBuilder.Marker annotations = parseAnnotations(builder);
|
||||
if (annotations != null) {
|
||||
receiver.done(JavaElementType.METHOD_RECEIVER);
|
||||
}
|
||||
else {
|
||||
receiver.drop();
|
||||
}
|
||||
}
|
||||
|
||||
ReferenceParser.parseReferenceList(builder, JavaTokenType.THROWS_KEYWORD, JavaElementType.THROWS_LIST, JavaTokenType.COMMA);
|
||||
|
||||
if (anno && expect(builder, JavaTokenType.DEFAULT_KEYWORD)) {
|
||||
parseAnnotationValue(builder);
|
||||
}
|
||||
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
if (tokenType == JavaTokenType.SEMICOLON) {
|
||||
builder.advanceLexer();
|
||||
}
|
||||
else if (tokenType == JavaTokenType.LBRACE) {
|
||||
StatementParser.parseCodeBlock(builder);
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.lbrace.or.semicolon"));
|
||||
// todo: special treatment - like in fields (DeclarationParserTest.testMultiLineUnclosed())
|
||||
}
|
||||
|
||||
declaration.done(anno ? JavaElementType.ANNOTATION_METHOD : JavaElementType.METHOD);
|
||||
return declaration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiBuilder.Marker parseParameterList(final PsiBuilder builder) {
|
||||
assert builder.getTokenType() == JavaTokenType.LPARENTH : builder.getTokenType();
|
||||
final PsiBuilder.Marker paramList = builder.mark();
|
||||
builder.advanceLexer();
|
||||
|
||||
PsiBuilder.Marker invalidElements = null;
|
||||
boolean commaExpected = false;
|
||||
int paramCount = 0;
|
||||
while (true) {
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
if (tokenType == null || tokenType == JavaTokenType.RPARENTH) {
|
||||
boolean noLastParam = !commaExpected && paramCount > 0;
|
||||
if (noLastParam) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier.or.type"));
|
||||
}
|
||||
if (!expect(builder, JavaTokenType.RPARENTH)) {
|
||||
if (!noLastParam) {
|
||||
error(builder, JavaErrorMessages.message("expected.rparen"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (commaExpected) {
|
||||
if (builder.getTokenType() == JavaTokenType.COMMA) {
|
||||
commaExpected = false;
|
||||
if (invalidElements != null) {
|
||||
invalidElements.error(JavaErrorMessages.message("expected.parameter"));
|
||||
invalidElements = null;
|
||||
}
|
||||
builder.advanceLexer();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PsiBuilder.Marker param = parseParameter(builder, true);
|
||||
if (param != null) {
|
||||
commaExpected = true;
|
||||
if (invalidElements != null) {
|
||||
invalidElements.errorBefore(JavaErrorMessages.message("expected.comma"), param);
|
||||
invalidElements = null;
|
||||
}
|
||||
paramCount++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalidElements == null) {
|
||||
if (builder.getTokenType() == JavaTokenType.COMMA) {
|
||||
error(builder, JavaErrorMessages.message("expected.parameter"));
|
||||
builder.advanceLexer();
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
invalidElements = builder.mark();
|
||||
}
|
||||
}
|
||||
|
||||
// adding a reference, not simple tokens allows "Browse .." to work well
|
||||
final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, true, false);
|
||||
if (ref == null && builder.getTokenType() != null) {
|
||||
builder.advanceLexer();
|
||||
}
|
||||
}
|
||||
|
||||
if (invalidElements != null) {
|
||||
invalidElements.error(commaExpected ? JavaErrorMessages.message("expected.comma") : JavaErrorMessages.message("expected.parameter"));
|
||||
}
|
||||
|
||||
paramList.done(JavaElementType.PARAMETER_LIST);
|
||||
return paramList;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiBuilder.Marker parseParameter(final PsiBuilder builder, final boolean ellipsis) {
|
||||
final PsiBuilder.Marker param = builder.mark();
|
||||
|
||||
final Pair<PsiBuilder.Marker, Boolean> modListInfo = parseModifierList(builder);
|
||||
final PsiBuilder.Marker type = ellipsis ? ReferenceParser.parseTypeWithEllipsis(builder, true, true) :
|
||||
ReferenceParser.parseType(builder, true, true);
|
||||
|
||||
if (type == null && modListInfo.second) {
|
||||
param.rollbackTo();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.type"));
|
||||
emptyElement(builder, JavaElementType.TYPE);
|
||||
}
|
||||
|
||||
if (expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
eatBrackets(builder);
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
|
||||
param.done(JavaElementType.PARAMETER);
|
||||
return param;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -389,12 +529,8 @@ public class DeclarationParser {
|
||||
boolean eatSemicolon = true;
|
||||
boolean expectSemicolon = true;
|
||||
while (true) {
|
||||
while (expect(builder, JavaTokenType.LBRACKET)) {
|
||||
if (!expect(builder, JavaTokenType.RBRACKET)) {
|
||||
error(builder, JavaErrorMessages.message("expected.rbracket"));
|
||||
expectSemicolon = false;
|
||||
break;
|
||||
}
|
||||
if (!eatBrackets(builder)) {
|
||||
expectSemicolon = false;
|
||||
}
|
||||
|
||||
if (expect(builder, JavaTokenType.EQ)) {
|
||||
@@ -438,6 +574,16 @@ public class DeclarationParser {
|
||||
return declaration;
|
||||
}
|
||||
|
||||
private static boolean eatBrackets(final PsiBuilder builder) {
|
||||
while (expect(builder, JavaTokenType.LBRACKET)) {
|
||||
if (!expect(builder, JavaTokenType.RBRACKET)) {
|
||||
error(builder, JavaErrorMessages.message("expected.rbracket"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiBuilder.Marker parseAnnotations(final PsiBuilder builder) {
|
||||
PsiBuilder.Marker firstAnno = null;
|
||||
@@ -452,6 +598,7 @@ public class DeclarationParser {
|
||||
|
||||
@NotNull
|
||||
private static PsiBuilder.Marker parseAnnotation(final PsiBuilder builder) {
|
||||
assert builder.getTokenType() == JavaTokenType.AT : builder.getTokenType();
|
||||
final PsiBuilder.Marker anno = builder.mark();
|
||||
builder.advanceLexer();
|
||||
|
||||
@@ -570,6 +717,7 @@ public class DeclarationParser {
|
||||
|
||||
@NotNull
|
||||
private static PsiBuilder.Marker parseAnnotationArrayInitializer(final PsiBuilder builder) {
|
||||
assert builder.getTokenType() == JavaTokenType.LBRACE : builder.getTokenType();
|
||||
final PsiBuilder.Marker annoArray = builder.mark();
|
||||
builder.advanceLexer();
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public class JavaParserUtil {
|
||||
@NotNull
|
||||
private static LanguageLevel getLanguageLevel(final PsiBuilder builder) {
|
||||
final LanguageLevel level = builder.getUserData(LANG_LEVEL_KEY);
|
||||
assert level != null;
|
||||
assert level != null : builder;
|
||||
return level;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class JavaParserUtil {
|
||||
}
|
||||
|
||||
public static void emptyElement(final PsiBuilder.Marker before, final IElementType type) {
|
||||
before.precede().done(type);
|
||||
before.precede().doneBefore(type, before);
|
||||
}
|
||||
|
||||
public static PsiBuilder braceMatchingBuilder(final PsiBuilder builder) {
|
||||
|
||||
@@ -278,28 +278,26 @@ public class ReferenceParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expect(builder, JavaTokenType.EXTENDS_KEYWORD)) {
|
||||
parseReferenceList(builder, JavaElementType.EXTENDS_BOUND_LIST, JavaTokenType.AND);
|
||||
}
|
||||
else {
|
||||
emptyElement(builder, JavaElementType.EXTENDS_BOUND_LIST);
|
||||
}
|
||||
parseReferenceList(builder, JavaTokenType.EXTENDS_KEYWORD, JavaElementType.EXTENDS_BOUND_LIST, JavaTokenType.AND);
|
||||
|
||||
param.done(JavaElementType.TYPE_PARAMETER);
|
||||
return param;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiBuilder.Marker parseReferenceList(final PsiBuilder builder, final IElementType type, final IElementType delimiter) {
|
||||
public static PsiBuilder.Marker parseReferenceList(final PsiBuilder builder, final IElementType start,
|
||||
final IElementType type, final IElementType delimiter) {
|
||||
final PsiBuilder.Marker element = builder.mark();
|
||||
|
||||
while (true) {
|
||||
final PsiBuilder.Marker classReference = parseJavaCodeReference(builder, true, true, true);
|
||||
if (classReference == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
if (!expect(builder, delimiter)) {
|
||||
break;
|
||||
if (expect(builder, start)) {
|
||||
while (true) {
|
||||
final PsiBuilder.Marker classReference = parseJavaCodeReference(builder, true, true, true);
|
||||
if (classReference == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
if (!expect(builder, delimiter)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.intellij.lang.java.parser;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@@ -24,6 +26,18 @@ public class StatementParser {
|
||||
|
||||
@Nullable
|
||||
public static PsiBuilder.Marker parseCodeBlock(final PsiBuilder builder) {
|
||||
if (builder.getTokenType() != JavaTokenType.LBRACE) return null;
|
||||
|
||||
final PsiBuilder.Marker codeBlock = builder.mark();
|
||||
builder.advanceLexer();
|
||||
|
||||
// temp
|
||||
if (builder.getTokenType() == JavaTokenType.RBRACE) {
|
||||
builder.advanceLexer();
|
||||
codeBlock.done(JavaElementType.CODE_BLOCK);
|
||||
return codeBlock;
|
||||
}
|
||||
|
||||
// todo: implement
|
||||
throw new UnsupportedOperationException(builder.toString());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
PsiJavaFile:CompletionHack0.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiField:s
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiErrorElement:Unexpected token
|
||||
PsiTypeParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeParameter:X
|
||||
PsiIdentifier:X('X')
|
||||
PsiElement(EXTENDS_BOUND_LIST)
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Unexpected identifier
|
||||
PsiIdentifier:IntelliJIdeaRulezz('IntelliJIdeaRulezz')
|
||||
PsiJavaToken:GT('>')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiTypeElement:String
|
||||
PsiJavaCodeReferenceElement:String
|
||||
PsiIdentifier:String('String')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:s('s')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:""
|
||||
PsiJavaToken:STRING_LITERAL('""')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,31 @@
|
||||
PsiJavaFile:CompletionHack1.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiField:s
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiErrorElement:Unexpected token
|
||||
PsiTypeParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeParameter:X
|
||||
PsiIdentifier:X('X')
|
||||
PsiElement(EXTENDS_BOUND_LIST)
|
||||
<empty list>
|
||||
PsiErrorElement:'>' expected.
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiTypeElement:String
|
||||
PsiJavaCodeReferenceElement:String
|
||||
PsiIdentifier:String('String')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:s('s')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:""
|
||||
PsiJavaToken:STRING_LITERAL('""')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,45 @@
|
||||
PsiJavaFile:Errors.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiModifierList:public static
|
||||
PsiKeyword:public('public')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:static('static')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Unexpected token
|
||||
PsiTypeParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeParameter:error
|
||||
PsiIdentifier:error('error')
|
||||
PsiElement(EXTENDS_BOUND_LIST)
|
||||
<empty list>
|
||||
PsiErrorElement:'>' expected.
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiTypeElement:descr
|
||||
PsiJavaCodeReferenceElement:descr
|
||||
PsiIdentifier:descr('descr')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiErrorElement:Identifier expected
|
||||
<empty list>
|
||||
PsiErrorElement:Unexpected token
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiJavaToken:STRING_LITERAL('"2"')
|
||||
PsiJavaToken:GT('>')
|
||||
PsiField:f1
|
||||
PsiModifierList:protected
|
||||
PsiKeyword:protected('protected')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiTypeElement:int
|
||||
PsiKeyword:int('int')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f1('f1')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:0
|
||||
PsiJavaToken:INTEGER_LITERAL('0')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,91 @@
|
||||
PsiJavaFile:GenericMethod.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:test
|
||||
PsiModifierList:public static
|
||||
PsiKeyword:public('public')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:static('static')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiTypeParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeParameter:E
|
||||
PsiIdentifier:E('E')
|
||||
PsiElement(EXTENDS_BOUND_LIST)
|
||||
<empty list>
|
||||
PsiJavaToken:GT('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:test('test')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiMethod:test1
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeParameter:E
|
||||
PsiIdentifier:E('E')
|
||||
PsiElement(EXTENDS_BOUND_LIST)
|
||||
<empty list>
|
||||
PsiJavaToken:GT('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:test1('test1')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiMethod:test2
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeParameter:E1
|
||||
PsiIdentifier:E1('E1')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EXTENDS_BOUND_LIST)
|
||||
PsiKeyword:extends('extends')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaCodeReferenceElement:Integer
|
||||
PsiIdentifier:Integer('Integer')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:COMMA(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiTypeParameter:E2
|
||||
PsiIdentifier:E2('E2')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EXTENDS_BOUND_LIST)
|
||||
PsiKeyword:extends('extends')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaCodeReferenceElement:Runnable
|
||||
PsiIdentifier:Runnable('Runnable')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:GT('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiTypeElement:String
|
||||
PsiJavaCodeReferenceElement:String
|
||||
PsiIdentifier:String('String')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:test2('test2')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,43 @@
|
||||
PsiJavaFile:GenericMethodErrors.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiErrorElement:Unexpected token
|
||||
PsiTypeParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeParameter:Error
|
||||
PsiIdentifier:Error('Error')
|
||||
PsiElement(EXTENDS_BOUND_LIST)
|
||||
<empty list>
|
||||
PsiErrorElement:'>' expected.
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiTypeElement:sss
|
||||
PsiJavaCodeReferenceElement:sss
|
||||
PsiIdentifier:sss('sss')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiErrorElement:Identifier expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Unexpected token
|
||||
PsiJavaToken:DIV('/')
|
||||
PsiJavaToken:GT('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaCodeReferenceElement:test <error>
|
||||
PsiIdentifier:test('test')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiReferenceParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeElement:error
|
||||
PsiJavaCodeReferenceElement:error
|
||||
PsiIdentifier:error('error')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:GT('>')
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,24 @@
|
||||
PsiJavaFile:MethodNormal0.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,20 @@
|
||||
PsiJavaFile:MethodNormal1.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,21 @@
|
||||
PsiJavaFile:Unclosed0.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiErrorElement:'{' or ';' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,22 @@
|
||||
PsiJavaFile:Unclosed1.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:(
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiErrorElement:')' expected
|
||||
<empty list>
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiErrorElement:'{' or ';' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,37 @@
|
||||
PsiJavaFile:Unclosed2.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiErrorElement:'{' or ';' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiMethod:g
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:g('g')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,29 @@
|
||||
PsiJavaFile:Unclosed3.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:(int a
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiParameter:a
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:int
|
||||
PsiKeyword:int('int')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:a('a')
|
||||
PsiErrorElement:')' expected
|
||||
<empty list>
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiErrorElement:'{' or ';' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,33 @@
|
||||
PsiJavaFile:Unclosed4.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:(int a,,
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiParameter:a
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:int
|
||||
PsiKeyword:int('int')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:a('a')
|
||||
PsiJavaToken:COMMA(',')
|
||||
PsiErrorElement:Parameter expected
|
||||
<empty list>
|
||||
PsiJavaToken:COMMA(',')
|
||||
PsiErrorElement:Identifier or type expected
|
||||
<empty list>
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiErrorElement:'{' or ';' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,30 @@
|
||||
PsiJavaFile:Unclosed5.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:(int a,)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiParameter:a
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:int
|
||||
PsiKeyword:int('int')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:a('a')
|
||||
PsiJavaToken:COMMA(',')
|
||||
PsiErrorElement:Identifier or type expected
|
||||
<empty list>
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,55 @@
|
||||
PsiJavaFile:WildcardParsing.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:x
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:List<? extends B>
|
||||
PsiJavaCodeReferenceElement:List<? extends B>
|
||||
PsiIdentifier:List('List')
|
||||
PsiReferenceParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeElement:? extends B
|
||||
PsiJavaToken:QUEST('?')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:extends('extends')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiTypeElement:B
|
||||
PsiJavaCodeReferenceElement:B
|
||||
PsiIdentifier:B('B')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:GT('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:x('x')
|
||||
PsiParameterList:(Collection<? super B> x)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiParameter:x
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:Collection<? super B>
|
||||
PsiJavaCodeReferenceElement:Collection<? super B>
|
||||
PsiIdentifier:Collection('Collection')
|
||||
PsiReferenceParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeElement:? super B
|
||||
PsiJavaToken:QUEST('?')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:super('super')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiTypeElement:B
|
||||
PsiJavaCodeReferenceElement:B
|
||||
PsiIdentifier:B('B')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:GT('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:x('x')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -4,9 +4,9 @@ PsiJavaFile:TypeParams5.java
|
||||
PsiTypeParameter:T
|
||||
PsiIdentifier:T('T')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:extends('extends')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EXTENDS_BOUND_LIST)
|
||||
PsiKeyword:extends('extends')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaCodeReferenceElement:X
|
||||
PsiIdentifier:X('X')
|
||||
PsiReferenceParameterList
|
||||
|
||||
@@ -4,9 +4,9 @@ PsiJavaFile:TypeParams7.java
|
||||
PsiTypeParameter:T
|
||||
PsiIdentifier:T('T')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:extends('extends')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EXTENDS_BOUND_LIST)
|
||||
PsiKeyword:extends('extends')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaCodeReferenceElement:X
|
||||
PsiIdentifier:X('X')
|
||||
PsiReferenceParameterList
|
||||
|
||||
+17
@@ -44,6 +44,23 @@ public class DeclarationParserTest extends JavaParsingTestCase {
|
||||
public void testMissingInitializerExpression() { doParserTest("{ int field=; }", false, false); }
|
||||
//public void testMultiLineUnclosed() { doParserTest("{ int \n Object o; }", false, false); } // todo: implement
|
||||
|
||||
//public void testMethodNormal0() { doParserTest("{ void f() { } }", false, false); } // todo: parse code block correctly
|
||||
public void testMethodNormal1() { doParserTest("{ void f(); }", false, false); }
|
||||
public void testUnclosed0() { doParserTest("{ void f() }", false, false); }
|
||||
public void testUnclosed1() { doParserTest("{ void f( }", false, false); }
|
||||
public void testUnclosed2() { doParserTest("{ void f()\n void g(); }", false, false); }
|
||||
public void testUnclosed3() { doParserTest("{ void f(int a }", false, false); }
|
||||
public void testUnclosed4() { doParserTest("{ void f(int a,, }", false, false); }
|
||||
public void testUnclosed5() { doParserTest("{ void f(int a,); }", false, false); }
|
||||
public void testGenericMethod() { doParserTest("{ public static <E> test();\n" +
|
||||
" <E> void test1();\n" +
|
||||
" <E1 extends Integer, E2 extends Runnable> String test2(); }", false, false); }
|
||||
public void testGenericMethodErrors() { doParserTest("{ <Error sss /> test <error>(); }", false, false); }
|
||||
public void testErrors() { doParserTest("{ public static <error descr=\"2\">protected int f1 = 0; }", false, false); }
|
||||
public void testCompletionHack0() { doParserTest("{ <X IntelliJIdeaRulezz>\n String s = \"\"; }", false, false); }
|
||||
public void testCompletionHack1() { doParserTest("{ <X\n String s = \"\"; }", false, false); }
|
||||
public void testWildcardParsing() { doParserTest("{ List<? extends B> x(Collection<? super B> x); }", false, false); }
|
||||
|
||||
private void doParserTest(final String text, final boolean isAnnotation, final boolean isEnum) {
|
||||
doParserTest(text, new Parser() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
|
||||
Reference in New Issue
Block a user