Skip to content

Commit a31702c

Browse files
committed
GROOVY-10395
1 parent 01289d0 commit a31702c

File tree

4 files changed

+107
-1
lines changed

4 files changed

+107
-1
lines changed

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

+47
Original file line numberDiff line numberDiff line change
@@ -6978,4 +6978,51 @@ public void testCompileStatic10394() {
69786978

69796979
runConformTest(sources, "12");
69806980
}
6981+
6982+
@Test
6983+
public void testCompileStatic10395() {
6984+
for (String type : new String[] {"int", "long", "short", "byte", "char", "double", "float"}) {
6985+
//@formatter:off
6986+
String[] sources = {
6987+
"Main.groovy",
6988+
"@groovy.transform.CompileStatic\n" +
6989+
"int test(" + type + " a, " + type + " b) {\n" +
6990+
" a <=> b\n" +
6991+
"}\n" +
6992+
"assert test((" + type + ")0,(" + type + ")0) == 0\n" +
6993+
"assert test((" + type + ")0,(" + type + ")1) < 0\n" +
6994+
"assert test((" + type + ")1,(" + type + ")0) > 0\n",
6995+
};
6996+
//@formatter:on
6997+
6998+
runConformTest(sources);
6999+
7000+
String result = disassemble(getOutputFile("Main.class"), 1);
7001+
int pos = result.indexOf("ScriptBytecodeAdapter.compareTo");
7002+
assertTrue(pos < 0);
7003+
}
7004+
}
7005+
7006+
@Test
7007+
public void testCompileStatic10395b() {
7008+
//@formatter:off
7009+
String[] sources = {
7010+
"Main.groovy",
7011+
"@groovy.transform.CompileStatic\n" +
7012+
"int test(boolean a, boolean b) {\n" +
7013+
" a <=> b\n" +
7014+
"}\n" +
7015+
"assert test(false,false) == 0\n" +
7016+
"assert test(false,true) < 0\n" +
7017+
"assert test(true,false) > 0\n" +
7018+
"assert test(true,true) == 0\n",
7019+
};
7020+
//@formatter:on
7021+
7022+
runConformTest(sources);
7023+
7024+
String result = disassemble(getOutputFile("Main.class"), 1);
7025+
int pos = result.indexOf("ScriptBytecodeAdapter.compareTo");
7026+
assertTrue(pos < 0);
7027+
}
69817028
}

base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/sc/transformers/BinaryExpressionTransformer.java

+22
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,28 @@ Expression transformBinaryExpression(final BinaryExpression bin) {
148148
compareToNullExpression.setSourcePosition(bin);
149149
return compareToNullExpression;
150150
}
151+
// GRECLIPSE add -- GROOVY-10395
152+
} else if (operationType == Types.COMPARE_TO) {
153+
ClassNode leftType = staticCompilationTransformer.getTypeChooser().resolveType(leftExpression, staticCompilationTransformer.getClassNode());
154+
ClassNode rightType = staticCompilationTransformer.getTypeChooser().resolveType(rightExpression, staticCompilationTransformer.getClassNode());
155+
// same-type primitive compare
156+
if (leftType.equals(rightType)
157+
&& ClassHelper.isPrimitiveType(leftType)
158+
|| ClassHelper.isPrimitiveType(rightType)) {
159+
ClassNode wrapperType = ClassHelper.getWrapper(leftType);
160+
Expression leftAndRight = new ArgumentListExpression(
161+
staticCompilationTransformer.transform(leftExpression),
162+
staticCompilationTransformer.transform(rightExpression)
163+
);
164+
// transform "a <=> b" into "[Integer|Long|Short|Byte|Double|Float|...].compare(a,b)"
165+
MethodCallExpression call = new MethodCallExpression(new ClassExpression(wrapperType), "compare", leftAndRight);
166+
call.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
167+
call.setMethodTarget(wrapperType.getMethods("compare").get(0));
168+
call.setImplicitThis(false);
169+
call.setSourcePosition(bin);
170+
return call;
171+
}
172+
// GRECLIPSE end
151173
} else if (operationType == Types.KEYWORD_IN) {
152174
return convertInOperatorToTernary(bin, rightExpression, leftExpression);
153175
}

