Skip to content

Commit 2730f3a

Browse files
committed
GROOVY-10056, GROOVY-10062
1 parent 9615572 commit 2730f3a

File tree

4 files changed

+89
-17
lines changed

4 files changed

+89
-17
lines changed

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

+38
Original file line numberDiff line numberDiff line change
@@ -2335,4 +2335,42 @@ public void testTypeChecked10053() {
23352335

23362336
runConformTest(sources, "[42]");
23372337
}
2338+
2339+
@Test
2340+
public void testTypeChecked10056() {
2341+
//@formatter:off
2342+
String[] sources = {
2343+
"Main.groovy",
2344+
"@groovy.transform.TypeChecked\n" +
2345+
"void test(String[][] arrayArray) {\n" +
2346+
" print Arrays.asList(arrayArray).get(0).length\n" +
2347+
"}\n" +
2348+
"String[][] arrayArray = [\n" +
2349+
" ['a','b','c'],\n" +
2350+
" ['d','e','f']\n" +
2351+
"]\n" +
2352+
"test(arrayArray)\n",
2353+
};
2354+
//@formatter:on
2355+
2356+
runConformTest(sources, "3");
2357+
}
2358+
2359+
@Test
2360+
public void testTypeChecked10062() {
2361+
//@formatter:off
2362+
String[] sources = {
2363+
"Main.groovy",
2364+
"def <T> T m(T t, ... zeroOrMore) { t }\n" +
2365+
"@groovy.transform.TypeChecked\n" +
2366+
"void test() {\n" +
2367+
" def obj = m(42)\n" +
2368+
" print obj.intValue()\n" +
2369+
"}\n" +
2370+
"test()\n",
2371+
};
2372+
//@formatter:on
2373+
2374+
runConformTest(sources, "42");
2375+
}
23382376
}

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

