diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/StaticCompilationTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/StaticCompilationTests.java index 77d7b3b69a..2cdf7d0005 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/StaticCompilationTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/StaticCompilationTests.java @@ -2463,22 +2463,19 @@ public void testCompileStatic9007or9043_enumConstToPrivate1() { "}\n" + "@groovy.transform.CompileStatic\n" + "void test() {\n" + - " print E.ONE.name\n" + + " E.ONE.name\n" + "}\n" + "test()\n", }; //@formatter:on - runConformTest(sources, "", "groovy.lang.MissingPropertyException: No such property: name for class: E"); - /* TODO: https://issues.apache.org/jira/browse/GROOVY-9093 runNegativeTest(sources, "----------\n" + "1. ERROR in Main.groovy (at line 6)\n" + "\tE.ONE.name\n" + "\t^^^^^\n" + - "Groovy:Access to E#name is forbidden @ line 6, column 3.\n" + + "Groovy:Access to E#name is forbidden\n" + "----------\n"); - */ } @Test @@ -2491,22 +2488,19 @@ public void testCompileStatic9007or9043_enumConstToPrivate2() { "}\n" + "@groovy.transform.CompileStatic\n" + "void test() {\n" + - " print E.ONE.ordinal\n" + + " E.ONE.ordinal\n" + "}\n" + "test()\n", }; //@formatter:on - runConformTest(sources, "", "groovy.lang.MissingPropertyException: No such property: ordinal for class: E"); - /* TODO: https://issues.apache.org/jira/browse/GROOVY-9093 runNegativeTest(sources, "----------\n" + "1. ERROR in Main.groovy (at line 6)\n" + "\tE.ONE.ordinal\n" + "\t^^^^^\n" + - "Groovy:Access to E#ordinal is forbidden @ line 6, column 3.\n" + + "Groovy:Access to E#ordinal is forbidden\n" + "----------\n"); - */ } @Test @@ -3023,16 +3017,13 @@ public void testCompileStatic9043_subToPackage2() { }; //@formatter:on - runConformTest(sources, ""); - /* TODO: https://issues.apache.org/jira/browse/GROOVY-9093 runNegativeTest(sources, "----------\n" + "1. ERROR in q\\More.groovy (at line 5)\n" + "\tprint VALUE\n" + "\t ^^^^^\n" + - "Groovy:Access to q.More#VALUE is forbidden @ line 5, column 11.\n" + + "Groovy:Access to q.More#VALUE is forbidden\n" + "----------\n"); - */ } @Test @@ -3174,16 +3165,13 @@ public void testCompileStatic9043_subToPrivate2() { }; //@formatter:on - runConformTest(sources, ""); - /* TODO: https://issues.apache.org/jira/browse/GROOVY-9093 runNegativeTest(sources, "----------\n" + "1. ERROR in q\\More.groovy (at line 5)\n" + "\tprint VALUE\n" + "\t ^^^^^\n" + - "Groovy:Access to q.More#VALUE is forbidden @ line 5, column 11.\n" + + "Groovy:Access to q.More#VALUE is forbidden\n" + "----------\n"); - */ } @Test diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java index ecdd3f9d3d..20cc6962f3 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java @@ -444,20 +444,19 @@ private boolean makeGetPrivateFieldWithBridgeMethod(final Expression receiver, f } @Override - public void makeGroovyObjectGetPropertySite(final Expression receiver, final String methodName, final boolean safe, final boolean implicitThis) { + public void makeGroovyObjectGetPropertySite(final Expression receiver, final String propertyName, final boolean safe, final boolean implicitThis) { TypeChooser typeChooser = controller.getTypeChooser(); ClassNode classNode = controller.getClassNode(); ClassNode receiverType = typeChooser.resolveType(receiver, classNode); if (receiver instanceof VariableExpression && ((VariableExpression) receiver).isThisExpression() && !controller.isInClosure()) { receiverType = classNode; } - - String property = methodName; + if (implicitThis) { if (controller.getInvocationWriter() instanceof StaticInvocationWriter) { MethodCallExpression currentCall = ((StaticInvocationWriter) controller.getInvocationWriter()).getCurrentCall(); if (currentCall != null && currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER) != null) { - property = currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER); + String property = currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER); String[] props = property.split("\\."); BytecodeExpression thisLoader = new BytecodeExpression() { @Override @@ -478,14 +477,23 @@ public void visit(final MethodVisitor mv) { } } - if (makeGetPropertyWithGetter(receiver, receiverType, property, safe, implicitThis)) return; - if (makeGetPrivateFieldWithBridgeMethod(receiver, receiverType, property, safe, implicitThis)) return; - if (makeGetField(receiver, receiverType, property, safe, implicitThis)) return; + if (makeGetPropertyWithGetter(receiver, receiverType, propertyName, safe, implicitThis)) return; + if (makeGetPrivateFieldWithBridgeMethod(receiver, receiverType, propertyName, safe, implicitThis)) return; + if (makeGetField(receiver, receiverType, propertyName, safe, implicitThis)) return; + + // GRECLIPSE add -- GROOVY-9093 + boolean isScriptVariable = (receiverType.isScript() && receiver instanceof VariableExpression && ((VariableExpression) receiver).getAccessedVariable() == null); + if (!isScriptVariable && controller.getClassNode().getOuterClass() == null) { // inner class still needs dynamic property sequence + String receiverName = (receiver instanceof ClassExpression ? receiver.getType() : receiverType).toString(false); + String message = "Access to "+ receiverName + "#" + propertyName + " is forbidden"; + controller.getSourceUnit().addError(new SyntaxException(message, receiver)); + } + // GRECLIPSE end MethodCallExpression call = new MethodCallExpression( receiver, "getProperty", - new ArgumentListExpression(new ConstantExpression(property)) + new ArgumentListExpression(new ConstantExpression(propertyName)) ); call.setImplicitThis(implicitThis); call.setSafe(safe); diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java index f52cda22ac..f7c33aff56 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java @@ -56,6 +56,7 @@ import java.util.Map; import java.util.Objects; +import static org.apache.groovy.ast.tools.ClassNodeUtils.getField; import static org.apache.groovy.ast.tools.ExpressionUtils.isThisExpression; import static org.apache.groovy.util.BeanUtils.capitalize; import static org.codehaus.groovy.ast.ClassHelper.BigDecimal_TYPE; @@ -432,11 +433,10 @@ public void makeGroovyObjectGetPropertySite(final Expression receiver, final Str receiverType = controller.getTypeChooser().resolveType(receiver, receiverType); } - String property = propertyName; if (implicitThis && controller.getInvocationWriter() instanceof StaticInvocationWriter) { Expression currentCall = ((StaticInvocationWriter) controller.getInvocationWriter()).getCurrentCall(); if (currentCall != null && currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER) != null) { - property = currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER); + String property = currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER); String[] props = property.split("\\."); BytecodeExpression thisLoader = bytecodeX(CLOSURE_TYPE, mv -> mv.visitVarInsn(ALOAD, 0)); PropertyExpression pexp = propX(thisLoader, constX(props[0]), safe); @@ -449,11 +449,18 @@ public void makeGroovyObjectGetPropertySite(final Expression receiver, final Str } } - if (makeGetPropertyWithGetter(receiver, receiverType, property, safe, implicitThis)) return; - if (makeGetPrivateFieldWithBridgeMethod(receiver, receiverType, property, safe, implicitThis)) return; - if (makeGetField(receiver, receiverType, property, safe, implicitThis)) return; - - MethodCallExpression call = callX(receiver, "getProperty", args(constX(property))); + if (makeGetPropertyWithGetter(receiver, receiverType, propertyName, safe, implicitThis)) return; + if (makeGetPrivateFieldWithBridgeMethod(receiver, receiverType, propertyName, safe, implicitThis)) return; + if (makeGetField(receiver, receiverType, propertyName, safe, implicitThis)) return; + // GRECLIPSE add -- GROOVY-9093 + boolean isScriptVariable = (receiverType.isScript() && receiver instanceof VariableExpression && ((VariableExpression) receiver).getAccessedVariable() == null); + if (!isScriptVariable && controller.getClassNode().getOuterClass() == null) { // inner class still needs dynamic property sequence + String receiverName = (receiver instanceof ClassExpression ? receiver.getType() : receiverType).toString(false); + String message = "Access to "+ receiverName + "#" + propertyName + " is forbidden"; + controller.getSourceUnit().addError(new SyntaxException(message, receiver)); + } + // GRECLIPSE end + MethodCallExpression call = callX(receiver, "getProperty", args(constX(propertyName))); call.setImplicitThis(implicitThis); call.setMethodTarget(GROOVYOBJECT_GETPROPERTY_METHOD); call.setSafe(safe); @@ -529,8 +536,7 @@ private boolean makeGetPropertyWithGetter(final Expression receiver, final Class } boolean makeGetField(final Expression receiver, final ClassNode receiverType, final String fieldName, final boolean safe, final boolean implicitThis) { - FieldNode field = receiverType.getField(fieldName); - + FieldNode field = getField(receiverType, fieldName); // GROOVY-7039: include interface constants if (field != null && isDirectAccessAllowed(field, controller.getClassNode())) { CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); @@ -573,18 +579,6 @@ boolean makeGetField(final Expression receiver, final ClassNode receiverType, fi operandStack.replace(replacementType); return true; } - - for (ClassNode face : receiverType.getInterfaces()) { - // GROOVY-7039 - if (face != receiverType && makeGetField(receiver, face, fieldName, safe, implicitThis)) { - return true; - } - } - - ClassNode superClass = receiverType.getSuperClass(); - if (superClass != null && !OBJECT_TYPE.equals(superClass)) { - return makeGetField(receiver, superClass, fieldName, safe, implicitThis); - } return false; }