Skip to content

Commit aea831c

Browse files
committed
GROOVY-10319
1 parent 5077522 commit aea831c

File tree

5 files changed

+61
-1
lines changed

5 files changed

+61
-1
lines changed

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

+24
Original file line numberDiff line numberDiff line change
@@ -6392,4 +6392,28 @@ public void testCompileStatic10282() {
63926392

63936393
runConformTest(sources, "----------");
63946394
}
6395+
6396+
@Test
6397+
public void testCompileStatic10319() {
6398+
//@formatter:off
6399+
String[] sources = {
6400+
"p/Main.groovy",
6401+
"package p\n" +
6402+
"@groovy.transform.ToString(includeFields=true)\n" +
6403+
"@groovy.transform.CompileStatic\n" +
6404+
"class C implements Cloneable {\n" +
6405+
" private int[] array = [1]\n" +
6406+
" @Override\n" +
6407+
" C clone() {\n" +
6408+
" C c = (C) super.clone()\n" +
6409+
" c.array = array.clone()\n" +
6410+
" return c\n" +
6411+
" }\n" +
6412+
"}\n" +
6413+
"print new C().clone()\n",
6414+
};
6415+
//@formatter:on
6416+
6417+
runConformTest(sources, "p.C([1])");
6418+
}
63956419
}

base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

+12
Original file line numberDiff line numberDiff line change
@@ -5557,6 +5557,18 @@ protected boolean areCategoryMethodCalls(final List<MethodNode> foundMethods, fi
55575557
* @return the methods that are defined on the receiver completed with stubs for future methods
55585558
*/
55595559
protected List<MethodNode> findMethodsWithGenerated(ClassNode receiver, String name) {
5560+
// GRECLIPSE add -- GROOVY-10319
5561+
if (receiver.isArray()) {
5562+
if (name.equals("clone")) {
5563+
MethodNode clone = new MethodNode("clone", Opcodes.ACC_PUBLIC, OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null);
5564+
clone.setDeclaringClass(OBJECT_TYPE); // retain Object for declaringClass and returnType
5565+
clone.setNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, receiver);
5566+
return Collections.singletonList(clone);
5567+
} else {
5568+
return OBJECT_TYPE.getMethods(name);
5569+
}
5570+
}
5571+
// GRECLIPSE end
55605572
List<MethodNode> methods = receiver.getMethods(name);
55615573
// GRECLIPSE add -- GROOVY-9890
55625574
if (receiver.isAbstract()) {

base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

+12
Original file line numberDiff line numberDiff line change
@@ -5236,6 +5236,18 @@ protected boolean areCategoryMethodCalls(final List<MethodNode> foundMethods, fi
52365236
* @return the methods that are defined on the receiver completed with stubs for future methods
52375237
*/
52385238
protected List<MethodNode> findMethodsWithGenerated(final ClassNode receiver, final String name) {
5239+
// GRECLIPSE add -- GROOVY-10319
5240+
if (receiver.isArray()) {
5241+
if (name.equals("clone")) {
5242+
MethodNode clone = new MethodNode("clone", Opcodes.ACC_PUBLIC, OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null);
5243+
clone.setDeclaringClass(OBJECT_TYPE); // retain Object for declaringClass and returnType
5244+
clone.setNodeMetaData(INFERRED_RETURN_TYPE, receiver);
5245+
return Collections.singletonList(clone);
5246+
} else {
5247+
return OBJECT_TYPE.getMethods(name);
5248+
}
5249+
}
5250+
// GRECLIPSE end
52395251
List<MethodNode> methods = receiver.getMethods(name);
52405252
if (receiver.isAbstract()) {
52415253
collectAllInterfaceMethodsByName(receiver, name, methods);

base/org.codehaus.groovy40/src/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -629,10 +629,11 @@ public void makeCall(final Expression origin, final Expression receiver, final E
629629
origMCE.getArguments()
630630
);
631631
MethodNode methodTarget = origMCE.getMethodTarget();
632+
newMCE.setImplicitThis(origMCE.isImplicitThis());
632633
newMCE.setMethodTarget(methodTarget);
633634
newMCE.setSafe(false);
634-
newMCE.setImplicitThis(origMCE.isImplicitThis());
635635
newMCE.setSourcePosition(origMCE);
636+
newMCE.getObjectExpression().setSourcePosition(origMCE.getObjectExpression());
636637
newMCE.visit(controller.getAcg());
637638
compileStack.removeVar(slot.getIndex());
638639
ClassNode returnType = operandStack.getTopOperand();

base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

+11
Original file line numberDiff line numberDiff line change
@@ -4892,6 +4892,17 @@ protected boolean areCategoryMethodCalls(final List<MethodNode> foundMethods, fi
48924892
* @return the methods that are defined on the receiver completed with stubs for future methods
48934893
*/
48944894
protected List<MethodNode> findMethodsWithGenerated(final ClassNode receiver, final String name) {
4895+
if (receiver.isArray()) {
4896+
if (name.equals("clone")) { // GROOVY-10319: array clone -- <https://docs.oracle.com/javase/specs/jls/se8/html/jls-10.html#jls-10.7>
4897+
MethodNode clone = new MethodNode("clone", Opcodes.ACC_PUBLIC, OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null);
4898+
clone.setDeclaringClass(OBJECT_TYPE); // retain Object for declaringClass and returnType
4899+
clone.setNodeMetaData(INFERRED_RETURN_TYPE, receiver);
4900+
return Collections.singletonList(clone);
4901+
} else {
4902+
return OBJECT_TYPE.getMethods(name);
4903+
}
4904+
}
4905+
48954906
List<MethodNode> methods = receiver.getMethods(name);
48964907
if (receiver.isAbstract()) {
48974908
collectAllInterfaceMethodsByName(receiver, name, methods);

0 commit comments

Comments
 (0)