/** INTERNAL: Visit an executable and create a MetadataMethod object. */ @Override public MetadataMethod visitExecutable( ExecutableElement executableElement, MetadataClass metadataClass) { MetadataMethod method = new MetadataMethod(metadataClass.getMetadataFactory(), metadataClass); // Set the name. method.setName(executableElement.getSimpleName().toString()); // Set the attribute name. method.setAttributeName(Helper.getAttributeNameFromMethodName(method.getName())); // Set the modifiers. method.setModifiers(getModifiers(executableElement.getModifiers())); // Visit executable element for the parameters, return type and generic type. executableElement.asType().accept(typeVisitor, method); // Set the annotations. buildMetadataAnnotations(method, executableElement.getAnnotationMirrors()); // Handle multiple methods with the same name. MetadataMethod existing = metadataClass.getMethods().get(method.getName()); if (existing == null) { metadataClass.addMethod(method); } else { while (existing.getNext() != null) { existing = existing.getNext(); } existing.setNext(method); } return method; }
@SuppressWarnings("checkstyle:parameternumber") private SourceMethod( Type declaringMapper, ExecutableElement executable, List<Parameter> parameters, Type returnType, List<Type> exceptionTypes, MappingOptions mappingOptions, Types typeUtils, TypeFactory typeFactory, MapperConfiguration config, List<SourceMethod> prototypeMethods, Type mapperToImplement) { this.declaringMapper = declaringMapper; this.executable = executable; this.parameters = parameters; this.returnType = returnType; this.exceptionTypes = exceptionTypes; this.accessibility = Accessibility.fromModifiers(executable.getModifiers()); this.mappingOptions = mappingOptions; this.mappingTargetParameter = determineMappingTargetParameter(parameters); this.targetTypeParameter = determineTargetTypeParameter(parameters); this.typeUtils = typeUtils; this.typeFactory = typeFactory; this.config = config; this.prototypeMethods = prototypeMethods; this.mapperToImplement = mapperToImplement; }
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); } } } }
/** * Returns true if generated code can invoke {@code constructor}. That is, if the constructor is * non-private and its enclosing class is either a top-level class or a static nested class. */ public static boolean isCallableConstructor(ExecutableElement constructor) { if (constructor.getModifiers().contains(Modifier.PRIVATE)) { return false; } TypeElement type = (TypeElement) constructor.getEnclosingElement(); return type.getEnclosingElement().getKind() == ElementKind.PACKAGE || type.getModifiers().contains(Modifier.STATIC); }
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; }
/** * Returns true if the passed {@link TypeElement} requires a passed instance in order to be used * within a component. */ static boolean requiresAPassedInstance(Elements elements, TypeElement typeElement) { ImmutableSet<ExecutableElement> methods = MoreElements.getLocalAndInheritedMethods(typeElement, elements); boolean foundInstanceMethod = false; for (ExecutableElement method : methods) { if (method.getModifiers().contains(ABSTRACT) && !isAnnotationPresent(method, Binds.class)) { /* We found an abstract method that isn't a @Binds method. That automatically means that * a user will have to provide an instance because we don't know which subclass to use. */ return true; } else if (!method.getModifiers().contains(STATIC) && (isAnnotationPresent(method, Provides.class) || isAnnotationPresent(method, Produces.class))) { foundInstanceMethod = true; } } if (foundInstanceMethod) { return !componentCanMakeNewInstances(typeElement); } return false; }
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(); }
public TypeConstructorWrapper(MapperGeneratorContext context, TypeElement typeElement) { this.context = context; this.typeElement = typeElement; boolean defaultConstructor = false; boolean matchingSourcesConstructor = false; List<ExecutableElement> constructors = ElementFilter.constructorsIn(typeElement.getEnclosedElements()); for (ExecutableElement constructor : constructors) { if (constructor.getModifiers().contains(Modifier.PUBLIC) && !constructor.getModifiers().contains(Modifier.ABSTRACT)) { int paramsCount = constructor.getParameters().size(); if (paramsCount == 0) { defaultConstructor = true; } if (!matchingSourcesConstructor && paramsCount == context.getSourcesCount()) { matchingSourcesConstructor = validateParametersTypes(constructor); } } } hasMatchingSourcesConstructor = matchingSourcesConstructor; hasDefaultConstructor = defaultConstructor; }
private int processConstructor(ExecutableElement constrElt) { if (constrElt.getModifiers().contains(Modifier.PUBLIC)) { Element ownerElt = constrElt.getEnclosingElement(); if (ownerElt.equals(modelElt)) { List<? extends VariableElement> parameters = constrElt.getParameters(); int size = parameters.size(); if (size == 1) { TypeInfo ti = typeFactory.create(parameters.get(0).asType()); if (ti instanceof ClassTypeInfo) { ClassTypeInfo cl = (ClassTypeInfo) ti; if (cl.getKind() == ClassKind.JSON_OBJECT) { return 2; } } } } } return 0; }
/** * @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); } }
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; }
@Override public Void visitExecutable(ExecutableElement elem, TypeElement parent) { if (imp != null) { final Set<Modifier> modifiers = elem.getModifiers(); boolean error = false; if (!modifiers.contains(Modifier.STATIC)) { error("@Resetter methods must be static"); error = true; } if (!modifiers.contains(Modifier.PUBLIC)) { error("@Resetter methods must be public"); error = true; } List<? extends VariableElement> params = elem.getParameters(); if (params != null && !params.isEmpty()) { error("@Resetter methods must not have parameters"); error = true; } if (!error) { model.addResetter(parent, elem); } } return null; }
@Override public boolean isStatic() { return executable.getModifiers().contains(Modifier.STATIC); }
/** * Whether an implementation of this method must be generated or not. * * @return true when an implementation is required */ @Override public boolean overridesMethod() { return declaringMapper == null && executable.getModifiers().contains(Modifier.ABSTRACT); }
private void doProcess(RoundEnvironment roundEnv) { for (Element element : roundEnv.getElementsAnnotatedWith(Provided.class)) { providedChecker.checkProvidedParameter(element); } ImmutableListMultimap.Builder<String, FactoryMethodDescriptor> indexedMethods = ImmutableListMultimap.builder(); ImmutableSet.Builder<ImplementationMethodDescriptor> implementationMethodDescriptors = ImmutableSet.builder(); for (Element element : roundEnv.getElementsAnnotatedWith(AutoFactory.class)) { Optional<AutoFactoryDeclaration> declaration = declarationFactory.createIfValid(element); if (declaration.isPresent()) { TypeElement extendingType = declaration.get().extendingType(); List<ExecutableElement> supertypeMethods = ElementFilter.methodsIn(elements.getAllMembers(extendingType)); for (ExecutableElement supertypeMethod : supertypeMethods) { if (supertypeMethod.getModifiers().contains(Modifier.ABSTRACT)) { ExecutableType methodType = Elements2.getExecutableElementAsMemberOf(types, supertypeMethod, extendingType); implementationMethodDescriptors.add( new ImplementationMethodDescriptor.Builder() .name(supertypeMethod.getSimpleName().toString()) .returnType(getAnnotatedType(element).getQualifiedName().toString()) .publicMethod() .passedParameters( Parameter.forParameterList( supertypeMethod.getParameters(), methodType.getParameterTypes())) .build()); } } for (TypeElement implementingType : declaration.get().implementingTypes()) { List<ExecutableElement> interfaceMethods = ElementFilter.methodsIn(elements.getAllMembers(implementingType)); for (ExecutableElement interfaceMethod : interfaceMethods) { if (interfaceMethod.getModifiers().contains(Modifier.ABSTRACT)) { ExecutableType methodType = Elements2.getExecutableElementAsMemberOf( types, interfaceMethod, implementingType); implementationMethodDescriptors.add( new ImplementationMethodDescriptor.Builder() .name(interfaceMethod.getSimpleName().toString()) .returnType(getAnnotatedType(element).getQualifiedName().toString()) .publicMethod() .passedParameters( Parameter.forParameterList( interfaceMethod.getParameters(), methodType.getParameterTypes())) .build()); } } } } ImmutableSet<FactoryMethodDescriptor> descriptors = factoryDescriptorGenerator.generateDescriptor(element); indexedMethods.putAll( Multimaps.index( descriptors, new Function<FactoryMethodDescriptor, String>() { @Override public String apply(FactoryMethodDescriptor descriptor) { return descriptor.factoryName(); } })); } for (Entry<String, Collection<FactoryMethodDescriptor>> entry : indexedMethods.build().asMap().entrySet()) { ImmutableSet.Builder<String> extending = ImmutableSet.builder(); ImmutableSortedSet.Builder<String> implementing = ImmutableSortedSet.naturalOrder(); boolean publicType = false; Boolean allowSubclasses = null; boolean skipCreation = false; for (FactoryMethodDescriptor methodDescriptor : entry.getValue()) { extending.add(methodDescriptor.declaration().extendingType().getQualifiedName().toString()); for (TypeElement implementingType : methodDescriptor.declaration().implementingTypes()) { implementing.add(implementingType.getQualifiedName().toString()); } publicType |= methodDescriptor.publicMethod(); if (allowSubclasses == null) { allowSubclasses = methodDescriptor.declaration().allowSubclasses(); } else if (!allowSubclasses.equals(methodDescriptor.declaration().allowSubclasses())) { skipCreation = true; messager.printMessage( Kind.ERROR, "Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.", methodDescriptor.declaration().target(), methodDescriptor.declaration().mirror(), methodDescriptor.declaration().valuesMap().get("allowSubclasses")); } } if (!skipCreation) { try { factoryWriter.writeFactory( new FactoryDescriptor( entry.getKey(), Iterables.getOnlyElement(extending.build()), implementing.build(), publicType, ImmutableSet.copyOf(entry.getValue()), // TODO(gak): this needs to be indexed too implementationMethodDescriptors.build(), allowSubclasses)); } catch (IOException e) { messager.printMessage(Kind.ERROR, "failed"); } } } }
private static boolean isPublic(ExecutableElement method) { return method.getModifiers().contains(Modifier.PUBLIC); }