diff --git a/ide-test/org.codehaus.groovy.eclipse.dsl.tests/src/org/codehaus/groovy/eclipse/dsl/tests/DSLInferencingTests.groovy b/ide-test/org.codehaus.groovy.eclipse.dsl.tests/src/org/codehaus/groovy/eclipse/dsl/tests/DSLInferencingTests.groovy index 620a2f2fc4..a3548b5136 100644 --- a/ide-test/org.codehaus.groovy.eclipse.dsl.tests/src/org/codehaus/groovy/eclipse/dsl/tests/DSLInferencingTests.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.dsl.tests/src/org/codehaus/groovy/eclipse/dsl/tests/DSLInferencingTests.groovy @@ -1168,6 +1168,39 @@ final class DSLInferencingTests extends DSLInferencingTestSuite { assertType(contents, 0, contents.length(), 'java.util.Map') } + @Test + void testWildcardType1() { + createDsls '''\ + contribute(currentType()) { + property name:'prop', type:'Class' + } + '''.stripIndent() + String contents = 'prop' + assertType(contents, 0, contents.length(), 'java.lang.Class') + } + + @Test + void testWildcardType2() { + createDsls '''\ + contribute(currentType()) { + property name:'prop', type:'Map' + } + '''.stripIndent() + String contents = 'prop' + assertType(contents, 0, contents.length(), 'java.util.Map') + } + + @Test + void testWildcardType3() { + createDsls '''\ + contribute(currentType()) { + property name:'prop', type:'Map>' + } + '''.stripIndent() + String contents = 'prop' + assertType(contents, 0, contents.length(), 'java.util.Map>') + } + @Test void testNestedCalls() { createDsls '''\ diff --git a/ide/org.codehaus.groovy.eclipse.dsl/src/org/codehaus/groovy/eclipse/dsl/lookup/ResolverCache.java b/ide/org.codehaus.groovy.eclipse.dsl/src/org/codehaus/groovy/eclipse/dsl/lookup/ResolverCache.java index b4005f90b3..eaafd6ad95 100644 --- a/ide/org.codehaus.groovy.eclipse.dsl/src/org/codehaus/groovy/eclipse/dsl/lookup/ResolverCache.java +++ b/ide/org.codehaus.groovy.eclipse.dsl/src/org/codehaus/groovy/eclipse/dsl/lookup/ResolverCache.java @@ -83,22 +83,26 @@ public ClassNode resolve(String name) { // now recur down through the type parameters if (typeParamStart > 0 && type.isUsingGenerics()) { - String[] typeParameterNames = componentName.substring(typeParamStart + 1, componentName.length() - 1).split(","); + String[] typeParameterNames = componentName.substring(typeParamStart + 1, componentName.length() - 1).split("\\s*,\\s*"); ClassNode[] typeParameterTypes = new ClassNode[typeParameterNames.length]; for (int i = 0; i < typeParameterNames.length; i += 1) { - typeParameterTypes[i] = resolve(typeParameterNames[i]); // TODO: Handle "? extends T" and "? super T" + typeParameterTypes[i] = resolve(typeParameterNames[i].replaceFirst("^\\?\\s+(extends|super)\\s+", "")); } type = VariableScope.clone(type); GenericsType[] genericsTypes = type.getGenericsTypes(); // need to be careful here...there may be too many or too few type parameters for (int i = 0; i < genericsTypes.length && i < typeParameterTypes.length; i += 1) { + if (typeParameterNames[i].startsWith("?")) { + genericsTypes[i] = GenericsUtils.buildWildcardType(typeParameterTypes[i]); + } else { + genericsTypes[i].setPlaceholder(false); // must precede setType + genericsTypes[i].setName(typeParameterTypes[i].getName()); + genericsTypes[i].setType(typeParameterTypes[i]); + genericsTypes[i].setUpperBounds(null); + genericsTypes[i].setLowerBound(null); + genericsTypes[i].setWildcard(false); + } genericsTypes[i].setResolved(true); - genericsTypes[i].setWildcard(false); - genericsTypes[i].setLowerBound(null); - genericsTypes[i].setUpperBounds(null); - genericsTypes[i].setPlaceholder(false); - genericsTypes[i].setType(typeParameterTypes[i]); - genericsTypes[i].setName(typeParameterTypes[i].getName()); } nameTypeCache.put(componentName, type); }