Skip to content

Commit

Permalink
GROOVY-9093
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Oct 24, 2020
1 parent 514bfbe commit 2759818
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 2759818

Please sign in to comment.