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 4770817bc9..d94cbb38c5 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 @@ -1,5 +1,5 @@ /* - * Copyright 2009-2021 the original author or authors. + * Copyright 2009-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -657,6 +657,30 @@ public void testTypeChecked6240() { runConformTest(sources, "A1B2C3"); } + @Test + public void testTypeChecked6277() { + //@formatter:off + String[] sources = { + "p/Main.groovy", + "package p\n" + + "@groovy.transform.TypeChecked\n" + + "def test(Pogo pogo) {\n" + + " def x = pogo.x;\n" + + " x.toLowerCase()\n" + + "}\n" + + "print test(new Pogo())\n", + + "p/Pogo.groovy", + "package p\n" + + "class Pogo {\n" + + " protected String getX() { 'Works' }" + + "}\n", + }; + //@formatter:on + + runConformTest(sources, "works"); + } + @Test public void testTypeChecked6455() { //@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 c81e0a7717..c3efcd54e2 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 @@ -2060,11 +2060,10 @@ private static boolean hasAccessToMember(final ClassNode sender, final ClassNode if (Modifier.isPublic(modifiers) || sender.equals(receiver) || sender.getOuterClasses().contains(receiver)) { return true; } - if (Modifier.isProtected(modifiers)) { - return sender.isDerivedFrom(receiver); - } else { - return !Modifier.isPrivate(modifiers) && Objects.equals(sender.getPackageName(), receiver.getPackageName()); + if (!Modifier.isPrivate(modifiers) && Objects.equals(sender.getPackageName(), receiver.getPackageName())) { + return true; } + return Modifier.isProtected(modifiers) && sender.isDerivedFrom(receiver); } // GRECLIPSE end @@ -2221,7 +2220,7 @@ private boolean storeField(FieldNode field, boolean returnTrueIfFieldExists, Pro if (field == null || !returnTrueIfFieldExists) return false; if (visitor != null) visitor.visitField(field); checkOrMarkPrivateAccess(expressionToStoreOn, field, lhsOfAssignment); - // GRECLIPSE add + // GRECLIPSE add -- GROOVY-8999 boolean accessible = hasAccessToMember(isSuperExpression(expressionToStoreOn.getObjectExpression()) ? typeCheckingContext.getEnclosingClassNode() : receiver, field.getDeclaringClass(), field.getModifiers()); if (expressionToStoreOn instanceof AttributeExpression) { if (!accessible) { 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 c8c3c32227..35fbae6932 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 @@ -1962,18 +1962,30 @@ && hasAccessToMember(enclosingTypes.iterator().next(), getter.getDeclaringClass( return foundGetterOrSetter; } + /* GRECLIPSE edit + private static boolean hasAccessToField(final ClassNode accessor, final FieldNode field) { + if (field.isPublic() || accessor.equals(field.getDeclaringClass())) { + return true; + } + if (field.isProtected()) { + return accessor.isDerivedFrom(field.getDeclaringClass()); + } else { + return !field.isPrivate() && Objects.equals(accessor.getPackageName(), field.getDeclaringClass().getPackageName()); + } + } + */ private static boolean hasAccessToMember(final ClassNode accessor, final ClassNode receiver, final int modifiers) { if (Modifier.isPublic(modifiers) || accessor.equals(receiver) || accessor.getOuterClasses().contains(receiver)) { return true; } - if (Modifier.isProtected(modifiers)) { - return accessor.isDerivedFrom(receiver); - } else { - return !Modifier.isPrivate(modifiers) && Objects.equals(accessor.getPackageName(), receiver.getPackageName()); + if (!Modifier.isPrivate(modifiers) && Objects.equals(accessor.getPackageName(), receiver.getPackageName())) { + return true; } + return Modifier.isProtected(modifiers) && accessor.isDerivedFrom(receiver); } + // GRECLIPSE end private MethodNode findGetter(final ClassNode current, String name, final boolean searchOuterClasses) { MethodNode getterMethod = current.getGetterMethod(name); 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 ec1584a9ba..531cf15d6b 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 @@ -1713,18 +1713,30 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re return foundGetterOrSetter; } + /* GRECLIPSE edit + private static boolean hasAccessToField(final ClassNode accessor, final FieldNode field) { + if (field.isPublic() || accessor.equals(field.getDeclaringClass())) { + return true; + } + if (field.isProtected()) { + return accessor.isDerivedFrom(field.getDeclaringClass()); + } else { + return !field.isPrivate() && Objects.equals(accessor.getPackageName(), field.getDeclaringClass().getPackageName()); + } + } + */ private static boolean hasAccessToMember(final ClassNode accessor, final ClassNode receiver, final int modifiers) { if (Modifier.isPublic(modifiers) || accessor.equals(receiver) || accessor.getOuterClasses().contains(receiver)) { return true; } - if (Modifier.isProtected(modifiers)) { - return accessor.isDerivedFrom(receiver); - } else { - return !Modifier.isPrivate(modifiers) && Objects.equals(accessor.getPackageName(), receiver.getPackageName()); + if (!Modifier.isPrivate(modifiers) && Objects.equals(accessor.getPackageName(), receiver.getPackageName())) { + return true; } + return Modifier.isProtected(modifiers) && accessor.isDerivedFrom(receiver); } + // GRECLIPSE end private MethodNode findGetter(final ClassNode current, String name, final boolean searchOuterClasses) { MethodNode getterMethod = current.getGetterMethod(name);