diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/FragmentArgHandler.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/FragmentArgHandler.java index 529dfb1939..56071d5796 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/FragmentArgHandler.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/FragmentArgHandler.java @@ -109,7 +109,7 @@ private void createBuilderInjectionMethod(Element element, EFragmentHolder holde TypeMirror type = codeModelHelper.getActualType(element, holder); JClass paramClass = codeModelHelper.typeMirrorToJClass(type, holder); - JMethod method = builderClass.method(PUBLIC, builderClass, fieldName); + JMethod method = builderClass.method(PUBLIC, holder.narrow(builderClass), fieldName); JVar arg = method.param(paramClass, fieldName); method.body().invoke(builderArgsField, bundleHelper.getMethodNameToSave()).arg(argKeyStaticField).arg(arg); method.body()._return(_this()); diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/rest/RestServiceHandler.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/rest/RestServiceHandler.java index d0b3ac9d6f..6510feafa3 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/rest/RestServiceHandler.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/rest/RestServiceHandler.java @@ -24,16 +24,20 @@ import org.androidannotations.annotations.rest.Rest; import org.androidannotations.annotations.rest.RestService; import org.androidannotations.handler.BaseAnnotationHandler; +import org.androidannotations.helper.APTCodeModelHelper; import org.androidannotations.holder.EComponentHolder; import org.androidannotations.model.AnnotationElements; import org.androidannotations.process.IsValid; import com.sun.codemodel.JBlock; +import com.sun.codemodel.JClass; import com.sun.codemodel.JExpr; import com.sun.codemodel.JFieldRef; public class RestServiceHandler extends BaseAnnotationHandler { + private APTCodeModelHelper codeModelHelper = new APTCodeModelHelper(); + public RestServiceHandler(ProcessingEnvironment processingEnvironment) { super(RestService.class, processingEnvironment); } @@ -52,14 +56,17 @@ public void process(Element element, EComponentHolder holder) { String fieldName = element.getSimpleName().toString(); TypeMirror fieldTypeMirror = element.asType(); - String interfaceName = fieldTypeMirror.toString(); + TypeMirror erasedFieldTypeMirror = processingEnv.getTypeUtils().erasure(fieldTypeMirror); + String interfaceName = erasedFieldTypeMirror.toString(); String generatedClassName = interfaceName + classSuffix(); + JClass clazz = codeModelHelper.narrowGeneratedClass(refClass(generatedClassName), fieldTypeMirror, holder); + JBlock methodBody = holder.getInitBody(); JFieldRef field = JExpr.ref(fieldName); - methodBody.assign(field, JExpr._new(refClass(generatedClassName)).arg(holder.getContextRef())); + methodBody.assign(field, JExpr._new(clazz).arg(holder.getContextRef())); } } diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/APTCodeModelHelper.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/APTCodeModelHelper.java index 49b3f13dc7..6325444d92 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/APTCodeModelHelper.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/APTCodeModelHelper.java @@ -226,6 +226,16 @@ public void generifyStaticHelper(GeneratedClassHolder holder, JMethod staticHelp } } + public JClass narrowGeneratedClass(JClass generatedClass, TypeMirror fromTypeArguments, GeneratedClassHolder holder) { + DeclaredType type = (DeclaredType) fromTypeArguments; + + for (TypeMirror param : type.getTypeArguments()) { + JClass paramClass = typeMirrorToJClass(param, holder); + generatedClass = generatedClass.narrow(paramClass); + } + return generatedClass; + } + private JMethod findAlreadyGeneratedMethod(ExecutableElement executableElement, GeneratedClassHolder holder) { JDefinedClass definedClass = holder.getGeneratedClass(); String methodName = executableElement.getSimpleName().toString(); diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/BaseGeneratedClassHolder.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/BaseGeneratedClassHolder.java index cb8df6bda0..efa47a9250 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/BaseGeneratedClassHolder.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/BaseGeneratedClassHolder.java @@ -20,6 +20,9 @@ import static com.sun.codemodel.JMod.STATIC; import static org.androidannotations.helper.ModelConstants.classSuffix; +import java.util.ArrayList; +import java.util.List; + import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; @@ -32,6 +35,7 @@ import com.sun.codemodel.JClass; import com.sun.codemodel.JCodeModel; import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JTypeVar; public abstract class BaseGeneratedClassHolder implements GeneratedClassHolder { @@ -117,4 +121,15 @@ public JClass refClass(Class clazz) { public JDefinedClass definedClass(String fullyQualifiedClassName) { return processHolder.definedClass(fullyQualifiedClassName); } + + public JClass narrow(JClass toNarrow) { + List classes = new ArrayList(); + for (JTypeVar type : generatedClass.typeParams()) { + classes.add(codeModel().directClass(type.name())); + } + if (classes.isEmpty()) { + return toNarrow; + } + return toNarrow.narrow(classes); + } } diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EBeanHolder.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EBeanHolder.java index 816fb80a27..282d81063f 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EBeanHolder.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EBeanHolder.java @@ -31,6 +31,7 @@ import org.androidannotations.process.ProcessHolder; import com.sun.codemodel.JBlock; +import com.sun.codemodel.JClass; import com.sun.codemodel.JFieldVar; import com.sun.codemodel.JMethod; import com.sun.codemodel.JVar; @@ -83,7 +84,11 @@ public void invokeInitInConstructor() { public void createFactoryMethod(boolean hasSingletonScope) { - JMethod factoryMethod = generatedClass.method(PUBLIC | STATIC, generatedClass, GET_INSTANCE_METHOD_NAME); + JClass narrowedGeneratedClass = codeModelHelper.narrowGeneratedClass(generatedClass, annotatedElement.asType(), this); + + JMethod factoryMethod = generatedClass.method(PUBLIC | STATIC, narrowedGeneratedClass, GET_INSTANCE_METHOD_NAME); + + codeModelHelper.generifyStaticHelper(this, factoryMethod, annotatedElement); JVar factoryMethodContextParam = factoryMethod.param(classes().CONTEXT, "context"); @@ -100,13 +105,13 @@ public void createFactoryMethod(boolean hasSingletonScope) { ._if(instanceField.eq(_null())) // ._then(); JVar previousNotifier = viewNotifierHelper.replacePreviousNotifierWithNull(creationBlock); - creationBlock.assign(instanceField, _new(generatedClass).arg(factoryMethodContextParam.invoke("getApplicationContext"))); + creationBlock.assign(instanceField, _new(narrowedGeneratedClass).arg(factoryMethodContextParam.invoke("getApplicationContext"))); creationBlock.invoke(instanceField, getInit()); viewNotifierHelper.resetPreviousNotifier(creationBlock, previousNotifier); factoryMethodBody._return(instanceField); } else { - factoryMethodBody._return(_new(generatedClass).arg(factoryMethodContextParam)); + factoryMethodBody._return(_new(narrowedGeneratedClass).arg(factoryMethodContextParam)); } } diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java index b024f0c94b..823f4daafb 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java @@ -25,9 +25,6 @@ import static com.sun.codemodel.JMod.STATIC; import static org.androidannotations.helper.ModelConstants.generationSuffix; -import java.util.ArrayList; -import java.util.List; - import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; @@ -146,17 +143,6 @@ private void setFragmentBuilder() throws JClassAlreadyExistsException { setFragmentBuilderCreate(); } - private JClass narrow(JClass toNarrow) { - List classes = new ArrayList<>(); - for (JTypeVar type : generatedClass.typeParams()) { - classes.add(codeModel().directClass(type.name())); - } - if (classes.isEmpty()) { - return toNarrow; - } - return toNarrow.narrow(classes); - } - private void setFragmentBuilderBuild() { JMethod method = fragmentBuilderClass.method(PUBLIC, generatedClass._extends(), "build"); method.annotate(Override.class); diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EViewHolder.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EViewHolder.java index c3bc78c18f..6b2b55dea8 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EViewHolder.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EViewHolder.java @@ -87,7 +87,9 @@ private void createConstructorAndBuilder() { JBlock body = copyConstructor.body(); JInvocation superCall = body.invoke("super"); - JInvocation newInvocation = JExpr._new(generatedClass); + JClass narrowedGeneratedClass = narrow(generatedClass); + + JInvocation newInvocation = JExpr._new(narrowedGeneratedClass); for (VariableElement param : userConstructor.getParameters()) { String paramName = param.getSimpleName().toString(); JClass paramType = codeModelHelper.typeMirrorToJClass(param.asType(), this); @@ -97,7 +99,7 @@ private void createConstructorAndBuilder() { newInvocation.arg(JExpr.ref(paramName)); } - JVar newCall = staticHelper.body().decl(generatedClass, "instance", newInvocation); + JVar newCall = staticHelper.body().decl(narrowedGeneratedClass, "instance", newInvocation); staticHelper.body().invoke(newCall, getOnFinishInflate()); staticHelper.body()._return(newCall); body.invoke(getInit()); diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/RestHolder.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/RestHolder.java index 620884ddee..7a49fc114b 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/RestHolder.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/RestHolder.java @@ -62,7 +62,7 @@ public RestHolder(ProcessHolder processHolder, TypeElement annotatedElement) thr protected void setExtends() { String annotatedComponentQualifiedName = annotatedElement.getQualifiedName().toString(); JClass annotatedComponent = codeModel().directClass(annotatedComponentQualifiedName); - generatedClass._implements(annotatedComponent); + generatedClass._implements(narrow(annotatedComponent)); } private void implementMethods() { @@ -286,7 +286,8 @@ private void setAuthenticationField() { } public JFieldVar getRestErrorHandlerField() { - // restErrorHandlerField is created only if the method setRestErrorHandler is implemented + // restErrorHandlerField is created only if the method + // setRestErrorHandler is implemented return restErrorHandlerField; } diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/GenericClient.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/GenericClient.java new file mode 100644 index 0000000000..1117b0dcbd --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/GenericClient.java @@ -0,0 +1,24 @@ +/** + * Copyright (C) 2010-2015 eBusiness Information, Excilys Group + * + * Licensed 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.androidannotations.rest; + +import org.androidannotations.annotations.rest.Rest; +import org.springframework.http.converter.StringHttpMessageConverter; + +@Rest(converters = { StringHttpMessageConverter.class }) +public interface GenericClient { + +} diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/GenericClientHolderBean.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/GenericClientHolderBean.java new file mode 100644 index 0000000000..6bcd0f411a --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/GenericClientHolderBean.java @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2010-2015 eBusiness Information, Excilys Group + * + * Licensed 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.androidannotations.rest; + +import org.androidannotations.annotations.EBean; +import org.androidannotations.annotations.rest.RestService; + +@EBean +public class GenericClientHolderBean { + + @RestService + GenericClient client; +} diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/RestServiceTest.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/RestServiceTest.java new file mode 100644 index 0000000000..938c3c1c05 --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/RestServiceTest.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2010-2015 eBusiness Information, Excilys Group + * + * Licensed 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.androidannotations.rest; + +import java.io.IOException; + +import org.androidannotations.AndroidAnnotationProcessor; +import org.androidannotations.utils.AAProcessorTestHelper; +import org.junit.Before; +import org.junit.Test; + +public class RestServiceTest extends AAProcessorTestHelper { + + @Before + public void setUp() { + addManifestProcessorParameter(RestServiceTest.class); + addProcessor(AndroidAnnotationProcessor.class); + } + + @Test + public void restServiceOnGenericField() throws IOException { + CompileResult result = compileFiles(GenericClient.class, GenericClientHolderBean.class); + assertCompilationSuccessful(result); + } +}