Skip to content

Commit fe8f02d

Browse files
committed
GROOVY-9391
1 parent 0fcd983 commit fe8f02d

File tree

7 files changed

+114
-49
lines changed

7 files changed

+114
-49
lines changed

base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/GroovySimpleTests.java

+24
Original file line numberDiff line numberDiff line change
@@ -5377,6 +5377,30 @@ public void testGroovy9336() {
53775377
runConformTest(sources, "65536.0");
53785378
}
53795379

5380+
@Test // https://issues.apache.org/jira/browse/GROOVY-9391
5381+
public void testGroovy9391() {
5382+
//@formatter:off
5383+
String[] sources = {
5384+
"Main.groovy",
5385+
"class A { def m() {} }\n" +
5386+
"class B extends A { }\n" +
5387+
"class C extends B {\n" +
5388+
" def m() {\n" +
5389+
" ((A) super).m()\n" + // makes no sense
5390+
" }\n" +
5391+
"}\n",
5392+
};
5393+
//@formatter:on
5394+
5395+
runNegativeTest(sources,
5396+
"----------\n" +
5397+
"1. ERROR in Main.groovy (at line 5)\n" +
5398+
"\t((A) super).m()\n" +
5399+
"\t ^^^^^^^^^\n" +
5400+
"Groovy:Cannot cast or coerce `super`\n" +
5401+
"----------\n");
5402+
}
5403+
53805404
@Test // https://issues.apache.org/jira/browse/GROOVY-9906
53815405
public void testGroovy9906() {
53825406
//@formatter:off

base/org.codehaus.groovy25/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -2768,8 +2768,9 @@ protected Expression asExpression(AST node) {
27682768
ClassNode type = makeTypeWithArguments(rightNode);
27692769

27702770
CastExpression asExpression = CastExpression.asExpression(type, leftExpression);
2771-
// GRECLIPSE edit -- set the sloc from the start of the target and the end of the type
2772-
//configureAST(asExpression, node);
2771+
/* GRECLIPSE edit -- set the sloc from the start of the target to the end of the type
2772+
configureAST(asExpression, node);
2773+
*/
27732774
asExpression.setStart(leftExpression.getStart());
27742775
asExpression.setLineNumber(leftExpression.getLineNumber());
27752776
asExpression.setColumnNumber(leftExpression.getColumnNumber());
@@ -2789,6 +2790,9 @@ protected Expression asExpression(AST node) {
27892790
// set the range of the type by itself
27902791
asExpression.setNameStart(typeStart);
27912792
asExpression.setNameEnd(asExpression.getEnd());
2793+
2794+
if (leftExpression instanceof VariableExpression && ((VariableExpression) leftExpression).isSuperExpression())
2795+
getController().addError(new SyntaxException("Cannot cast or coerce `super`", asExpression)); // GROOVY-9391
27922796
// GRECLIPSE end
27932797
return asExpression;
27942798
}
@@ -2816,6 +2820,8 @@ protected Expression castExpression(AST castNode) {
28162820
castExpression.setNameStart(locations.findOffset(typeNode.getLine(), typeNode.getColumn()));
28172821
castExpression.setNameEnd(locations.findOffset(typeNode.getLineLast(), typeNode.getColumnLast()));
28182822
}
2823+
if (expression instanceof VariableExpression && ((VariableExpression) expression).isSuperExpression())
2824+
getController().addError(new SyntaxException("Cannot cast or coerce `super`", castExpression)); // GROOVY-9391
28192825
// GRECLIPSE end
28202826
return castExpression;
28212827
}

base/org.codehaus.groovy30/src/org/apache/groovy/parser/antlr4/AstBuilder.java

+12-4
Original file line numberDiff line numberDiff line change
@@ -3162,9 +3162,13 @@ public CastExpression visitCastExprAlt(CastExprAltContext ctx) {
31623162
ctx
31633163
);
31643164
*/
3165-
CastExpression cast = new CastExpression(visitCastParExpression(ctx.castParExpression()), (Expression) visit(ctx.expression()));
3165+
Expression expr = (Expression) this.visit(ctx.expression());
3166+
if (expr instanceof VariableExpression && ((VariableExpression) expr).isSuperExpression()) {
3167+
this.createParsingFailedException("Cannot cast or coerce `super`", ctx); // GROOVY-9391
3168+
}
3169+
CastExpression cast = new CastExpression(this.visitCastParExpression(ctx.castParExpression()), expr);
31663170
Expression name = configureAST(new ConstantExpression(null), ctx.castParExpression().type().primitiveType() != null
3167-
? ctx.castParExpression().type().primitiveType() : ctx.castParExpression().type().classOrInterfaceType());
3171+
? ctx.castParExpression().type().primitiveType() : ctx.castParExpression().type().classOrInterfaceType());
31683172
cast.setNameStart(name.getStart()); cast.setNameEnd(name.getEnd());
31693173
return configureAST(cast, ctx);
31703174
// GRECLIPSE end
@@ -3288,9 +3292,13 @@ public Expression visitRelationalExprAlt(RelationalExprAltContext ctx) {
32883292
CastExpression.asExpression(this.visitType(ctx.type()), (Expression) this.visit(ctx.left)),
32893293
ctx);
32903294
*/
3291-
CastExpression cast = CastExpression.asExpression(visitType(ctx.type()), (Expression) visit(ctx.left));
3295+
Expression expr = (Expression) this.visit(ctx.left);
3296+
if (expr instanceof VariableExpression && ((VariableExpression) expr).isSuperExpression()) {
3297+
this.createParsingFailedException("Cannot cast or coerce `super`", ctx); // GROOVY-9391
3298+
}
3299+
CastExpression cast = CastExpression.asExpression(this.visitType(ctx.type()), expr);
32923300
Expression name = configureAST(new ConstantExpression(null), ctx.type().primitiveType() != null
3293-
? ctx.type().primitiveType() : ctx.type().classOrInterfaceType());
3301+
? ctx.type().primitiveType() : ctx.type().classOrInterfaceType());
32943302
cast.setNameStart(name.getStart()); cast.setNameEnd(name.getEnd());
32953303
return configureAST(cast, ctx);
32963304
// GRECLIPSE end

