From dfe32b0a5f4fc68ae4279b5a4e887f46bb537d8f Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Wed, 17 Nov 2021 12:50:08 -0600 Subject: [PATCH] GROOVY-10341 --- .../core/tests/xform/TypeCheckedTests.java | 27 +++++++++++++++++++ .../stc/StaticTypeCheckingVisitor.java | 4 +++ .../stc/StaticTypeCheckingVisitor.java | 4 +++ .../stc/StaticTypeCheckingVisitor.java | 2 ++ 4 files changed, 37 insertions(+) diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java index 7dd7a5dc2c..b671c2b8b3 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java @@ -4747,6 +4747,33 @@ public void testTypeChecked10339() { "----------\n"); } + @Test + public void testTypeChecked10341() { + //@formatter:off + String[] sources = { + "Main.groovy", + "abstract class A {\n" + + " abstract def m()\n" + + "}\n" + + "@groovy.transform.TypeChecked\n" + + "class C extends A {\n" + + " @Override\n" + + " def m() {\n" + + " super.m()\n" + + " }\n" + + "}\n", + }; + //@formatter:on + + runNegativeTest(sources, + "----------\n" + + "1. ERROR in Main.groovy (at line 8)\n" + + "\tsuper.m()\n" + + "\t^^^^^^^^^\n" + + "Groovy:[Static type checking] - Abstract method m() cannot be called directly\n" + + "----------\n"); + } + @Test public void testTypeChecked10344() { //@formatter:off diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 339412f4b4..5813c4ba88 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -4312,6 +4312,10 @@ public void visitMethodCallExpression(MethodCallExpression call) { ClassNode owner = directMethodCallCandidate.getDeclaringClass(); addStaticTypeError("Non static method " + owner.getName() + "#" + directMethodCallCandidate.getName() + " cannot be called from static context", call); } + // GRECLIPSE add -- GROOVY-10341 + else if (directMethodCallCandidate.isAbstract() && objectExpression instanceof VariableExpression && ((VariableExpression) objectExpression).isSuperExpression()) + addStaticTypeError("Abstract method " + toMethodParametersString(directMethodCallCandidate.getName(), extractTypesFromParameters(directMethodCallCandidate.getParameters())) + " cannot be called directly", call); + // GRECLIPSE end if (chosenReceiver == null) { chosenReceiver = Receiver.make(directMethodCallCandidate.getDeclaringClass()); } diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index ff54f3b4f1..421cd0e51d 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -3963,6 +3963,10 @@ public void visitMethodCallExpression(final MethodCallExpression call) { ClassNode owner = directMethodCallCandidate.getDeclaringClass(); addStaticTypeError("Non static method " + owner.getName() + "#" + directMethodCallCandidate.getName() + " cannot be called from static context", call); } + // GRECLIPSE add -- GROOVY-10341 + else if (directMethodCallCandidate.isAbstract() && isSuperExpression(objectExpression)) + addStaticTypeError("Abstract method " + toMethodParametersString(directMethodCallCandidate.getName(), extractTypesFromParameters(directMethodCallCandidate.getParameters())) + " cannot be called directly", call); + // GRECLIPSE end if (chosenReceiver == null) { chosenReceiver = Receiver.make(directMethodCallCandidate.getDeclaringClass()); } diff --git a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index f73513b12a..41fd92a866 100644 --- a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -3478,6 +3478,8 @@ && implementsInterfaceOrIsSubclassOf(receiverType, node.getDeclaringClass()))) { if (!targetMethodCandidate.isStatic() && !isClassType(declaringClass) && objectExpression instanceof ClassExpression && call.getNodeMetaData(DYNAMIC_RESOLUTION) == null) { addStaticTypeError("Non-static method " + prettyPrintTypeName(declaringClass) + "#" + targetMethodCandidate.getName() + " cannot be called from static context", call); + } else if (targetMethodCandidate.isAbstract() && isSuperExpression(objectExpression)) { // GROOVY-10341 + addStaticTypeError("Abstract method " + toMethodParametersString(targetMethodCandidate.getName(), extractTypesFromParameters(targetMethodCandidate.getParameters())) + " cannot be called directly", call); } if (chosenReceiver == null) { chosenReceiver = Receiver.make(declaringClass);