Skip to content

Commit

Permalink
Fix for #1589: array clone() and length members
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Jun 30, 2024
1 parent ae0dd96 commit 94b892d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2009-2020 the original author or authors.
* Copyright 2009-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,6 +15,9 @@
*/
package org.eclipse.jdt.core.groovy.tests.search;

import static org.junit.Assert.assertTrue;

import org.codehaus.groovy.ast.FieldNode;
import org.junit.Test;

public final class ArrayInferencingTests extends InferencingTestSuite {
Expand Down Expand Up @@ -63,13 +66,42 @@ public void testArray7() {
assertType(contents, "length", "java.lang.Integer");
}

@Test
public void testArrayClone1() {
String contents = "def x = new int[0].clone()";
assertType(contents, "x", "int[]");
assertDeclaringType(contents, "clone", "int[]");
}

@Test
public void testArrayClone2() {
String contents = "def x = new Number[0].clone()";
assertType(contents, "x", "java.lang.Number[]");
assertDeclaringType(contents, "clone", "java.lang.Number[]");
}

@Test
public void testArrayClone3() {
String contents = "def x = ([] as Number[][]).clone()";
assertType(contents, "x", "java.lang.Number[][]");
assertDeclaringType(contents, "clone", "java.lang.Number[][]");
}

@Test
public void testArrayClone4() {
String contents = "def m(String... a) { def x = a.clone()}";
assertType(contents, "x", "java.lang.String[]");
assertDeclaringType(contents, "clone", "java.lang.String[]");
}

@Test
public void testArrayLength1() {
String contents = "int[] x = [1, 2]; x.length";
assertType(contents, "length", "java.lang.Integer");

int offset = contents.indexOf("length");
assertDeclaringType(contents, offset, offset + "length".length(), "int[]");
var length = (FieldNode) assertDeclaration(contents, offset, offset + "length".length(), "int[]", "length", DeclarationKind.FIELD);
assertTrue(length.isFinal() && length.isPublic() && length.isSynthetic());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,15 @@ protected ASTNode findDeclarationForDynamicVariable(final VariableExpression var
*/
protected ASTNode findDeclaration(final String name, final ClassNode declaringType, final boolean isLhsExpression, final boolean isStaticExpression, final int directFieldAccess, final List<ClassNode> methodCallArgumentTypes) {
if (declaringType.isArray()) {
// only length exists on arrays
if ("length".equals(name)) {
switch (name) {
case "length":
return createLengthField(declaringType);
case "clone":
MethodNode mn = new MethodNode("clone", Flags.AccPublic, declaringType, Parameter.EMPTY_ARRAY, null, null);
mn.setDeclaringClass(declaringType);
mn.setHasNoRealSourcePosition(true);
mn.setSynthetic(true);
return mn;
}
// otherwise search on object
return findDeclaration(name, VariableScope.OBJECT_CLASS_NODE, isLhsExpression, isStaticExpression, 0, methodCallArgumentTypes);
Expand Down Expand Up @@ -1041,9 +1047,10 @@ protected static PropertyNode createDynamicProperty(final String name, final Cla
}

protected static FieldNode createLengthField(final ClassNode declaringType) {
FieldNode fn = new FieldNode("length", Flags.AccPublic, ClassHelper.int_TYPE, declaringType, null);
FieldNode fn = new FieldNode("length", Flags.AccPublic | Flags.AccFinal, ClassHelper.int_TYPE, declaringType, null);
fn.setDeclaringClass(declaringType);
fn.setHasNoRealSourcePosition(true);
fn.setSynthetic(true);
return fn;
}

Expand Down

0 comments on commit 94b892d

Please sign in to comment.