Repository: groovy Updated Branches: refs/heads/master 432a8e5ed -> b739c2a9b
Make sure generics are correct for generified return types. Fixes https://issues.apache.org/jira/browse/GROOVY-7846 Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/8ee9cbc8 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/8ee9cbc8 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/8ee9cbc8 Branch: refs/heads/master Commit: 8ee9cbc8f1bca13f6c3fe0594224ea8a45554ed5 Parents: 432a8e5 Author: graemerocher <graeme.roc...@gmail.com> Authored: Fri May 27 11:26:20 2016 +0200 Committer: paulk <pa...@asert.com.au> Committed: Tue May 31 14:36:16 2016 +1000 ---------------------------------------------------------------------- .../groovy/transform/trait/TraitComposer.java | 21 ++++---- .../transform/traitx/Groovy7846Bug.groovy | 54 ++++++++++++++++++++ 2 files changed, 66 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/8ee9cbc8/src/main/org/codehaus/groovy/transform/trait/TraitComposer.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/transform/trait/TraitComposer.java b/src/main/org/codehaus/groovy/transform/trait/TraitComposer.java index 76e47b6..6804aae 100644 --- a/src/main/org/codehaus/groovy/transform/trait/TraitComposer.java +++ b/src/main/org/codehaus/groovy/transform/trait/TraitComposer.java @@ -59,17 +59,10 @@ import org.codehaus.groovy.transform.sc.StaticCompileTransformation; import org.objectweb.asm.Opcodes; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse; +import static org.codehaus.groovy.ast.tools.GenericsUtils.newClass; /** * This class contains a static utility method {@link #doExtendTraits(org.codehaus.groovy.ast.ClassNode, org.codehaus.groovy.control.SourceUnit, org.codehaus.groovy.control.CompilationUnit)} @@ -289,9 +282,12 @@ public abstract class TraitComposer { mce.setImplicitThis(false); genericsSpec = GenericsUtils.addMethodGenerics(helperMethod,genericsSpec); + Map<String,ClassNode> methodSpec = new HashMap<String, ClassNode>(); + methodSpec = GenericsUtils.addMethodGenerics(helperMethod,methodSpec); ClassNode[] exceptionNodes = correctToGenericsSpecRecurse(genericsSpec, copyExceptions(helperMethod.getExceptions())); ClassNode fixedReturnType = correctToGenericsSpecRecurse(genericsSpec, helperMethod.getReturnType()); + Expression forwardExpression = genericsSpec.isEmpty()?mce:new CastExpression(fixedReturnType,mce); int access = helperMethod.getModifiers(); // we could rely on the first parameter name ($static$self) but that information is not @@ -324,6 +320,13 @@ public abstract class TraitComposer { newGt = removeNonPlaceHolders(newGt); forwarder.setGenericsTypes(newGt); } + else { + GenericsType[] genericsTypes = helperMethod.getGenericsTypes(); + if(genericsTypes != null) { + GenericsType[] newGt = GenericsUtils.applyGenericsContextToPlaceHolders(methodSpec, helperMethod.getGenericsTypes()); + forwarder.setGenericsTypes(newGt); + } + } // add a helper annotation indicating that it is a bridge method AnnotationNode bridgeAnnotation = new AnnotationNode(Traits.TRAITBRIDGE_CLASSNODE); bridgeAnnotation.addMember("traitClass", new ClassExpression(trait)); http://git-wip-us.apache.org/repos/asf/groovy/blob/8ee9cbc8/src/test/org/codehaus/groovy/transform/traitx/Groovy7846Bug.groovy ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/transform/traitx/Groovy7846Bug.groovy b/src/test/org/codehaus/groovy/transform/traitx/Groovy7846Bug.groovy new file mode 100644 index 0000000..5512235 --- /dev/null +++ b/src/test/org/codehaus/groovy/transform/traitx/Groovy7846Bug.groovy @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.transform.traitx + +import org.codehaus.groovy.ast.ClassNode + +class Groovy7846Bug extends GroovyTestCase { + + void testTraitsShouldAllowGenerifiedReturnTypesInStaticMethods() { + def cl = new GroovyClassLoader() + cl.parseClass(''' + +class Foo { + static <T> T withClient(@DelegatesTo(Foo) Closure<T> callable ) { + callable.call() + } +} +trait TraitWithStaticMethod<D> { + + static Collection<D> asCollection(D type) { + return [type] + } + + static <T> T withClient(@DelegatesTo(Foo) Closure<T> callable ) { + callable.call() + } +} +''') + Class cls = cl.parseClass(''' +class Bar implements TraitWithStaticMethod<Bar> {} + +''') + + assert new ClassNode(cls).methods + assert cls.withClient { true } + } +} +