Skip to content

Commit c66e026

Browse files
committed
GROOVY-6954
1 parent 2b4f3ca commit c66e026

File tree

6 files changed

+1971
-49
lines changed

6 files changed

+1971
-49
lines changed

base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/StaticCompilationTests.java

+43-37
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,30 @@ public void testCompileStatic7363() {
12801280
runConformTest(sources, "42");
12811281
}
12821282

1283+
@Test
1284+
public void testCompileStatic7526() {
1285+
//@formatter:off
1286+
String[] sources = {
1287+
"Main.groovy",
1288+
"boolean check(String s) { true }\n" +
1289+
"@groovy.transform.CompileStatic\n" +
1290+
"void test(Pogo pogo) {\n" +
1291+
" if (check(pogo?.field)) {\n" + // VerifyError: Bad type on operand stack
1292+
" print 'works'\n" +
1293+
" }\n" +
1294+
"}\n" +
1295+
"test(new Pogo())\n",
1296+
1297+
"Pogo.groovy",
1298+
"class Pogo {\n" +
1299+
" public String field\n" +
1300+
"}\n",
1301+
};
1302+
//@formatter:on
1303+
1304+
runConformTest(sources, "works");
1305+
}
1306+
12831307
@Test
12841308
public void testCompileStatic7549() {
12851309
//@formatter:off
@@ -5136,42 +5160,24 @@ public void testCompileStatic9555() {
51365160

51375161
@Test
51385162
public void testCompileStatic9558() {
5139-
//@formatter:off
5140-
String[] sources = {
5141-
"Main.groovy",
5142-
"@groovy.transform.CompileStatic\n" +
5143-
"void test() {\n" +
5144-
" def config = new org.codehaus.groovy.control.CompilerConfiguration()\n" +
5145-
" config.tap {\n" +
5146-
" optimizationOptions['indy'] = true\n" + // Cannot cast object '...' with class 'CompilerConfiguration' to class 'Map'
5147-
" optimizationOptions.indy = true\n" +
5148-
" }\n" +
5149-
"}\n" +
5150-
"test()\n",
5151-
};
5152-
//@formatter:on
5153-
5154-
runConformTest(sources, "");
5155-
}
5156-
5157-
@Test
5158-
public void testCompileStatic9558a() {
5159-
//@formatter:off
5160-
String[] sources = {
5161-
"Main.groovy",
5162-
"@groovy.transform.CompileStatic\n" +
5163-
"void test() {\n" +
5164-
" def config = new org.codehaus.groovy.control.CompilerConfiguration()\n" +
5165-
" config.with {\n" +
5166-
" optimizationOptions['indy'] = true\n" + // Cannot cast object '...' with class 'CompilerConfiguration' to class 'Map'
5167-
" optimizationOptions.indy = true\n" +
5168-
" }\n" +
5169-
"}\n" +
5170-
"test()\n",
5171-
};
5172-
//@formatter:on
5163+
for (String dgm : new String[] {"tap", "with"}) {
5164+
//@formatter:off
5165+
String[] sources = {
5166+
"Main.groovy",
5167+
"@groovy.transform.CompileStatic\n" +
5168+
"void test() {\n" +
5169+
" def config = new org.codehaus.groovy.control.CompilerConfiguration()\n" +
5170+
" config." + dgm + " {\n" +
5171+
" optimizationOptions['indy'] = true\n" + // Cannot cast object '...' with class 'CompilerConfiguration' to class 'Map'
5172+
" optimizationOptions.indy = true\n" +
5173+
" }\n" +
5174+
"}\n" +
5175+
"test()\n",
5176+
};
5177+
//@formatter:on
51735178

5174-
runConformTest(sources, "");
5179+
runConformTest(sources);
5180+
}
51755181
}
51765182

51775183
@Test
@@ -5272,7 +5278,7 @@ public void testCompileStatic9603() {
52725278
};
52735279
//@formatter:on
52745280

5275-
runConformTest(sources, "");
5281+
runConformTest(sources);
52765282
}
52775283

52785284
@Test
@@ -6348,7 +6354,7 @@ public void testCompileStatic10089() {
63486354

63496355
@Test
63506356
public void testCompileStatic10197() {
6351-
for (String override : new String[]{"int getBaz() {1}", "final int baz = 1"}) {
6357+
for (String override : new String[] {"int getBaz() {1}", "final int baz = 1"}) {
63526358
//@formatter:off
63536359
String[] sources = {
63546360
"Main.groovy",

base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java

+47-10
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ private void writeNumberNumberCall(final Expression receiver, final String messa
819819

820820
@Override
821821
public void fallbackAttributeOrPropertySite(PropertyExpression expression, Expression objectExpression, String name, MethodCallerMultiAdapter adapter) {
822-
/* GRECLIPSE edit -- GROOVY-7304, GROOVY-9892
822+
/* GRECLIPSE edit -- GROOVY-6954, GROOVY-7304, GROOVY-9892
823823
if (name!=null &&
824824
(adapter == AsmClassGenerator.setField || adapter == AsmClassGenerator.setGroovyObjectField)
825825
) {
@@ -833,22 +833,27 @@ public void fallbackAttributeOrPropertySite(PropertyExpression expression, Expre
833833
}
834834
}
835835
*/
836-
if (name != null && controller.getCompileStack().isLHS()) {
837-
ClassNode classNode = controller.getClassNode();
838-
ClassNode receiverType = getPropertyOwnerType(objectExpression);
836+
CompileStack compileStack = controller.getCompileStack();
837+
OperandStack operandStack = controller.getOperandStack();
838+
839+
if (name != null && compileStack.isLHS()) {
840+
boolean[] isClassReceiver = new boolean[1];
841+
ClassNode receiverType = getPropertyOwnerType(objectExpression, isClassReceiver);
839842
if (adapter == AsmClassGenerator.setField || adapter == AsmClassGenerator.setGroovyObjectField) {
840843
if (setField(expression, objectExpression, receiverType, name)) return;
841-
} else if (isThisExpression(objectExpression)) {
844+
}
845+
if (isThisExpression(objectExpression)) {
846+
ClassNode classNode = controller.getClassNode();
842847
FieldNode fieldNode = receiverType.getField(name);
843848
if (fieldNode != null && fieldNode.isPrivate() && !receiverType.equals(classNode)
844849
&& StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(receiverType, classNode)) {
845850
Map<String, MethodNode> mutators = receiverType.redirect().getNodeMetaData(StaticCompilationMetadataKeys.PRIVATE_FIELDS_MUTATORS);
846851
if (mutators != null) {
847852
MethodNode methodNode = mutators.get(name);
848853
if (methodNode != null) {
849-
ClassNode rhsType = controller.getOperandStack().getTopOperand();
850-
int i = controller.getCompileStack().defineTemporaryVariable("$rhsValue", rhsType, true);
851-
VariableSlotLoader rhsValue = new VariableSlotLoader(rhsType, i, controller.getOperandStack());
854+
ClassNode rhsType = operandStack.getTopOperand();
855+
int i = compileStack.defineTemporaryVariable("$rhs", rhsType, true);
856+
VariableSlotLoader rhsValue = new VariableSlotLoader(rhsType, i, operandStack);
852857

853858
MethodCallExpression call = new MethodCallExpression(objectExpression, methodNode.getName(), new ArgumentListExpression(fieldNode.isStatic() ? new ConstantExpression(null) : objectExpression, rhsValue));
854859
call.setImplicitThis(expression.isImplicitThis());
@@ -857,13 +862,45 @@ public void fallbackAttributeOrPropertySite(PropertyExpression expression, Expre
857862
call.setMethodTarget(methodNode);
858863
call.visit(controller.getAcg());
859864

860-
controller.getCompileStack().removeVar(i);
861-
controller.getOperandStack().pop();
865+
compileStack.removeVar(i);
866+
operandStack.pop();
862867
return;
863868
}
864869
}
865870
}
866871
}
872+
if (isOrImplements(receiverType, MAP_TYPE) && !isClassReceiver[0]) {
873+
MethodVisitor mv = controller.getMethodVisitor();
874+
875+
// store value in temporary variable
876+
ClassNode rhsType = operandStack.getTopOperand();
877+
int rhs = compileStack.defineTemporaryVariable("$rhs", rhsType, true);
878+
879+
// push receiver on stack
880+
compileStack.pushLHS(false);
881+
objectExpression.visit(controller.getAcg());
882+
compileStack.popLHS();
883+
884+
// check if receiver null
885+
Label skip = new Label();
886+
if (expression.isSafe()) {
887+
mv.visitInsn(DUP);
888+
mv.visitJumpInsn(IFNULL, skip);
889+
}
890+
891+
mv.visitLdcInsn(name);
892+
BytecodeHelper.load(mv, rhsType, rhs);
893+
if (isPrimitiveType(rhsType)) BytecodeHelper.doCastToWrappedType(mv, rhsType, getWrapper(rhsType));
894+
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
895+
896+
if (expression.isSafe()) {
897+
mv.visitLabel(skip);
898+
}
899+
compileStack.removeVar(rhs);
900+
operandStack.pop();
901+
return;
902+
}
903+
867904
}
868905
// GRECLIPSE end
869906
super.fallbackAttributeOrPropertySite(expression, objectExpression, name, adapter);

base/org.codehaus.groovy30/.checkstyle

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<file-match-pattern match-pattern="groovy/classgen/asm/StatementWriter.java" include-pattern="false" />
4848
<file-match-pattern match-pattern="groovy/classgen/asm/sc/StaticInvocationWriter.java" include-pattern="false" />
4949
<file-match-pattern match-pattern="groovy/classgen/asm/sc/StaticPropertyAccessHelper.java" include-pattern="false" />
50-
<file-match-pattern match-pattern="groovy/classgen/asm/sc/StaticTypes(Closure|MethodReferenceExpression)Writer.java" include-pattern="false" />
50+
<file-match-pattern match-pattern="groovy/classgen/asm/sc/StaticTypes(CallSite|Closure|MethodReferenceExpression)Writer.java" include-pattern="false" />
5151
<file-match-pattern match-pattern="groovy/control/CompilationUnit.java" include-pattern="false" />
5252
<file-match-pattern match-pattern="groovy/control/CompilerConfiguration.java" include-pattern="false" />
5353
<file-match-pattern match-pattern="groovy/control/ErrorCollector.java" include-pattern="false" />

0 commit comments

Comments
 (0)