base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/sc/transformers/BinaryExpressionTransformer.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public Expression transformBinaryExpression(final BinaryExpression bin) {
148148
compareToNullExpression.setSourcePosition(bin);
149149
return compareToNullExpression;
150150
}
151-
// GRECLIPSE add -- GROOVY-10377
151+
// GRECLIPSE add -- GROOVY-10377, GROOVY-10395
152152
} else if (operationType == Types.COMPARE_IDENTICAL || operationType == Types.COMPARE_NOT_IDENTICAL) {
153153
if (isNullConstant(rightExpression)) {
154154
CompareToNullExpression ctn = new CompareToNullExpression(staticCompilationTransformer.transform(leftExpression), operationType == Types.COMPARE_IDENTICAL);
@@ -166,6 +166,25 @@ public Expression transformBinaryExpression(final BinaryExpression bin) {
166166
cid.setSourcePosition(bin);
167167
return cid;
168168
}
169+
} else if (operationType == Types.COMPARE_TO) {
170+
ClassNode leftType = findType(leftExpression), rightType = findType(rightExpression);
171+
// same-type primitive compare
172+
if (leftType.equals(rightType)
173+
&& ClassHelper.isPrimitiveType(leftType)
174+
|| ClassHelper.isPrimitiveType(rightType)) {
175+
ClassNode wrapperType = ClassHelper.getWrapper(leftType);
176+
Expression leftAndRight = args(
177+
staticCompilationTransformer.transform(leftExpression),
178+
staticCompilationTransformer.transform(rightExpression)
179+
);
180+
// transform "a <=> b" into "[Integer|Long|Short|Byte|Double|Float|...].compare(a,b)"
181+
MethodCallExpression call = callX(classX(wrapperType), "compare", leftAndRight);
182+
call.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
183+
call.setMethodTarget(wrapperType.getMethods("compare").get(0));
184+
call.setImplicitThis(false);
185+
call.setSourcePosition(bin);
186+
return call;
187+
}
169188
// GRECLIPSE end
170189
} else if (operationType == Types.KEYWORD_IN) {
171190
return staticCompilationTransformer.transform(convertInOperatorToTernary(bin, rightExpression, leftExpression));

base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/sc/transformers/BinaryExpressionTransformer.java

+18
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,24 @@ private Expression transformRelationComparison(final BinaryExpression bin) {
288288
Expression leftExpression = bin.getLeftExpression(), rightExpression = bin.getRightExpression();
289289
ClassNode leftType = findType(leftExpression), rightType = findType(rightExpression);
290290

291+
// same-type primitive compare
292+
if (leftType.equals(rightType)
293+
&& ClassHelper.isPrimitiveType(leftType)
294+
|| ClassHelper.isPrimitiveType(rightType)) {
295+
ClassNode wrapperType = ClassHelper.getWrapper(leftType);
296+
Expression leftAndRight = args(
297+
staticCompilationTransformer.transform(leftExpression),
298+
staticCompilationTransformer.transform(rightExpression)
299+
);
300+
// transform "a <=> b" into "[Integer|Long|Short|Byte|Double|Float|...].compare(a,b)"
301+
MethodCallExpression call = callX(classX(wrapperType), "compare", leftAndRight);
302+
call.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
303+
call.setMethodTarget(wrapperType.getMethods("compare").get(0));
304+
call.setImplicitThis(false);
305+
call.setSourcePosition(bin);
306+
return call;
307+
}
308+
291309
if (leftType.implementsInterface(ClassHelper.COMPARABLE_TYPE)
292310
&& rightType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
293311
// GROOVY-5644, GROOVY-6137, GROOVY-7473, GROOVY-10394: null safety and one-time evaluation

0 commit comments

Comments
 (0)