private void processExecutableElement(String prefix, ExecutableElement element) { if (element.getModifiers().contains(Modifier.PUBLIC) && (TypeKind.VOID != element.getReturnType().getKind())) { Element returns = this.processingEnv.getTypeUtils().asElement(element.getReturnType()); if (returns instanceof TypeElement) { ItemMetadata group = ItemMetadata.newGroup( prefix, this.typeUtils.getType(returns), this.typeUtils.getType(element.getEnclosingElement()), element.toString()); if (this.metadataCollector.hasSimilarGroup(group)) { this.processingEnv .getMessager() .printMessage( Kind.ERROR, "Duplicate `@ConfigurationProperties` definition for prefix '" + prefix + "'", element); } else { this.metadataCollector.add(group); processTypeElement(prefix, (TypeElement) returns, element); } } } }
private void processSimpleTypes( String prefix, TypeElement element, ExecutableElement source, TypeElementMembers members, Map<String, Object> fieldValues) { for (Map.Entry<String, ExecutableElement> entry : members.getPublicGetters().entrySet()) { String name = entry.getKey(); ExecutableElement getter = entry.getValue(); TypeMirror returnType = getter.getReturnType(); ExecutableElement setter = members.getPublicSetter(name, returnType); VariableElement field = members.getFields().get(name); Element returnTypeElement = this.processingEnv.getTypeUtils().asElement(returnType); boolean isExcluded = this.typeExcludeFilter.isExcluded(returnType); boolean isNested = isNested(returnTypeElement, field, element); boolean isCollection = this.typeUtils.isCollectionOrMap(returnType); if (!isExcluded && !isNested && (setter != null || isCollection)) { String dataType = this.typeUtils.getType(returnType); String sourceType = this.typeUtils.getType(element); String description = this.typeUtils.getJavaDoc(field); Object defaultValue = fieldValues.get(name); boolean deprecated = isDeprecated(getter) || isDeprecated(setter) || isDeprecated(source); this.metadataCollector.add( ItemMetadata.newProperty( prefix, name, dataType, sourceType, null, description, defaultValue, (deprecated ? getItemDeprecation(getter) : null))); } } }
/** * Tests whether a method invocation is an invocation of {@link Comparable#compareTo}. * * <p> * * @param node a method invocation node * @return true iff {@code node} is a invocation of {@code compareTo()} */ private boolean isInvocationOfCompareTo(MethodInvocationTree node) { ExecutableElement method = TreeUtils.elementFromUse(node); return (method.getParameters().size() == 1 && method.getReturnType().getKind() == TypeKind.INT // method symbols only have simple names && method.getSimpleName().contentEquals("compareTo")); }
@Override public void printErrorCheckMethod( final PrintWriter writer, final ExecutableElement method, final String tabs) { final Check check = method.getAnnotation(Check.class); if (check != null) // Get the error code from an IntBuffer output parameter writer.println( tabs + "Util.checkCLError(" + check.value() + ".get(" + check.value() + ".position()));"); else { final Class return_type = Utils.getJavaType(method.getReturnType()); if (return_type == int.class) writer.println(tabs + "Util.checkCLError(__result);"); else { boolean hasErrCodeParam = false; for (final VariableElement param : method.getParameters()) { if ("errcode_ret".equals(param.getSimpleName().toString()) && Utils.getJavaType(param.asType()) == IntBuffer.class) { hasErrCodeParam = true; break; } } if (hasErrCodeParam) throw new RuntimeException( "A method is missing the @Check annotation: " + method.toString()); } } }
private void processFromProperties(TypeElement type, Set<TypeElement> types) { List<? extends Element> children = type.getEnclosedElements(); VisitorConfig config = conf.getConfig(type, children); // fields if (config.visitFieldProperties()) { for (VariableElement field : ElementFilter.fieldsIn(children)) { TypeElement typeElement = typeExtractor.visit(field.asType()); if (typeElement != null) { types.add(typeElement); } } } // getters if (config.visitMethodProperties()) { for (ExecutableElement method : ElementFilter.methodsIn(children)) { String name = method.getSimpleName().toString(); if ((name.startsWith("get") || name.startsWith("is")) && method.getParameters().isEmpty()) { TypeElement typeElement = typeExtractor.visit(method.getReturnType()); if (typeElement != null) { types.add(typeElement); } } } } }
private MethodSpec generateMethod(ExecutableElement method) { MethodSpec.Builder builder = overriding(method); TypeKind returnType = method.getReturnType().getKind(); if (returnType != VOID) { builder.addStatement("return " + defaultValue(returnType)); } return builder.build(); }
private MethodSpec.Builder createOverridingMethod(ExecutableElement element) { // TODO fix the cast MethodSpec.Builder result = MethodSpec.overriding(element, (DeclaredType) getSourceType().asType(), types); String literal = ClassGenerationUtil.defaultReturnLiteral(element.getReturnType()); if (literal != null) result.addStatement("return $L", literal); return result; }
private static Set<TypeElement> nestedAnnotationElements( TypeElement annotationElement, Set<TypeElement> annotationElements) { if (annotationElements.add(annotationElement)) { for (ExecutableElement method : methodsIn(annotationElement.getEnclosedElements())) { TRAVERSE_NESTED_ANNOTATIONS.visit(method.getReturnType(), annotationElements); } } return annotationElements; }
private void processNestedTypes( String prefix, TypeElement element, ExecutableElement source, TypeElementMembers members) { for (Map.Entry<String, ExecutableElement> entry : members.getPublicGetters().entrySet()) { String name = entry.getKey(); ExecutableElement getter = entry.getValue(); VariableElement field = members.getFields().get(name); processNestedType(prefix, element, source, name, getter, field, getter.getReturnType()); } }
private void printMethod(ExecutableElement executableElement) { StringBuilder s = new StringBuilder(256); s.append("method: " + executableElement).append("\n\t"); s.append("annotations: " + executableElement.getAnnotationMirrors()).append("\n\t"); s.append("return: " + executableElement.getReturnType()).append("\n\t"); for (VariableElement var : executableElement.getParameters()) { s.append("parameter: " + var + ", " + var.getAnnotation(ApiParameterDoc.class)) .append("\n\t"); } generator.log(s.toString()); }
private ProcessorMetaModelMethod toMethodModel(ExecutableElement e, AnnotationMirror am) { // TypeMirror declaringType = e.getReceiverType(); final String declaringClassName = ((TypeElement) e.getEnclosingElement()).getQualifiedName().toString(); final String metamodelAnnotationName = getAnnotationClassName(am); final Map<String, String> metamodelAttributes = getAnnotationAttributes(am); return new ProcessorMetaModelMethod( e.getSimpleName().toString(), declaringClassName, getParamTypes(e), e.getReturnType().toString(), metamodelAnnotationName, metamodelAttributes); }
private Set<TypeElement> processDelegateMethods() { Set<Element> delegateMethods = (Set) getElements(QueryDelegate.class); Set<TypeElement> typeElements = new HashSet<TypeElement>(); for (Element delegateMethod : delegateMethods) { ExecutableElement method = (ExecutableElement) delegateMethod; Element element = delegateMethod.getEnclosingElement(); String name = method.getSimpleName().toString(); Type delegateType = typeFactory.getType(element.asType(), true); Type returnType = typeFactory.getType(method.getReturnType(), true); List<Parameter> parameters = elementHandler.transformParams(method.getParameters()); // remove first element parameters = parameters.subList(1, parameters.size()); EntityType entityType = null; for (AnnotationMirror annotation : delegateMethod.getAnnotationMirrors()) { if (TypeUtils.isAnnotationMirrorOfType(annotation, QueryDelegate.class)) { TypeMirror type = TypeUtils.getAnnotationValueAsTypeMirror(annotation, "value"); if (type != null) { entityType = typeFactory.getEntityType(type, true); } } } if (entityType != null) { registerTypeElement(entityType.getFullName(), (TypeElement) element); entityType.addDelegate( new Delegate(entityType, delegateType, name, parameters, returnType)); TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(entityType.getFullName()); boolean isAnnotated = false; for (Class<? extends Annotation> ann : conf.getEntityAnnotations()) { if (typeElement.getAnnotation(ann) != null) { isAnnotated = true; } } if (isAnnotated) { // handle also properties of entity type typeElements.add( processingEnv.getElementUtils().getTypeElement(entityType.getFullName())); } else { // skip handling properties context.extensionTypes.put(entityType.getFullName(), entityType); context.allTypes.put(entityType.getFullName(), entityType); } } } return typeElements; }
public TargetMethodInjector(ExecutableElement executableElement) { this.executableElement = executableElement; this.methodName = executableElement.getSimpleName().toString(); this.returnType = executableElement.getReturnType(); this.arguments = executableElement.getParameters(); if (executableElement.getAnnotation(POST.class) != null) { httpMethod = _POST; url = executableElement.getAnnotation(POST.class).value(); } else if (executableElement.getAnnotation(GET.class) != null) { httpMethod = _GET; url = executableElement.getAnnotation(GET.class).value(); } }
private ImmutableSet<ExecutableElement> methodsToImplement( TypeElement autoValueClass, Set<ExecutableElement> methods) { ImmutableSet.Builder<ExecutableElement> toImplement = ImmutableSet.builder(); for (ExecutableElement method : methods) { if (method.getModifiers().contains(Modifier.ABSTRACT) && !Arrays.asList("toString", "hashCode", "equals") .contains(method.getSimpleName().toString())) { if (method.getParameters().isEmpty() && method.getReturnType().getKind() != TypeKind.VOID) { toImplement.add(method); } } } return toImplement.build(); }
private void parseGetter(ExecutableElement methodElement) { assert methodElement.getSimpleName().toString().startsWith("get"); assert methodElement.getParameters().size() == 1; final boolean isFactoryGetter = methodElement .getParameters() .get(0) .asType() .toString() .equals(DynamicObjectFactory.class.getName()); final boolean isObjectTypeGetter = methodElement.getParameters().get(0).asType().toString().equals(ObjectType.class.getName()); assert !(isFactoryGetter & isObjectTypeGetter); if (isFactoryGetter) { assert methodElement.getParameters().get(0).getSimpleName().toString().equals("factory"); } else if (isObjectTypeGetter) { assert methodElement.getParameters().get(0).getSimpleName().toString().equals("objectType"); } else { assert methodElement .getParameters() .get(0) .asType() .toString() .equals(DynamicObject.class.getName()); assert methodElement.getParameters().get(0).getSimpleName().toString().equals("object"); } final String name = titleToCamel(methodElement.getSimpleName().toString().substring("get".length())); final PropertyBuilder property = getProperty(name); if (isFactoryGetter) { property.setHasFactoryGetter(true); } else if (isObjectTypeGetter) { property.setHasObjectTypeGetter(true); } else { property.setHasGetter(true); } setPropertyType(property, methodElement.getReturnType()); }
/** * Value is the canonical outside look of the value type. It should be either {@link * #typeAbstract()} or {@link #typeImmutable()}. For factory it is a special surrogate. * * @return canonical value type name forms */ @Value.Lazy public NameForms typeValue() { if (protoclass().kind().isValue()) { return returnsAbstractValueType() ? typeAbstract() : typeImmutable(); } if (isFactory()) { ExecutableElement method = (ExecutableElement) protoclass().sourceElement(); String type = method.getReturnType().toString(); return ImmutableConstitution.NameForms.builder() .simple(NA_ERROR) .relativeRaw(type) .packageOf(NA_ERROR) .relativeAlreadyQualified(true) .visibility(protoclass().visibility()) .build(); } return typeEnclosing(); }
private void processRequestMappingMethod(ExecutableElement executableElement) { TypeElement cls = (TypeElement) executableElement.getEnclosingElement(); String path = getClassLevelUrlPath(cls); RequestMapping anno = executableElement.getAnnotation(RequestMapping.class); path = addMethodPathComponent(executableElement, cls, path, anno); RequestMethod meth = getRequestMethod(executableElement, cls, anno); RestDocumentation.Resource.Method doc = _docs.getResourceDocumentation(path).newMethodDocumentation(meth); String docComment = processingEnv.getElementUtils().getDocComment(executableElement); if (StringUtils.isNotBlank(docComment)) { MethodStructure methodStructure = generateMethodStructure(docComment); doc.setCommentText(generateJavaDocHTML(methodStructure)); doc.setCommentSummary(methodStructure.getDescription()); } buildParameterData(executableElement, doc); buildResponseFormat(executableElement.getReturnType(), doc); }
public SectorMethod build() { SectorMethod method = new SectorMethod(); String methodName = methodElement.getSimpleName().toString(); SectorOperation operationAnnotation = methodElement.getAnnotation(SectorOperation.class); if (operationAnnotation == null) { return null; } int argCount = methodElement.getParameters().size(); method.cellbased = operationAnnotation.cellbased(); method.name = "hz_" + methodName; method.returnType = methodElement.getReturnType().toString(); method.invocationClassName = CodeGenerationUtils.capitalizeFirstLetter(methodName) + argCount + "Invocation"; method.targetMethod = methodName; method.readonly = operationAnnotation.readonly(); method.functionId = sectorClassModel.getMethods().size(); List<FormalArgument> args = new LinkedList<>(); for (VariableElement variableElement : methodElement.getParameters()) { FormalArgument formalArgument = new FormalArgument(); if (method.cellbased && args.isEmpty()) { formalArgument.name = "id"; formalArgument.type = "long"; } else { formalArgument.name = "arg" + (args.size() + 1); formalArgument.type = variableElement.asType().toString(); } args.add(formalArgument); } method.formalArguments = args; buildOriginalMethos(method); buildAsyncMethod(method); return method; }
private boolean isJsonBeanGetter(ExecutableElement executableElement) { if (executableElement.getKind() != ElementKind.METHOD) { return false; } if (executableElement.getReturnType().getKind() == TypeKind.NULL) { return false; } if (!(executableElement.getSimpleName().toString().startsWith("get") || executableElement.getSimpleName().toString().startsWith("is"))) { return false; } if (executableElement.getParameters().size() > 0) { return false; } return executableElement.getAnnotation(JsonIgnore.class) == null; }
/** * @param env the environment * @param annUtil utils * @param d the method */ public MethodHandler( final ProcessingEnvironment env, final AnnUtil annUtil, final ExecutableElement d) { this.env = env; this.annUtil = annUtil; msg = env.getMessager(); staticMethod = d.getModifiers().contains(Modifier.STATIC); methName = d.getSimpleName().toString(); getter = methName.startsWith("get"); setter = methName.startsWith("set"); immutable = d.getAnnotation(Immutable.class) != null; CloneForOverride cfo = d.getAnnotation(CloneForOverride.class); cloneForOverride = cfo != null; if (cloneForOverride) { cloneCollectionType = cfo.cloneCollectionType(); cloneElementType = cfo.cloneElementType(); } returnType = d.getReturnType(); returnsVoid = env.getTypeUtils().getNoType(TypeKind.VOID).equals(returnType); pars = d.getParameters(); thrownTypes = d.getThrownTypes(); if ((setter) && (pars != null) && (pars.size() == 1)) { fieldType = pars.iterator().next().asType(); basicType = fieldType.getKind().isPrimitive(); } if (getter) { fieldType = returnType; basicType = returnType.getKind().isPrimitive(); } if (setter || getter) { ucFieldName = methName.substring(3); fieldName = ucFieldName.substring(0, 1).toLowerCase() + ucFieldName.substring(1); } }
boolean verifiedFactory(ExecutableElement element) { if (!FactoryMirror.isPresent(element)) { return false; } if (!isTopLevel() || element.getReturnType().getKind() == TypeKind.VOID || element.getModifiers().contains(Modifier.PRIVATE) || !element.getModifiers().contains(Modifier.STATIC) || !element.getTypeParameters().isEmpty()) { report() .withElement(element) .annotationNamed(FactoryMirror.simpleName()) .error( "@%s method '%s' should be static, non-private, non-void" + " with no type parameters and enclosed in top level type", FactoryMirror.simpleName(), element.getSimpleName()); return false; } return true; }
public static CodeExecutableElement clone( @SuppressWarnings("unused") ProcessingEnvironment env, ExecutableElement method) { CodeExecutableElement copy = new CodeExecutableElement(method.getReturnType(), method.getSimpleName().toString()); for (TypeMirror thrownType : method.getThrownTypes()) { copy.addThrownType(thrownType); } copy.setDefaultValue(method.getDefaultValue()); for (AnnotationMirror mirror : method.getAnnotationMirrors()) { copy.addAnnotationMirror(mirror); } for (VariableElement var : method.getParameters()) { copy.addParameter(CodeVariableElement.clone(var)); } for (Element element : method.getEnclosedElements()) { copy.add(element); } copy.getModifiers().addAll(method.getModifiers()); copy.setVarArgs(method.isVarArgs()); return copy; }
private void addFieldFromBeanMethod(JsonObject o, ExecutableElement executableElement) { if (!isJsonBeanGetter(executableElement)) { return; } TypeMirror type = executableElement.getReturnType(); String methodName = executableElement.getSimpleName().toString(); int trimLength = methodName.startsWith("is") ? 2 : 3; String beanName = methodName.substring(trimLength + 1, methodName.length()); beanName = methodName.substring(trimLength, trimLength + 1).toLowerCase() + beanName; // loop over the element's generic types, and build a concrete list from the owning context List<DeclaredType> concreteTypes = new ArrayList(); // replace variables with the current concrete manifestation if (type instanceof TypeVariable) { type = getDeclaredTypeForTypeVariable((TypeVariable) type); if (type == null) { return; // couldn't find a replacement -- must be a generics-capable type with no generics // info } } String docComment = processingEnv.getElementUtils().getDocComment(executableElement); if (type instanceof DeclaredType) { TypeElement element = (TypeElement) ((DeclaredType) type).asElement(); for (TypeParameterElement generic : element.getTypeParameters()) { concreteTypes.add(_typeArguments.get(generic.getSimpleName())); } Collection<DeclaredType> types = new HashSet<DeclaredType>(_typeRecursionGuard); types.add(_type); o.addField(beanName, newJsonType((DeclaredType) type, concreteTypes, types)) .setCommentText(docComment); } else { o.addField(beanName, newJsonType(type)).setCommentText(docComment); } }
private void processLabels(TypeElement resourcesType, List<LabelTemplateMethod> methods) { for (Element element : resourcesType.getEnclosedElements()) { if (element.getKind() != ElementKind.METHOD) { continue; } final ExecutableElement method = (ExecutableElement) element; Message labelAnnotation = element.getAnnotation(Message.class); final TemplateParam returnType = new TemplateParam(method.getReturnType().toString()); final boolean deprecated = method.getAnnotation(Deprecated.class) != null; final LabelTemplateMethod labelMethod; try { labelMethod = new LabelTemplateMethod( method.getSimpleName().toString(), deprecated, returnType, labelAnnotation.value(), labelAnnotation.mobile()); } catch (Throwable t) { processingEnv.getMessager().printMessage(Kind.WARNING, t.getMessage(), resourcesType); continue; } for (VariableElement variable : method.getParameters()) { final String paramName = variable.getSimpleName().toString(); final String paramType = variable.asType().toString(); List<TemplateAnnotation> annotations = new ArrayList<TemplateAnnotation>(); for (AnnotationMirror annotationMirrors : variable.getAnnotationMirrors()) { annotations.add(new TemplateAnnotation(annotationMirrors.getAnnotationType().toString())); } labelMethod.getParams().add(new TemplateParam(paramType, paramName, annotations)); } methods.add(labelMethod); } }
private MethodSpec buildCreateMethod( ClassName mapKeyGeneratedTypeName, TypeElement annotationElement) { String createMethodName = "create" + annotationElement.getSimpleName(); MethodSpec.Builder createMethod = methodBuilder(createMethodName) .addAnnotation(AutoAnnotation.class) .addModifiers(PUBLIC, STATIC) .returns(TypeName.get(annotationElement.asType())); ImmutableList.Builder<CodeBlock> parameters = ImmutableList.builder(); for (ExecutableElement annotationMember : methodsIn(annotationElement.getEnclosedElements())) { String parameterName = annotationMember.getSimpleName().toString(); TypeName parameterType = TypeName.get(annotationMember.getReturnType()); createMethod.addParameter(parameterType, parameterName); parameters.add(CodeBlocks.format("$L", parameterName)); } ClassName autoAnnotationClass = mapKeyGeneratedTypeName.peerClass( "AutoAnnotation_" + mapKeyGeneratedTypeName.simpleName() + "_" + createMethodName); createMethod.addStatement( "return new $T($L)", autoAnnotationClass, makeParametersCodeBlock(parameters.build())); return createMethod.build(); }
private void parseListenerAnnotation( Class<? extends Annotation> annotationClass, Element element, Map<TypeElement, BindingClass> targetClassMap, Set<String> erasedTargetNames) throws Exception { // This should be guarded by the annotation's @Target but it's worth a check for safe casting. if (!(element instanceof ExecutableElement) || element.getKind() != METHOD) { throw new IllegalStateException( String.format("@%s annotation must be on a method.", annotationClass.getSimpleName())); } ExecutableElement executableElement = (ExecutableElement) element; TypeElement enclosingElement = (TypeElement) element.getEnclosingElement(); // Assemble information on the method. Annotation annotation = element.getAnnotation(annotationClass); Method annotationValue = annotationClass.getDeclaredMethod("value"); if (annotationValue.getReturnType() != int[].class) { throw new IllegalStateException( String.format("@%s annotation value() type not int[].", annotationClass)); } int[] ids = (int[]) annotationValue.invoke(annotation); String name = executableElement.getSimpleName().toString(); boolean required = isRequiredBinding(element); // Verify that the method and its containing class are accessible via generated code. boolean hasError = isInaccessibleViaGeneratedCode(annotationClass, "methods", element); hasError |= isBindingInWrongPackage(annotationClass, element); Integer duplicateId = findDuplicate(ids); if (duplicateId != null) { error( element, "@%s annotation for method contains duplicate ID %d. (%s.%s)", annotationClass.getSimpleName(), duplicateId, enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } ListenerClass listener = annotationClass.getAnnotation(ListenerClass.class); if (listener == null) { throw new IllegalStateException( String.format( "No @%s defined on @%s.", ListenerClass.class.getSimpleName(), annotationClass.getSimpleName())); } for (int id : ids) { if (id == View.NO_ID) { if (ids.length == 1) { if (!required) { error( element, "ID-free binding must not be annotated with @Nullable. (%s.%s)", enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } // Verify target type is valid for a binding without an id. String targetType = listener.targetType(); if (!isSubtypeOfType(enclosingElement.asType(), targetType) && !isInterface(enclosingElement.asType())) { error( element, "@%s annotation without an ID may only be used with an object of type " + "\"%s\" or an interface. (%s.%s)", annotationClass.getSimpleName(), targetType, enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } } else { error( element, "@%s annotation contains invalid ID %d. (%s.%s)", annotationClass.getSimpleName(), id, enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } } } ListenerMethod method; ListenerMethod[] methods = listener.method(); if (methods.length > 1) { throw new IllegalStateException( String.format( "Multiple listener methods specified on @%s.", annotationClass.getSimpleName())); } else if (methods.length == 1) { if (listener.callbacks() != ListenerClass.NONE.class) { throw new IllegalStateException( String.format( "Both method() and callback() defined on @%s.", annotationClass.getSimpleName())); } method = methods[0]; } else { Method annotationCallback = annotationClass.getDeclaredMethod("callback"); Enum<?> callback = (Enum<?>) annotationCallback.invoke(annotation); Field callbackField = callback.getDeclaringClass().getField(callback.name()); method = callbackField.getAnnotation(ListenerMethod.class); if (method == null) { throw new IllegalStateException( String.format( "No @%s defined on @%s's %s.%s.", ListenerMethod.class.getSimpleName(), annotationClass.getSimpleName(), callback.getDeclaringClass().getSimpleName(), callback.name())); } } // Verify that the method has equal to or less than the number of parameters as the listener. List<? extends VariableElement> methodParameters = executableElement.getParameters(); if (methodParameters.size() > method.parameters().length) { error( element, "@%s methods can have at most %s parameter(s). (%s.%s)", annotationClass.getSimpleName(), method.parameters().length, enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } // Verify method return type matches the listener. TypeMirror returnType = executableElement.getReturnType(); if (returnType instanceof TypeVariable) { TypeVariable typeVariable = (TypeVariable) returnType; returnType = typeVariable.getUpperBound(); } if (!returnType.toString().equals(method.returnType())) { error( element, "@%s methods must have a '%s' return type. (%s.%s)", annotationClass.getSimpleName(), method.returnType(), enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } if (hasError) { return; } Parameter[] parameters = Parameter.NONE; if (!methodParameters.isEmpty()) { parameters = new Parameter[methodParameters.size()]; BitSet methodParameterUsed = new BitSet(methodParameters.size()); String[] parameterTypes = method.parameters(); for (int i = 0; i < methodParameters.size(); i++) { VariableElement methodParameter = methodParameters.get(i); TypeMirror methodParameterType = methodParameter.asType(); if (methodParameterType instanceof TypeVariable) { TypeVariable typeVariable = (TypeVariable) methodParameterType; methodParameterType = typeVariable.getUpperBound(); } for (int j = 0; j < parameterTypes.length; j++) { if (methodParameterUsed.get(j)) { continue; } if (isSubtypeOfType(methodParameterType, parameterTypes[j]) || isInterface(methodParameterType)) { parameters[i] = new Parameter(j, methodParameterType.toString()); methodParameterUsed.set(j); break; } } if (parameters[i] == null) { StringBuilder builder = new StringBuilder(); builder .append("Unable to match @") .append(annotationClass.getSimpleName()) .append(" method arguments. (") .append(enclosingElement.getQualifiedName()) .append('.') .append(element.getSimpleName()) .append(')'); for (int j = 0; j < parameters.length; j++) { Parameter parameter = parameters[j]; builder .append("\n\n Parameter #") .append(j + 1) .append(": ") .append(methodParameters.get(j).asType().toString()) .append("\n "); if (parameter == null) { builder.append("did not match any listener parameters"); } else { builder .append("matched listener parameter #") .append(parameter.getListenerPosition() + 1) .append(": ") .append(parameter.getType()); } } builder .append("\n\nMethods may have up to ") .append(method.parameters().length) .append(" parameter(s):\n"); for (String parameterType : method.parameters()) { builder.append("\n ").append(parameterType); } builder.append( "\n\nThese may be listed in any order but will be searched for from top to bottom."); error(executableElement, builder.toString()); return; } } } MethodViewBinding binding = new MethodViewBinding(name, Arrays.asList(parameters), required); BindingClass bindingClass = getOrCreateTargetClass(targetClassMap, enclosingElement); for (int id : ids) { if (!bindingClass.addMethod(id, listener, method, binding)) { error( element, "Multiple listener methods with return value specified for ID %d. (%s.%s)", id, enclosingElement.getQualifiedName(), element.getSimpleName()); return; } } // Add the type-erased version to the valid binding targets set. erasedTargetNames.add(enclosingElement.toString()); }
private void writeProvidesAdapter( JavaWriter writer, ExecutableElement providerMethod, Map<ExecutableElement, String> methodToClassName, Map<String, AtomicInteger> methodNameToNextId) throws IOException { String methodName = providerMethod.getSimpleName().toString(); String moduleType = CodeGen.typeToString(providerMethod.getEnclosingElement().asType()); String className = bindingClassName(providerMethod, methodToClassName, methodNameToNextId); String returnType = CodeGen.typeToString(providerMethod.getReturnType()); List<? extends VariableElement> parameters = providerMethod.getParameters(); boolean dependent = !parameters.isEmpty(); writer.emitEmptyLine(); writer.emitJavadoc(binderTypeDocs(returnType, false, false, dependent)); writer.beginType( className, "class", PUBLIC | FINAL | STATIC, JavaWriter.type(Binding.class, returnType), JavaWriter.type(Provider.class, returnType)); writer.emitField(moduleType, "module", PRIVATE | FINAL); for (Element parameter : parameters) { TypeMirror parameterType = parameter.asType(); writer.emitField( JavaWriter.type(Binding.class, CodeGen.typeToString(parameterType)), parameterName(parameter), PRIVATE); } writer.emitEmptyLine(); writer.beginMethod(null, className, PUBLIC, moduleType, "module"); boolean singleton = providerMethod.getAnnotation(Singleton.class) != null; String key = JavaWriter.stringLiteral(GeneratorKeys.get(providerMethod)); String membersKey = null; writer.emitStatement( "super(%s, %s, %s, %s.class)", key, membersKey, (singleton ? "IS_SINGLETON" : "NOT_SINGLETON"), moduleType); writer.emitStatement("this.module = module"); writer.endMethod(); if (dependent) { writer.emitEmptyLine(); writer.emitJavadoc(ProcessorJavadocs.ATTACH_METHOD); writer.emitAnnotation(Override.class); writer.emitAnnotation(SuppressWarnings.class, JavaWriter.stringLiteral("unchecked")); writer.beginMethod("void", "attach", PUBLIC, Linker.class.getCanonicalName(), "linker"); for (VariableElement parameter : parameters) { String parameterKey = GeneratorKeys.get(parameter); writer.emitStatement( "%s = (%s) linker.requestBinding(%s, %s.class)", parameterName(parameter), writer.compressType( JavaWriter.type(Binding.class, CodeGen.typeToString(parameter.asType()))), JavaWriter.stringLiteral(parameterKey), writer.compressType(moduleType)); } writer.endMethod(); writer.emitEmptyLine(); writer.emitJavadoc(ProcessorJavadocs.GET_DEPENDENCIES_METHOD); writer.emitAnnotation(Override.class); String setOfBindings = JavaWriter.type(Set.class, "Binding<?>"); writer.beginMethod( "void", "getDependencies", PUBLIC, setOfBindings, "getBindings", setOfBindings, "injectMembersBindings"); for (Element parameter : parameters) { writer.emitStatement("getBindings.add(%s)", parameter.getSimpleName().toString()); } writer.endMethod(); } writer.emitEmptyLine(); writer.emitJavadoc(ProcessorJavadocs.GET_METHOD, returnType); writer.emitAnnotation(Override.class); writer.beginMethod(returnType, "get", PUBLIC); StringBuilder args = new StringBuilder(); boolean first = true; for (Element parameter : parameters) { if (!first) args.append(", "); else first = false; args.append(String.format("%s.get()", parameter.getSimpleName().toString())); } writer.emitStatement("return module.%s(%s)", methodName, args.toString()); writer.endMethod(); writer.endType(); }
@Override public Set<ConstraintCheckError> checkMethod( ExecutableElement element, AnnotationMirror annotation) { return checkInternal(element, annotation, element.getReturnType(), "NOT_SUPPORTED_RETURN_TYPE"); }
public JavaType getReturnType() { return getTypeAdapter(executable.getReturnType()); }
@Override public boolean process(Set<? extends TypeElement> elements, RoundEnvironment env) { System.out.println("processing: " + env.toString()); List<MethodToLog> methodToLogs = new ArrayList<>(); List<String> classNames = new ArrayList<>(); for (Element element : env.getElementsAnnotatedWith(XLog.class)) { if (element.getKind() != ElementKind.METHOD && element.getKind() != ElementKind.CONSTRUCTOR && element.getKind() != ElementKind.CLASS) { throw new IllegalStateException( String.format( "@%s annotation must be on as method, constructor or class.", element.getSimpleName())); } if (element instanceof TypeElement) { // class String pkgName = ((TypeElement) element).getQualifiedName().toString(); if (!classNames.contains(pkgName)) { classNames.add(pkgName); } } else if (element instanceof ExecutableElement) { // method or constructor ExecutableElement e = (ExecutableElement) element; int type = XLogUtils.TYPE_METHOD; if (e.getKind() == ElementKind.METHOD) { type = XLogUtils.TYPE_METHOD; } else if (e.getKind() == ElementKind.CONSTRUCTOR) { type = XLogUtils.TYPE_CONSTRUCTOR; } TypeElement te = findEnclosingTypeElement(e); System.out.println(te.getQualifiedName().toString() + "." + e.getSimpleName()); System.out.println(e.getReturnType()); List<String> parameters = new ArrayList<>(); List<String> parameterNames = new ArrayList<>(); for (VariableElement ve : e.getParameters()) { System.out.println(ve.asType()); System.out.println(ve.getSimpleName()); parameters.add(ve.asType().toString()); parameterNames.add(ve.getSimpleName().toString()); } MethodToLog methodToLog = new MethodToLog( type, te.getQualifiedName().toString(), e.getSimpleName().toString(), parameters, parameterNames); methodToLogs.add(methodToLog); if (!classNames.contains(methodToLog.getClassName())) { classNames.add(methodToLog.getClassName()); } } } if (methodToLogs.size() > 0) { generateXLogProcessor("_" + MD5(env.toString()), methodToLogs, classNames); } return true; }