IDEA-123111 (qualified super parsing fixed)

This commit is contained in:
Roman Shevchenko
2015-06-18 12:12:42 +03:00
parent 1914f8ac06
commit 8dc9a98de3
5 changed files with 46 additions and 51 deletions
@@ -315,11 +315,10 @@ public class ExpressionParser {
return operand;
}
private enum BreakPoint {P1, P2, P3, P4}
private enum BreakPoint {P1, P2, P4}
// todo[r.sh] make 'this', 'super' and 'class' reference expressions
@Nullable
private PsiBuilder.Marker parsePrimary(final PsiBuilder builder, @Nullable final BreakPoint breakPoint, final int breakOffset) {
private PsiBuilder.Marker parsePrimary(PsiBuilder builder, @Nullable BreakPoint breakPoint, int breakOffset) {
PsiBuilder.Marker startMarker = builder.mark();
PsiBuilder.Marker expr = parsePrimaryExpressionStart(builder);
@@ -365,6 +364,14 @@ public class ExpressionParser {
dotPos.drop();
expr = parseNew(builder, expr);
}
else if (dotTokenType == JavaTokenType.SUPER_KEYWORD && builder.lookAhead(1) == JavaTokenType.LPARENTH) {
dotPos.drop();
PsiBuilder.Marker refExpr = expr.precede();
builder.mark().done(JavaElementType.REFERENCE_PARAMETER_LIST);
builder.advanceLexer();
refExpr.done(JavaElementType.REFERENCE_EXPRESSION);
expr = refExpr;
}
else if (THIS_OR_SUPER.contains(dotTokenType) && exprType(expr) == JavaElementType.REFERENCE_EXPRESSION) {
if (breakPoint == BreakPoint.P2 && builder.getCurrentOffset() == breakOffset) {
dotPos.rollbackTo();
@@ -372,11 +379,11 @@ public class ExpressionParser {
return expr;
}
final PsiBuilder.Marker copy = startMarker.precede();
final int offset = builder.getCurrentOffset();
PsiBuilder.Marker copy = startMarker.precede();
int offset = builder.getCurrentOffset();
startMarker.rollbackTo();
final PsiBuilder.Marker ref = myParser.getReferenceParser().parseJavaCodeReference(builder, false, true, false, false);
PsiBuilder.Marker ref = myParser.getReferenceParser().parseJavaCodeReference(builder, false, true, false, false);
if (ref == null || builder.getTokenType() != JavaTokenType.DOT || builder.getCurrentOffset() != dotOffset) {
copy.rollbackTo();
return parsePrimary(builder, BreakPoint.P2, offset);
@@ -393,17 +400,10 @@ public class ExpressionParser {
expr = ref.precede();
expr.done(dotTokenType == JavaTokenType.THIS_KEYWORD ? JavaElementType.THIS_EXPRESSION : JavaElementType.SUPER_EXPRESSION);
}
else if (dotTokenType == JavaTokenType.SUPER_KEYWORD) {
dotPos.drop();
final PsiBuilder.Marker refExpr = expr.precede();
builder.mark().done(JavaElementType.REFERENCE_PARAMETER_LIST);
builder.advanceLexer();
refExpr.done(JavaElementType.REFERENCE_EXPRESSION);
expr = refExpr;
}
else {
dotPos.drop();
final PsiBuilder.Marker refExpr = expr.precede();
PsiBuilder.Marker refExpr = expr.precede();
myParser.getReferenceParser().parseReferenceParameterList(builder, false, false);
if (!expectOrError(builder, ID_OR_SUPER, "expected.identifier")) {
@@ -418,40 +418,11 @@ public class ExpressionParser {
}
else if (tokenType == JavaTokenType.LPARENTH) {
if (exprType(expr) != JavaElementType.REFERENCE_EXPRESSION) {
if (exprType(expr) == JavaElementType.SUPER_EXPRESSION) {
if (breakPoint == BreakPoint.P3) {
startMarker.drop();
return expr;
}
final PsiBuilder.Marker copy = startMarker.precede();
startMarker.rollbackTo();
final PsiBuilder.Marker qualifier = parsePrimaryExpressionStart(builder);
if (qualifier != null) {
final PsiBuilder.Marker refExpr = qualifier.precede();
if (builder.getTokenType() == JavaTokenType.DOT) {
builder.advanceLexer();
if (builder.getTokenType() == JavaTokenType.SUPER_KEYWORD) {
builder.advanceLexer();
refExpr.done(JavaElementType.REFERENCE_EXPRESSION);
expr = refExpr;
startMarker = copy;
continue;
}
}
}
copy.rollbackTo();
return parsePrimary(builder, BreakPoint.P3, -1);
}
else {
startMarker.drop();
return expr;
}
startMarker.drop();
return expr;
}
final PsiBuilder.Marker callExpr = expr.precede();
PsiBuilder.Marker callExpr = expr.precede();
parseArgumentList(builder);
callExpr.done(JavaElementType.METHOD_CALL_EXPRESSION);
expr = callExpr;
@@ -60,6 +60,8 @@ PsiJavaFile:QualifiedSuperMethodCall1.java
<empty list>
PsiIdentifier:d('d')
PsiJavaToken:DOT('.')
PsiReferenceParameterList
<empty list>
PsiKeyword:super('super')
PsiExpressionList
PsiJavaToken:LPARENTH('(')
@@ -6,9 +6,11 @@ PsiJavaFile:QualifiedSuperMethodCall1.java
<empty list>
PsiIdentifier:d('d')
PsiJavaToken:DOT('.')
PsiReferenceParameterList
<empty list>
PsiKeyword:super('super')
PsiExpressionList
PsiJavaToken:LPARENTH('(')
PsiLiteralExpression:0
PsiJavaToken:INTEGER_LITERAL('0')
PsiJavaToken:RPARENTH(')')
PsiJavaToken:RPARENTH(')')
@@ -0,0 +1,19 @@
PsiJavaFile:QualifiedSuperMethodCall3.java
PsiMethodCallExpression:C.A.super()
PsiReferenceExpression:C.A.super
PsiReferenceExpression:C.A
PsiReferenceExpression:C
PsiReferenceParameterList
<empty list>
PsiIdentifier:C('C')
PsiJavaToken:DOT('.')
PsiReferenceParameterList
<empty list>
PsiIdentifier:A('A')
PsiJavaToken:DOT('.')
PsiReferenceParameterList
<empty list>
PsiKeyword:super('super')
PsiExpressionList
PsiJavaToken:LPARENTH('(')
PsiJavaToken:RPARENTH(')')
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package com.intellij.lang.java.parser.partial;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.java.parser.JavaParser;
import com.intellij.lang.java.parser.JavaParsingTestCase;
import org.jetbrains.annotations.NonNls;
public class ExpressionParserTest extends JavaParsingTestCase {
public ExpressionParserTest() {
@@ -112,6 +111,7 @@ public class ExpressionParserTest extends JavaParsingTestCase {
public void testQualifiedSuperMethodCall0() { doParserTest("new D().super(0)"); }
public void testQualifiedSuperMethodCall1() { doParserTest("d.super(0)"); }
public void testQualifiedSuperMethodCall2() { doParserTest("(new O()).<T>super()"); }
public void testQualifiedSuperMethodCall3() { doParserTest("C.A.super()"); }
public void testSuperMethodCallTypeParameterList() { doParserTest("super()"); }
public void testPrimitiveClassObjectAccess() { doParserTest("int.class"); }
public void testPrimitiveFieldAccess() { doParserTest("int.x"); }
@@ -149,9 +149,10 @@ public class ExpressionParserTest extends JavaParsingTestCase {
public void testLambdaExpression19() { doParserTest("(@A T t) -> (null)"); }
public void testAmbiguousLambdaExpression() { doParserTest("f( (x) < y , z > (w) -> v )"); }
private void doParserTest(@NonNls final String text) {
private void doParserTest(String text) {
doParserTest(text, new MyTestParser());
}
private static class MyTestParser implements TestParser {
@Override
public void parse(final PsiBuilder builder) {