base/org.codehaus.groovy30/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -2832,8 +2832,9 @@ protected Expression asExpression(AST node) {
28322832
ClassNode type = makeTypeWithArguments(rightNode);
28332833

28342834
CastExpression asExpression = CastExpression.asExpression(type, leftExpression);
2835-
// GRECLIPSE edit -- set the sloc from the start of the target and the end of the type
2836-
//configureAST(asExpression, node);
2835+
/* GRECLIPSE edit -- set the sloc from the start of the target to the end of the type
2836+
configureAST(asExpression, node);
2837+
*/
28372838
asExpression.setStart(leftExpression.getStart());
28382839
asExpression.setLineNumber(leftExpression.getLineNumber());
28392840
asExpression.setColumnNumber(leftExpression.getColumnNumber());
@@ -2853,6 +2854,9 @@ protected Expression asExpression(AST node) {
28532854
// set the range of the type by itself
28542855
asExpression.setNameStart(typeStart);
28552856
asExpression.setNameEnd(asExpression.getEnd());
2857+
2858+
if (leftExpression instanceof VariableExpression && ((VariableExpression) leftExpression).isSuperExpression())
2859+
getController().addError(new SyntaxException("Cannot cast or coerce `super`", asExpression)); // GROOVY-9391
28562860
// GRECLIPSE end
28572861
return asExpression;
28582862
}
@@ -2880,6 +2884,8 @@ protected Expression castExpression(AST castNode) {
28802884
castExpression.setNameStart(locations.findOffset(typeNode.getLine(), typeNode.getColumn()));
28812885
castExpression.setNameEnd(locations.findOffset(typeNode.getLineLast(), typeNode.getColumnLast()));
28822886
}
2887+
if (expression instanceof VariableExpression && ((VariableExpression) expression).isSuperExpression())
2888+
getController().addError(new SyntaxException("Cannot cast or coerce `super`", castExpression)); // GROOVY-9391
28832889
// GRECLIPSE end
28842890
return castExpression;
28852891
}

base/org.codehaus.groovy40/src/org/apache/groovy/parser/antlr4/AstBuilder.java