+19-14
Original file line numberDiff line numberDiff line change
@@ -5826,32 +5826,43 @@ protected ClassNode inferReturnTypeGenerics(
58265826
boolean isVargs = isVargs(parameters);
58275827
ArgumentListExpression argList = InvocationWriter.makeArgumentList(arguments);
58285828
List<Expression> expressions = argList.getExpressions();
5829+
/* GRECLIPSE edit -- GROOVY-9996, GROOVY-10056, GROOVY-10062
58295830
int paramLength = parameters.length;
58305831
if (expressions.size() >= paramLength) {
58315832
for (int i = 0; i < paramLength; i += 1) {
5832-
// GRECLIPSE add -- GROOVY-9984: skip null
5833-
if (isNullConstant(expressions.get(i))) continue;
5834-
// GRECLIPSE end
58355833
boolean lastArg = (i == paramLength - 1);
58365834
ClassNode type = parameters[i].getType();
5837-
/* GRECLIPSE edit -- GROOVY-9996
58385835
ClassNode actualType = getType(expressions.get(i));
5839-
*/
5840-
ClassNode actualType = getDeclaredOrInferredType(expressions.get(i));
5841-
// GRECLIPSE end
58425836
while (!type.isUsingGenerics() && type.isArray() && actualType.isArray()) {
58435837
type = type.getComponentType();
58445838
actualType = actualType.getComponentType();
58455839
}
5840+
*/
5841+
int nArguments = expressions.size(), nParams = parameters.length;
5842+
if (isVargs ? nArguments >= nParams - 1 : nArguments == nParams) {
5843+
for (int i = 0; i < nArguments; i += 1) {
5844+
if (isNullConstant(expressions.get(i))) continue; // GROOVY-9984
5845+
ClassNode type = parameters[Math.min(i, nParams - 1)].getType();
5846+
ClassNode actualType = getDeclaredOrInferredType(expressions.get(i));
5847+
// GRECLIPSE end
58465848
if (isUsingGenericsOrIsArrayUsingGenerics(type)) {
5847-
/* GRECLIPSE edit -- GROOVY-9803
5849+
/* GRECLIPSE edit -- GROOVY-9803, GROOVY-10056, GROOVY-10062
58485850
if (implementsInterfaceOrIsSubclassOf(actualType, CLOSURE_TYPE) &&
58495851
isSAMType(type)) {
58505852
// implicit closure coercion in action!
58515853
Map<GenericsTypeName, GenericsType> pholders = applyGenericsContextToParameterClass(resolvedPlaceholders, type);
58525854
actualType = convertClosureTypeToSAMType(expressions.get(i), actualType, type, pholders);
58535855
}
5856+
if (isVargs && lastArg && actualType.isArray()) {
5857+
actualType = actualType.getComponentType();
5858+
}
5859+
if (isVargs && lastArg && type.isArray()) {
5860+
type = type.getComponentType();
5861+
}
58545862
*/
5863+
if (isVargs && (i >= nParams || (i == nParams - 1 && (nArguments > nParams || !actualType.isArray())))) {
5864+
type = type.getComponentType();
5865+
}
58555866
if (actualType.isDerivedFrom(CLOSURE_TYPE)) {
58565867
MethodNode sam = findSAM(type);
58575868
if (sam != null) { // implicit closure coercion in action!
@@ -5861,12 +5872,6 @@ protected ClassNode inferReturnTypeGenerics(
58615872
}
58625873
}
58635874
// GRECLIPSE end
5864-
if (isVargs && lastArg && actualType.isArray()) {
5865-
actualType = actualType.getComponentType();
5866-
}
5867-
if (isVargs && lastArg && type.isArray()) {
5868-
type = type.getComponentType();
5869-
}
58705875
actualType = wrapTypeIfNecessary(actualType);
58715876

58725877
Map<GenericsTypeName, GenericsType> connections = new HashMap<GenericsTypeName, GenericsType>();

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

+16-3
Original file line numberDiff line numberDiff line change
@@ -5545,20 +5545,31 @@ protected ClassNode inferReturnTypeGenerics(final ClassNode receiver, final Meth
55455545
List<Expression> expressions = InvocationWriter.makeArgumentList(arguments).getExpressions();
55465546
Parameter[] parameters = method.getParameters();
55475547
boolean isVargs = isVargs(parameters);
5548+
/* GRECLIPSE edit -- GROOVY-10056, GROOVY-10062
55485549
int paramLength = parameters.length;
55495550
if (expressions.size() >= paramLength) {
55505551
for (int i = 0; i < paramLength; i += 1) {
5551-
// GRECLIPSE add -- GROOVY-9984: skip null
5552-
if (isNullConstant(expressions.get(i))) continue;
5553-
// GRECLIPSE end
55545552
boolean lastArg = (i == paramLength - 1);
55555553
ClassNode paramType = parameters[i].getType();
55565554
ClassNode argumentType = getDeclaredOrInferredType(expressions.get(i));
55575555
while (paramType.isArray() && argumentType.isArray()) {
55585556
paramType = paramType.getComponentType();
55595557
argumentType = argumentType.getComponentType();
55605558
}
5559+
*/
5560+
int nArguments = expressions.size(), nParams = parameters.length;
5561+
if (isVargs ? nArguments >= nParams - 1 : nArguments == nParams) {
5562+
for (int i = 0; i < nArguments; i += 1) {
5563+
if (isNullConstant(expressions.get(i))) continue; // GROOVY-9984
5564+
ClassNode paramType = parameters[Math.min(i, nParams - 1)].getType();
5565+
ClassNode argumentType = getDeclaredOrInferredType(expressions.get(i));
5566+
// GRECLIPSE end
55615567
if (isUsingGenericsOrIsArrayUsingGenerics(paramType)) {
5568+
// GRECLIPSE add -- use element type if supplying array param with multiple arguments or single non-array argument
5569+
if (isVargs && (i >= nParams || (i == nParams - 1 && (nArguments > nParams || !argumentType.isArray())))) {
5570+
paramType = paramType.getComponentType();
5571+
}
5572+
// GRECLIPSE end
55625573
if (argumentType.isDerivedFrom(CLOSURE_TYPE)) {
55635574
MethodNode sam = findSAM(paramType);
55645575
if (sam != null) { // implicit closure coercion in action!
@@ -5567,12 +5578,14 @@ protected ClassNode inferReturnTypeGenerics(final ClassNode receiver, final Meth
55675578
applyGenericsContextToParameterClass(resolvedPlaceholders, paramType));
55685579
}
55695580
}
5581+
/* GRECLIPSE edit -- GROOVY-10056, GROOVY-10062
55705582
if (isVargs && lastArg && argumentType.isArray()) {
55715583
argumentType = argumentType.getComponentType();
55725584
}
55735585
if (isVargs && lastArg && paramType.isArray()) {
55745586
paramType = paramType.getComponentType();
55755587
}
5588+
*/
55765589
argumentType = wrapTypeIfNecessary(argumentType);
55775590

55785591
Map<GenericsTypeName, GenericsType> connections = new HashMap<>();

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

+16
Original file line numberDiff line numberDiff line change
@@ -5346,6 +5346,7 @@ protected ClassNode inferReturnTypeGenerics(final ClassNode receiver, final Meth
53465346
List<Expression> expressions = InvocationWriter.makeArgumentList(arguments).getExpressions();
53475347
Parameter[] parameters = method.getParameters();
53485348
boolean isVargs = isVargs(parameters);
5349+
/* GRECLIPSE edit -- GROOVY-10056, GROOVY-10062
53495350
int paramLength = parameters.length;
53505351
if (expressions.size() >= paramLength) {
53515352
for (int i = 0; i < paramLength; i += 1) {
@@ -5358,7 +5359,20 @@ protected ClassNode inferReturnTypeGenerics(final ClassNode receiver, final Meth
53585359
paramType = paramType.getComponentType();
53595360
argumentType = argumentType.getComponentType();
53605361
}
5362+
*/
5363+
int nArguments = expressions.size(), nParams = parameters.length;
5364+
if (isVargs ? nArguments >= nParams - 1 : nArguments == nParams) {
5365+
for (int i = 0; i < nArguments; i += 1) {
5366+
if (isNullConstant(expressions.get(i))) continue; // GROOVY-9984
5367+
ClassNode paramType = parameters[Math.min(i, nParams - 1)].getType();
5368+
ClassNode argumentType = getDeclaredOrInferredType(expressions.get(i));
5369+
// GRECLIPSE end
53615370
if (isUsingGenericsOrIsArrayUsingGenerics(paramType)) {
5371+
// GRECLIPSE add -- use element type if supplying array param with multiple arguments or single non-array argument
5372+
if (isVargs && (i >= nParams || (i == nParams - 1 && (nArguments > nParams || !argumentType.isArray())))) {
5373+
paramType = paramType.getComponentType();
5374+
}
5375+
// GRECLIPSE end
53625376
if (argumentType.isDerivedFrom(CLOSURE_TYPE)) {
53635377
MethodNode sam = findSAM(paramType);
53645378
if (sam != null) { // implicit closure coercion in action!
@@ -5367,12 +5381,14 @@ protected ClassNode inferReturnTypeGenerics(final ClassNode receiver, final Meth
53675381
applyGenericsContextToParameterClass(resolvedPlaceholders, paramType));
53685382
}
53695383
}
5384+
/* GRECLIPSE edit -- GROOVY-10056, GROOVY-10062
53705385
if (isVargs && lastArg && argumentType.isArray()) {
53715386
argumentType = argumentType.getComponentType();
53725387
}
53735388
if (isVargs && lastArg && paramType.isArray()) {
53745389
paramType = paramType.getComponentType();
53755390
}
5391+
*/
53765392
argumentType = wrapTypeIfNecessary(argumentType);
53775393

53785394
Map<GenericsTypeName, GenericsType> connections = new HashMap<>();

0 commit comments

Comments
 (0)