Skip to content

Commit

Permalink
GROOVY-9391
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Dec 7, 2021
1 parent 0fcd983 commit fe8f02d
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5377,6 +5377,30 @@ public void testGroovy9336() {
runConformTest(sources, "65536.0");
}

@Test // https://issues.apache.org/jira/browse/GROOVY-9391
public void testGroovy9391() {
//@formatter:off
String[] sources = {
"Main.groovy",
"class A { def m() {} }\n" +
"class B extends A { }\n" +
"class C extends B {\n" +
" def m() {\n" +
" ((A) super).m()\n" + // makes no sense
" }\n" +
"}\n",
};
//@formatter:on

runNegativeTest(sources,
"----------\n" +
"1. ERROR in Main.groovy (at line 5)\n" +
"\t((A) super).m()\n" +
"\t ^^^^^^^^^\n" +
"Groovy:Cannot cast or coerce `super`\n" +
"----------\n");
}

@Test // https://issues.apache.org/jira/browse/GROOVY-9906
public void testGroovy9906() {
//@formatter:off
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2768,8 +2768,9 @@ protected Expression asExpression(AST node) {
ClassNode type = makeTypeWithArguments(rightNode);

CastExpression asExpression = CastExpression.asExpression(type, leftExpression);
// GRECLIPSE edit -- set the sloc from the start of the target and the end of the type
//configureAST(asExpression, node);
/* GRECLIPSE edit -- set the sloc from the start of the target to the end of the type
configureAST(asExpression, node);
*/
asExpression.setStart(leftExpression.getStart());
asExpression.setLineNumber(leftExpression.getLineNumber());
asExpression.setColumnNumber(leftExpression.getColumnNumber());
Expand All @@ -2789,6 +2790,9 @@ protected Expression asExpression(AST node) {
// set the range of the type by itself
asExpression.setNameStart(typeStart);
asExpression.setNameEnd(asExpression.getEnd());

if (leftExpression instanceof VariableExpression && ((VariableExpression) leftExpression).isSuperExpression())
getController().addError(new SyntaxException("Cannot cast or coerce `super`", asExpression)); // GROOVY-9391
// GRECLIPSE end
return asExpression;
}
Expand Down Expand Up @@ -2816,6 +2820,8 @@ protected Expression castExpression(AST castNode) {
castExpression.setNameStart(locations.findOffset(typeNode.getLine(), typeNode.getColumn()));
castExpression.setNameEnd(locations.findOffset(typeNode.getLineLast(), typeNode.getColumnLast()));
}
if (expression instanceof VariableExpression && ((VariableExpression) expression).isSuperExpression())
getController().addError(new SyntaxException("Cannot cast or coerce `super`", castExpression)); // GROOVY-9391
// GRECLIPSE end
return castExpression;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3162,9 +3162,13 @@ public CastExpression visitCastExprAlt(CastExprAltContext ctx) {
ctx
);
*/
CastExpression cast = new CastExpression(visitCastParExpression(ctx.castParExpression()), (Expression) visit(ctx.expression()));
Expression expr = (Expression) this.visit(ctx.expression());
if (expr instanceof VariableExpression && ((VariableExpression) expr).isSuperExpression()) {
this.createParsingFailedException("Cannot cast or coerce `super`", ctx); // GROOVY-9391
}
CastExpression cast = new CastExpression(this.visitCastParExpression(ctx.castParExpression()), expr);
Expression name = configureAST(new ConstantExpression(null), ctx.castParExpression().type().primitiveType() != null
? ctx.castParExpression().type().primitiveType() : ctx.castParExpression().type().classOrInterfaceType());
? ctx.castParExpression().type().primitiveType() : ctx.castParExpression().type().classOrInterfaceType());
cast.setNameStart(name.getStart()); cast.setNameEnd(name.getEnd());
return configureAST(cast, ctx);
// GRECLIPSE end
Expand Down Expand Up @@ -3288,9 +3292,13 @@ public Expression visitRelationalExprAlt(RelationalExprAltContext ctx) {
CastExpression.asExpression(this.visitType(ctx.type()), (Expression) this.visit(ctx.left)),
ctx);
*/
CastExpression cast = CastExpression.asExpression(visitType(ctx.type()), (Expression) visit(ctx.left));
Expression expr = (Expression) this.visit(ctx.left);
if (expr instanceof VariableExpression && ((VariableExpression) expr).isSuperExpression()) {
this.createParsingFailedException("Cannot cast or coerce `super`", ctx); // GROOVY-9391
}
CastExpression cast = CastExpression.asExpression(this.visitType(ctx.type()), expr);
Expression name = configureAST(new ConstantExpression(null), ctx.type().primitiveType() != null
? ctx.type().primitiveType() : ctx.type().classOrInterfaceType());
? ctx.type().primitiveType() : ctx.type().classOrInterfaceType());
cast.setNameStart(name.getStart()); cast.setNameEnd(name.getEnd());
return configureAST(cast, ctx);
// GRECLIPSE end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2832,8 +2832,9 @@ protected Expression asExpression(AST node) {
ClassNode type = makeTypeWithArguments(rightNode);