+34-39
Original file line numberDiff line numberDiff line change
@@ -3421,13 +3421,14 @@ public Expression visitUnaryNotExprAlt(final UnaryNotExprAltContext ctx) {
34213421

34223422
@Override
34233423
public CastExpression visitCastExprAlt(final CastExprAltContext ctx) {
3424-
CastExpression cast = new CastExpression(
3425-
this.visitCastParExpression(ctx.castParExpression()),
3426-
(Expression) this.visit(ctx.expression())
3427-
);
3424+
Expression expr = (Expression) this.visit(ctx.expression());
3425+
if (expr instanceof VariableExpression && ((VariableExpression) expr).isSuperExpression()) {
3426+
this.createParsingFailedException("Cannot cast or coerce `super`", ctx); // GROOVY-9391
3427+
}
3428+
CastExpression cast = new CastExpression(this.visitCastParExpression(ctx.castParExpression()), expr);
34283429
// GRECLIPSE add
34293430
Expression name = configureAST(new ConstantExpression(null), ctx.castParExpression().type().primitiveType() != null
3430-
? ctx.castParExpression().type().primitiveType() : ctx.castParExpression().type().classOrInterfaceType());
3431+
? ctx.castParExpression().type().primitiveType() : ctx.castParExpression().type().classOrInterfaceType());
34313432
cast.setNameStart(name.getStart()); cast.setNameEnd(name.getEnd());
34323433
// GRECLIPSE end
34333434
return configureAST(cast, ctx);
@@ -3545,45 +3546,39 @@ public Expression visitShiftExprAlt(final ShiftExprAltContext ctx) {
35453546
@Override
35463547
public Expression visitRelationalExprAlt(final RelationalExprAltContext ctx) {
35473548
switch (ctx.op.getType()) {
3548-
case AS:
3549-
/* GRECLIPSE edit
3550-
return configureAST(
3551-
CastExpression.asExpression(this.visitType(ctx.type()), (Expression) this.visit(ctx.left)),
3552-
ctx);
3553-
*/
3554-
CastExpression cast = CastExpression.asExpression(visitType(ctx.type()), (Expression) visit(ctx.left));
3549+
case AS:
3550+
Expression expr = (Expression) this.visit(ctx.left);
3551+
if (expr instanceof VariableExpression && ((VariableExpression) expr).isSuperExpression()) {
3552+
this.createParsingFailedException("Cannot cast or coerce `super`", ctx); // GROOVY-9391
3553+
}
3554+
CastExpression cast = CastExpression.asExpression(this.visitType(ctx.type()), expr);
3555+
// GRECLIPSE add
35553556
Expression name = configureAST(new ConstantExpression(null), ctx.type().primitiveType() != null
3556-
? ctx.type().primitiveType() : ctx.type().classOrInterfaceType());
3557+
? ctx.type().primitiveType() : ctx.type().classOrInterfaceType());
35573558
cast.setNameStart(name.getStart()); cast.setNameEnd(name.getEnd());
3558-
return configureAST(cast, ctx);
3559-
// GRECLIPSE end
3559+
// GRECLIPSE end
3560+
return configureAST(cast, ctx);
35603561

3561-
case INSTANCEOF:
3562-
case NOT_INSTANCEOF:
3563-
ctx.type().putNodeMetaData(IS_INSIDE_INSTANCEOF_EXPR, true);
3564-
return configureAST(
3565-
new BinaryExpression((Expression) this.visit(ctx.left),
3566-
this.createGroovyToken(ctx.op),
3567-
configureAST(new ClassExpression(this.visitType(ctx.type())), ctx.type())),
3568-
ctx);
3569-
3570-
case LE:
3571-
case GE:
3572-
case GT:
3573-
case LT:
3574-
case IN:
3575-
case NOT_IN: {
3576-
if (ctx.op.getType() == IN || ctx.op.getType() == NOT_IN ) {
3577-
return this.createBinaryExpression(ctx.left, ctx.op, ctx.right, ctx);
3578-
}
3562+
case INSTANCEOF:
3563+
case NOT_INSTANCEOF:
3564+
ctx.type().putNodeMetaData(IS_INSIDE_INSTANCEOF_EXPR, Boolean.TRUE);
3565+
return configureAST(
3566+
new BinaryExpression(
3567+
(Expression) this.visit(ctx.left),
3568+
this.createGroovyToken(ctx.op),
3569+
configureAST(new ClassExpression(this.visitType(ctx.type())), ctx.type())),
3570+
ctx);
35793571

3580-
return configureAST(
3581-
this.createBinaryExpression(ctx.left, ctx.op, ctx.right),
3582-
ctx);
3583-
}
3572+
case GT:
3573+
case GE:
3574+
case LT:
3575+
case LE:
3576+
case IN:
3577+
case NOT_IN:
3578+
return this.createBinaryExpression(ctx.left, ctx.op, ctx.right, ctx);
35843579

3585-
default:
3586-
throw createParsingFailedException("Unsupported relational expression: " + ctx.getText(), ctx);
3580+
default:
3581+
throw this.createParsingFailedException("Unsupported relational expression: " + ctx.getText(), ctx);
35873582
}
35883583
}
35893584

base/org.codehaus.groovy40/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -2832,8 +2832,9 @@ protected Expression asExpression(AST node) {
28322832
ClassNode type = makeTypeWithArguments(rightNode);
28332833

28342834
CastExpression asExpression = CastExpression.asExpression(type, leftExpression);
2835-
// GRECLIPSE edit -- set the sloc from the start of the target and the end of the type
2836-
//configureAST(asExpression, node);
2835+
/* GRECLIPSE edit -- set the sloc from the start of the target to the end of the type
2836+
configureAST(asExpression, node);
2837+
*/
28372838
asExpression.setStart(leftExpression.getStart());
28382839
asExpression.setLineNumber(leftExpression.getLineNumber());
28392840
asExpression.setColumnNumber(leftExpression.getColumnNumber());
@@ -2853,6 +2854,9 @@ protected Expression asExpression(AST node) {
28532854
// set the range of the type by itself
28542855
asExpression.setNameStart(typeStart);
28552856
asExpression.setNameEnd(asExpression.getEnd());
2857+
2858+
if (leftExpression instanceof VariableExpression && ((VariableExpression) leftExpression).isSuperExpression())
2859+
getController().addError(new SyntaxException("Cannot cast or coerce `super`", asExpression)); // GROOVY-9391
28562860
// GRECLIPSE end
28572861
return asExpression;
28582862
}
@@ -2880,6 +2884,8 @@ protected Expression castExpression(AST castNode) {
28802884
castExpression.setNameStart(locations.findOffset(typeNode.getLine(), typeNode.getColumn()));
28812885
castExpression.setNameEnd(locations.findOffset(typeNode.getLineLast(), typeNode.getColumnLast()));
28822886
}
2887+
if (expression instanceof VariableExpression && ((VariableExpression) expression).isSuperExpression())
2888+
getController().addError(new SyntaxException("Cannot cast or coerce `super`", castExpression)); // GROOVY-9391
28832889
// GRECLIPSE end
28842890
return castExpression;
28852891
}

ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/ui/SemanticHighlightingTests.groovy

+20
Original file line numberDiff line numberDiff line change
@@ -3739,6 +3739,26 @@ final class SemanticHighlightingTests extends GroovyEclipseTestSuite {
37393739
assertHighlighting('class X { def \'\'\'test case name\'\'\'() {} }', new HighlightedTypedPosition(6, 1, CLASS))
37403740
}
37413741

3742+
@Test
3743+
void testCastAndCoerce() {
3744+
String contents = '''\
3745+
|void test(obj) {
3746+
| def one = (String) obj
3747+
| def two = obj as String
3748+
|}
3749+
|'''.stripMargin()
3750+
3751+
assertHighlighting(contents,
3752+
new HighlightedTypedPosition(contents.indexOf('test'), 4, METHOD),
3753+
new HighlightedTypedPosition(contents.indexOf('obj'), 3, PARAMETER),
3754+
new HighlightedTypedPosition(contents.indexOf('one'), 3, VARIABLE),
3755+
new HighlightedTypedPosition(contents.indexOf('String'), 6, CLASS),
3756+
new HighlightedTypedPosition(contents.indexOf('obj', contents.indexOf('String')), 3, PARAMETER),
3757+
new HighlightedTypedPosition(contents.indexOf('two'), 3, VARIABLE),
3758+
new HighlightedTypedPosition(contents.lastIndexOf('obj'), 3, PARAMETER),
3759+
new HighlightedTypedPosition(contents.lastIndexOf('String'), 6, CLASS))
3760+
}
3761+
37423762
@Test
37433763
void testAliasType1() {
37443764
String contents = '''\

0 commit comments

Comments
 (0)