void init(Constructor constructor) { for (TypeVariable param : constructor.getTypeParameters()) { typeParameters.add(ElementFactory.getTypeParameterElement(param)); } type = TypeMirrorFactory.get(constructor); enclosingElement = ElementFactory.get(constructor.getDeclaringClass()); returnType = Typ.getNoType(TypeKind.VOID); Type[] genericParameterTypes = constructor.getGenericParameterTypes(); Annotation[][] parameterAnnotations = constructor.getParameterAnnotations(); int index = 0; for (Type param : genericParameterTypes) { parameters.add(ElementFactory.getVariableElement(param, parameterAnnotations[index++])); } varArgs = constructor.isVarArgs(); for (Type type : constructor.getGenericExceptionTypes()) { thrownTypes.add(TypeMirrorFactory.get(type)); } }
/** @author Timo Vesalainen */ public class ExecutableElementImpl extends ElementImpl implements ExecutableElement { private ExecutableType type; private List<TypeParameterElement> typeParameters = new ArrayList<>(); private TypeMirror returnType = Typ.getNoType(TypeKind.VOID); private List<VariableElement> parameters = new ArrayList<>(); private boolean varArgs; private List<TypeMirror> thrownTypes = new ArrayList<>(); private AnnotationValue defaultValue; @Override public TypeMirror asType() { return type; } public static class MethodBuilder extends ConstructorBuilder { public MethodBuilder( TypeElement enclosingElement, String name, List<? extends TypeMirror> classTypeArguments, Map<String, TypeParameterElement> classTypeParameterMap) { super(enclosingElement, ElementKind.METHOD, name, classTypeArguments, classTypeParameterMap); } public MethodBuilder setReturnType(Class<?> returnType, String... typeArgs) { return setReturnType(returnType.getCanonicalName(), typeArgs); } public MethodBuilder setReturnType(String returnType, String... typeArgs) { TypeMirror type = resolvType(returnType); if (typeArgs.length > 0 && type.getKind() == TypeKind.DECLARED) { DeclaredType dt = (DeclaredType) type; TypeElement te = (TypeElement) dt.asElement(); TypeMirror[] args = new TypeMirror[typeArgs.length]; for (int ii = 0; ii < args.length; ii++) { args[ii] = resolvType(typeArgs[ii]); } return setReturnType(Typ.getDeclaredType(te, args)); } else { if (typeArgs.length > 0) { throw new IllegalArgumentException("type args not used"); } return setReturnType(type); } } public MethodBuilder setReturnType(TypeMirror returnType) { exe.returnType = returnType; return this; } } public static class ConstructorBuilder { protected ExecutableElementImpl exe; private TypeParameterBuilder typeParamBuilder; public ConstructorBuilder( TypeElement enclosingElement, List<? extends TypeMirror> classTypeArguments, Map<String, TypeParameterElement> classTypeParameterMap) { this( enclosingElement, ElementKind.CONSTRUCTOR, "<init>", classTypeArguments, classTypeParameterMap); } public ConstructorBuilder( TypeElement enclosingElement, ElementKind kind, String name, List<? extends TypeMirror> classTypeArguments, Map<String, TypeParameterElement> classTypeParameterMap) { exe = new ExecutableElementImpl(enclosingElement, kind, name); typeParamBuilder = new TypeParameterBuilder( enclosingElement, exe.typeParameters, classTypeArguments, classTypeParameterMap); } public ExecutableElement getExecutableElement() { exe.type = new ExecutableTypeImpl(exe); return exe; } public ConstructorBuilder addModifier(Modifier modifier) { exe.modifiers.add(modifier); return this; } public ConstructorBuilder addModifiers(int modifier) { MethodFlags.setModifiers(exe.modifiers, modifier); return this; } public VariableBuilder addParameter(String name) { VariableBuilder variableBuilder = new VariableElementImpl.VariableBuilder(exe, name, typeParamBuilder); exe.parameters.add(variableBuilder.getVariableElement()); return variableBuilder; } public ConstructorBuilder addParameter(VariableElement param) { exe.parameters.add(param); return this; } public ConstructorBuilder addThrownType(Class<?> thrownType) { return addThrownType(resolvType(thrownType.getCanonicalName())); } public ConstructorBuilder addThrownType(String thrownType) { return addThrownType(resolvType(thrownType)); } public ConstructorBuilder addThrownType(TypeMirror thrownType) { exe.thrownTypes.add(thrownType); return this; } public List<TypeMirror> getTypeArguments() { return typeParamBuilder.getTypeArguments(); } protected TypeMirror resolvType(String type) { return typeParamBuilder.resolvType(type); } public ConstructorBuilder addTypeParameter(String name, Class<?>... bounds) { exe.typeParameters.add(typeParamBuilder.addTypeParameter(name, bounds)); return this; } public ConstructorBuilder addTypeParameter(String name, CharSequence... bounds) { exe.typeParameters.add(typeParamBuilder.addTypeParameter(name, bounds)); return this; } public ConstructorBuilder addTypeParameter(String name, TypeElement... bounds) { exe.typeParameters.add(typeParamBuilder.addTypeParameter(name, bounds)); return this; } public ConstructorBuilder addTypeParameter(String name, TypeMirror... bounds) { exe.typeParameters.add(typeParamBuilder.addTypeParameter(name, bounds)); return this; } public ConstructorBuilder addTypeParameter(TypeParameterElement param) { exe.typeParameters.add(typeParamBuilder.addTypeParameter(param)); return this; } } public ExecutableElementImpl(Element enclosingElement, ElementKind kind, String name) { super(kind, name); this.enclosingElement = enclosingElement; } ExecutableElementImpl(Constructor constructor) { super(ElementKind.CONSTRUCTOR, constructor, constructor.getModifiers(), "<init>"); } void init(Constructor constructor) { for (TypeVariable param : constructor.getTypeParameters()) { typeParameters.add(ElementFactory.getTypeParameterElement(param)); } type = TypeMirrorFactory.get(constructor); enclosingElement = ElementFactory.get(constructor.getDeclaringClass()); returnType = Typ.getNoType(TypeKind.VOID); Type[] genericParameterTypes = constructor.getGenericParameterTypes(); Annotation[][] parameterAnnotations = constructor.getParameterAnnotations(); int index = 0; for (Type param : genericParameterTypes) { parameters.add(ElementFactory.getVariableElement(param, parameterAnnotations[index++])); } varArgs = constructor.isVarArgs(); for (Type type : constructor.getGenericExceptionTypes()) { thrownTypes.add(TypeMirrorFactory.get(type)); } } ExecutableElementImpl(Method method) { super(ElementKind.METHOD, method, method.getModifiers(), method.getName()); } void init(Method method) { for (TypeVariable param : method.getTypeParameters()) { typeParameters.add(ElementFactory.getTypeParameterElement(param)); } type = TypeMirrorFactory.get(method); enclosingElement = ElementFactory.get(method.getDeclaringClass()); returnType = TypeMirrorFactory.get(method.getGenericReturnType()); Type[] genericParameterTypes = method.getGenericParameterTypes(); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); int index = 0; for (Type param : genericParameterTypes) { parameters.add(ElementFactory.getVariableElement(param, parameterAnnotations[index++])); } varArgs = method.isVarArgs(); for (Type type : method.getGenericExceptionTypes()) { thrownTypes.add(TypeMirrorFactory.get(type)); } Object defValue = method.getDefaultValue(); if (defValue != null) { defaultValue = new AnnotationValueImpl(defValue); } } @Override public List<? extends TypeParameterElement> getTypeParameters() { return typeParameters; } @Override @SuppressWarnings("unchecked") public List<? extends Element> getEnclosedElements() { return Collections.EMPTY_LIST; } @Override public <R, P> R accept(ElementVisitor<R, P> v, P p) { return v.visitExecutable(this, p); } @Override public TypeMirror getReturnType() { return returnType; } @Override public List<? extends VariableElement> getParameters() { return parameters; } @Override public boolean isVarArgs() { return varArgs; } @Override public List<? extends TypeMirror> getThrownTypes() { return thrownTypes; } @Override public AnnotationValue getDefaultValue() { return defaultValue; } @Override public int hashCode() { int hash = 5; return hash; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final ExecutableElementImpl other = (ExecutableElementImpl) obj; if (!Objects.equals(this.typeParameters, other.typeParameters)) { return false; } if (!Objects.equals(this.enclosingElement, other.enclosingElement)) { return false; } if (!Objects.equals(this.returnType, other.returnType)) { return false; } if (!Objects.equals(this.parameters, other.parameters)) { return false; } if (this.varArgs != other.varArgs) { return false; } if (!Objects.equals(this.thrownTypes, other.thrownTypes)) { return false; } if (!Objects.equals(this.defaultValue, other.defaultValue)) { return false; } return true; } @Override public String toString() { return "ExecutableElementImpl{" + getSimpleName() + '}'; } }