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 38d850d59f..0722ffe0a0 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 @@ -7703,4 +7703,35 @@ public void testTypeChecked11335() { runConformTest(sources, "works"); } + + @Test + public void testTypeChecked11358() { + //@formatter:off + String[] sources = { + "Main.groovy", + "abstract class A {\n" + + " private int f\n" + + "}\n" + + "@groovy.transform.TypeChecked\n" + + "void test(A a) {\n" + + " int i = a.@f\n" + + " int j = a.f\n" + + "}\n" + + "test(new A() {})\n", + }; + //@formatter:on + + runNegativeTest(sources, + "----------\n" + + "1. ERROR in Main.groovy (at line 6)\n" + + "\tint i = a.@f\n" + + "\t ^\n" + + "Groovy:[Static type checking] - Cannot access field: f of class: A\n" + + "----------\n" + + "2. ERROR in Main.groovy (at line 7)\n" + + "\tint j = a.f\n" + + "\t ^^^\n" + + "Groovy:[Static type checking] - No such property: f for class: A\n" + + "----------\n"); + } } 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 6ff4eece81..bbe0e92a1c 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 @@ -1920,7 +1920,7 @@ private boolean isStaticInContext(final MethodNode method) { private boolean storeField(final FieldNode field, final PropertyExpression expressionToStoreOn, final ClassNode receiver, final ClassCodeVisitorSupport visitor, final String delegationData, final boolean lhsOfAssignment) { if (visitor != null) visitor.visitField(field); checkOrMarkPrivateAccess(expressionToStoreOn, field, lhsOfAssignment); - /* GRECLIPSE edit -- GROOVY-11319 + /* GRECLIPSE edit -- GROOVY-11319, GROOVY-11358 boolean accessible = hasAccessToMember(isSuperExpression(expressionToStoreOn.getObjectExpression()) ? typeCheckingContext.getEnclosingClassNode() : receiver, field.getDeclaringClass(), field.getModifiers()); if (expressionToStoreOn instanceof AttributeExpression) { // TODO: expand to include PropertyExpression @@ -1930,7 +1930,7 @@ private boolean storeField(final FieldNode field, final PropertyExpression expre } */ boolean superField = isSuperExpression(expressionToStoreOn.getObjectExpression()); - boolean accessible = ( !superField && receiver.equals(field.getDeclaringClass()) ) // GROOVY-7300 + boolean accessible = (!superField && receiver.equals(field.getDeclaringClass()) && !field.getDeclaringClass().isAbstract()) || hasAccessToMember(typeCheckingContext.getEnclosingClassNode(), field.getDeclaringClass(), field.getModifiers()); if (!accessible) { if (expressionToStoreOn instanceof AttributeExpression) { 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 f8dff8e081..cf9ea88f41 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 @@ -1839,7 +1839,7 @@ private boolean storeField(final FieldNode field, final PropertyExpression expre if (visitor != null) visitor.visitField(field); checkOrMarkPrivateAccess(expressionToStoreOn, field, lhsOfAssignment); boolean superField = isSuperExpression(expressionToStoreOn.getObjectExpression()); - boolean accessible = ( !superField && receiver.equals(field.getDeclaringClass()) ) // GROOVY-7300 + boolean accessible = (!superField && receiver.equals(field.getDeclaringClass()) && !field.getDeclaringClass().isAbstract()) // GROOVY-7300, GROOVY-11358 || hasAccessToMember(typeCheckingContext.getEnclosingClassNode(), field.getDeclaringClass(), field.getModifiers()); if (!accessible) { diff --git a/base/org.codehaus.groovy50/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy50/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 33fdbe53ad..b5f3ad2c2d 100644 --- a/base/org.codehaus.groovy50/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy50/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -1923,7 +1923,7 @@ private boolean storeField(final FieldNode field, final PropertyExpression expre if (visitor != null) visitor.visitField(field); checkOrMarkPrivateAccess(expressionToStoreOn, field, lhsOfAssignment); boolean superField = isSuperExpression(expressionToStoreOn.getObjectExpression()); - boolean accessible = ( !superField && receiver.equals(field.getDeclaringClass()) ) // GROOVY-7300 + boolean accessible = (!superField && receiver.equals(field.getDeclaringClass()) && !field.getDeclaringClass().isAbstract()) // GROOVY-7300, GROOVY-11358 || hasAccessToMember(typeCheckingContext.getEnclosingClassNode(), field.getDeclaringClass(), field.getModifiers()); if (!accessible) {