CastExpression asExpression = CastExpression.asExpression(type, leftExpression);
// GRECLIPSE edit -- set the sloc from the start of the target and the end of the type
//configureAST(asExpression, node);
/* GRECLIPSE edit -- set the sloc from the start of the target to the end of the type
configureAST(asExpression, node);
*/
asExpression.setStart(leftExpression.getStart());
asExpression.setLineNumber(leftExpression.getLineNumber());
asExpression.setColumnNumber(leftExpression.getColumnNumber());
Expand All @@ -2853,6 +2854,9 @@ protected Expression asExpression(AST node) {
// set the range of the type by itself
asExpression.setNameStart(typeStart);
asExpression.setNameEnd(asExpression.getEnd());

if (leftExpression instanceof VariableExpression && ((VariableExpression) leftExpression).isSuperExpression())
getController().addError(new SyntaxException("Cannot cast or coerce `super`", asExpression)); // GROOVY-9391
// GRECLIPSE end
return asExpression;
}
Expand Down Expand Up @@ -2880,6 +2884,8 @@ protected Expression castExpression(AST castNode) {
castExpression.setNameStart(locations.findOffset(typeNode.getLine(), typeNode.getColumn()));
castExpression.setNameEnd(locations.findOffset(typeNode.getLineLast(), typeNode.getColumnLast()));
}
if (expression instanceof VariableExpression && ((VariableExpression) expression).isSuperExpression())
getController().addError(new SyntaxException("Cannot cast or coerce `super`", castExpression)); // GROOVY-9391
// GRECLIPSE end
return castExpression;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3421,13 +3421,14 @@ public Expression visitUnaryNotExprAlt(final UnaryNotExprAltContext ctx) {

@Override
public CastExpression visitCastExprAlt(final CastExprAltContext ctx) {
CastExpression cast = new CastExpression(
this.visitCastParExpression(ctx.castParExpression()),
(Expression) this.visit(ctx.expression())
);
Expression expr = (Expression) this.visit(ctx.expression());
if (expr instanceof VariableExpression && ((VariableExpression) expr).isSuperExpression()) {
this.createParsingFailedException("Cannot cast or coerce `super`", ctx); // GROOVY-9391
}
CastExpression cast = new CastExpression(this.visitCastParExpression(ctx.castParExpression()), expr);
// GRECLIPSE add
Expression name = configureAST(new ConstantExpression(null), ctx.castParExpression().type().primitiveType() != null
? ctx.castParExpression().type().primitiveType() : ctx.castParExpression().type().classOrInterfaceType());
? ctx.castParExpression().type().primitiveType() : ctx.castParExpression().type().classOrInterfaceType());
cast.setNameStart(name.getStart()); cast.setNameEnd(name.getEnd());
// GRECLIPSE end
return configureAST(cast, ctx);
Expand Down Expand Up @@ -3545,45 +3546,39 @@ public Expression visitShiftExprAlt(final ShiftExprAltContext ctx) {
@Override
public Expression visitRelationalExprAlt(final RelationalExprAltContext ctx) {
switch (ctx.op.getType()) {
case AS:
/* GRECLIPSE edit
return configureAST(
CastExpression.asExpression(this.visitType(ctx.type()), (Expression) this.visit(ctx.left)),
ctx);
*/
CastExpression cast = CastExpression.asExpression(visitType(ctx.type()), (Expression) visit(ctx.left));
case AS:
Expression expr = (Expression) this.visit(ctx.left);
if (expr instanceof VariableExpression && ((VariableExpression) expr).isSuperExpression()) {
this.createParsingFailedException("Cannot cast or coerce `super`", ctx); // GROOVY-9391
}
CastExpression cast = CastExpression.asExpression(this.visitType(ctx.type()), expr);
// GRECLIPSE add
Expression name = configureAST(new ConstantExpression(null), ctx.type().primitiveType() != null
? ctx.type().primitiveType() : ctx.type().classOrInterfaceType());
? ctx.type().primitiveType() : ctx.type().classOrInterfaceType());
cast.setNameStart(name.getStart()); cast.setNameEnd(name.getEnd());
return configureAST(cast, ctx);
// GRECLIPSE end
// GRECLIPSE end
return configureAST(cast, ctx);

case INSTANCEOF:
case NOT_INSTANCEOF:
ctx.type().putNodeMetaData(IS_INSIDE_INSTANCEOF_EXPR, true);
return configureAST(
new BinaryExpression((Expression) this.visit(ctx.left),
this.createGroovyToken(ctx.op),
configureAST(new ClassExpression(this.visitType(ctx.type())), ctx.type())),
ctx);

case LE:
case GE:
case GT:
case LT:
case IN:
case NOT_IN: {
if (ctx.op.getType() == IN || ctx.op.getType() == NOT_IN ) {
return this.createBinaryExpression(ctx.left, ctx.op, ctx.right, ctx);
}
case INSTANCEOF:
case NOT_INSTANCEOF:
ctx.type().putNodeMetaData(IS_INSIDE_INSTANCEOF_EXPR, Boolean.TRUE);
return configureAST(
new BinaryExpression(
(Expression) this.visit(ctx.left),
this.createGroovyToken(ctx.op),
configureAST(new ClassExpression(this.visitType(ctx.type())), ctx.type())),
ctx);

return configureAST(
this.createBinaryExpression(ctx.left, ctx.op, ctx.right),
ctx);
}
case GT:
case GE:
case LT:
case LE:
case IN:
case NOT_IN:
return this.createBinaryExpression(ctx.left, ctx.op, ctx.right, ctx);

default:
throw createParsingFailedException("Unsupported relational expression: " + ctx.getText(), ctx);
default:
throw this.createParsingFailedException("Unsupported relational expression: " + ctx.getText(), ctx);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2832,8 +2832,9 @@ protected Expression asExpression(AST node) {
ClassNode type = makeTypeWithArguments(rightNode);

CastExpression asExpression = CastExpression.asExpression(type, leftExpression);
// GRECLIPSE edit -- set the sloc from the start of the target and the end of the type
//configureAST(asExpression, node);
/* GRECLIPSE edit -- set the sloc from the start of the target to the end of the type
configureAST(asExpression, node);
*/
asExpression.setStart(leftExpression.getStart());
asExpression.setLineNumber(leftExpression.getLineNumber());
asExpression.setColumnNumber(leftExpression.getColumnNumber());
Expand All @@ -2853,6 +2854,9 @@ protected Expression asExpression(AST node) {
// set the range of the type by itself
asExpression.setNameStart(typeStart);
asExpression.setNameEnd(asExpression.getEnd());

if (leftExpression instanceof VariableExpression && ((VariableExpression) leftExpression).isSuperExpression())
getController().addError(new SyntaxException("Cannot cast or coerce `super`", asExpression)); // GROOVY-9391
// GRECLIPSE end
return asExpression;
}
Expand Down Expand Up @@ -2880,6 +2884,8 @@ protected Expression castExpression(AST castNode) {
castExpression.setNameStart(locations.findOffset(typeNode.getLine(), typeNode.getColumn()));
castExpression.setNameEnd(locations.findOffset(typeNode.getLineLast(), typeNode.getColumnLast()));
}
if (expression instanceof VariableExpression && ((VariableExpression) expression).isSuperExpression())
getController().addError(new SyntaxException("Cannot cast or coerce `super`", castExpression)); // GROOVY-9391
// GRECLIPSE end
return castExpression;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3739,6 +3739,26 @@ final class SemanticHighlightingTests extends GroovyEclipseTestSuite {
assertHighlighting('class X { def \'\'\'test case name\'\'\'() {} }', new HighlightedTypedPosition(6, 1, CLASS))
}

@Test
void testCastAndCoerce() {
String contents = '''\
|void test(obj) {
| def one = (String) obj
| def two = obj as String
|}
|'''.stripMargin()

assertHighlighting(contents,
new HighlightedTypedPosition(contents.indexOf('test'), 4, METHOD),
new HighlightedTypedPosition(contents.indexOf('obj'), 3, PARAMETER),
new HighlightedTypedPosition(contents.indexOf('one'), 3, VARIABLE),
new HighlightedTypedPosition(contents.indexOf('String'), 6, CLASS),
new HighlightedTypedPosition(contents.indexOf('obj', contents.indexOf('String')), 3, PARAMETER),
new HighlightedTypedPosition(contents.indexOf('two'), 3, VARIABLE),
new HighlightedTypedPosition(contents.lastIndexOf('obj'), 3, PARAMETER),
new HighlightedTypedPosition(contents.lastIndexOf('String'), 6, CLASS))
}

@Test
void testAliasType1() {
String contents = '''\
Expand Down

0 comments on commit fe8f02d

Please sign in to comment.