下面列出了javax.lang.model.element.ExecutableElement#getTypeParameters ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static Element paramElementFor(Element methodOrClass, ParamTree ptag) {
ElementKind kind = methodOrClass.getKind();
List<? extends Element> params = Collections.emptyList();
if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
ExecutableElement ee = (ExecutableElement) methodOrClass;
params = ptag.isTypeParameter()
? ee.getTypeParameters()
: ee.getParameters();
} else if (kind.isClass() || kind.isInterface()) {
TypeElement te = (TypeElement) methodOrClass;
params = te.getTypeParameters();
}
for (Element param : params) {
if (param.getSimpleName().contentEquals(ptag.getName().getName())) {
return param;
}
}
return null;
}
private TypeExtractor processTypeParameters(ExecutableElement method, EncodedElement.Builder builder) {
boolean isStatic = method.getModifiers().contains(Modifier.STATIC);
TypeExtractor typesReader = isStatic
? new TypeExtractor(types, method)
: this.typesReader;
for (TypeParameterElement p : method.getTypeParameters()) {
String name = p.getSimpleName().toString();
ImmutableList<Defined> bounds = typesReader.getDefined(p.getBounds());
if (!isStatic) {
typesReader = typesReader.withParameter(name, bounds);
}
builder.addTypeParams(new EncodedElement.TypeParam.Builder()
.name(name)
.addAllBounds(bounds)
.build());
}
builder.typeParameters(typesReader.parameters);
return typesReader;
}
static List<TypeVariableName> getTypeVariables(ExecutableElement method) {
final List<TypeVariableName> typeVariables = new ArrayList<>();
for (TypeParameterElement typeParameterElement : method.getTypeParameters()) {
typeVariables.add(
TypeVariableName.get(
typeParameterElement.getSimpleName().toString(), getBounds(typeParameterElement)));
}
return typeVariables;
}
private MethodSignature getSignature(TypeElement classElement, ExecutableElement element, String[] typeParameters, Types types) {
String name = element.getSimpleName().toString();
String[] parameters = new String[element.getParameters().size()];
for (int i = 0; i < parameters.length; i++) {
VariableElement var = element.getParameters().get(i);
TypeMirror type = var.asType();
String typeString = null;
if (type.getKind() == TypeKind.TYPEVAR) {
List<? extends TypeParameterElement> declaredTypeParameters = element.getTypeParameters();
if (declaredTypeParameters.isEmpty()) {
declaredTypeParameters = classElement.getTypeParameters();
}
int j = -1;
for (TypeParameterElement typeParam : declaredTypeParameters) {
j++;
if (typeParam.getSimpleName().toString().equals(type.toString())) {
break;
}
}
// FIXME why we were doing this for signatures ??
// if (j >= 0 && j < typeParameters.length) {
// typeString = typeParameters[j];
// } else {
typeString = types.erasure(type).toString();
// }
} else {
typeString = type.toString();
}
int index = typeString.indexOf('<');
if (index >= 0) {
typeString = typeString.substring(0, index);
}
parameters[i] = typeString;
}
return new MethodSignature(name, parameters);
}
public MethodEntity(ExecutableElement methodElement, Types typeMirror, Elements elementUtils) {
this.methodElement = methodElement;
this.returnType = methodElement.getReturnType().toString();
this.parameterElements = methodElement.getParameters();
this.isVarArgs = methodElement.isVarArgs();
this.methodName = methodElement.getSimpleName().toString();
this.exceptionTypes = methodElement.getThrownTypes();
this.typeParameterElements = methodElement.getTypeParameters();
this.classSimpleName = methodElement.getEnclosingElement().getSimpleName().toString();
this.classQualifiedName = ((TypeElement) methodElement.getEnclosingElement()).getQualifiedName().toString();
this.packageName = elementUtils.getPackageOf(methodElement).getQualifiedName().toString();
}
private static Map<String, Variable> overridenTypeVariables(ExecutableElement method) {
Map<String, Variable> variables = new HashMap<>();
for (TypeParameterElement typeParameter : method.getTypeParameters()) {
variables.put(typeParameter.toString(), new Variable());
}
return variables;
}
/**
* Returns a new method spec builder that overrides {@code method}.
*
* <p>This will copy its visibility modifiers, type parameters, return type, name, parameters, and
* throws declarations. An {@link Override} annotation will be added.
*
* <p>Note that in JavaPoet 1.2 through 1.7 this method retained annotations from the method and
* parameters of the overridden method. Since JavaPoet 1.8 annotations must be added separately.
*/
public static Builder overriding(ExecutableElement method) {
checkNotNull(method, "method == null");
Set<Modifier> modifiers = method.getModifiers();
if (modifiers.contains(Modifier.PRIVATE)
|| modifiers.contains(Modifier.FINAL)
|| modifiers.contains(Modifier.STATIC)) {
throw new IllegalArgumentException("cannot override method with modifiers: " + modifiers);
}
String methodName = method.getSimpleName().toString();
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(methodName);
methodBuilder.addAnnotation(Override.class);
modifiers = new LinkedHashSet<>(modifiers);
modifiers.remove(Modifier.ABSTRACT);
modifiers.remove(Util.DEFAULT); // LinkedHashSet permits null as element for Java 7
methodBuilder.addModifiers(modifiers);
for (TypeParameterElement typeParameterElement : method.getTypeParameters()) {
TypeVariable var = (TypeVariable) typeParameterElement.asType();
methodBuilder.addTypeVariable(TypeVariableName.get(var));
}
methodBuilder.returns(TypeName.get(method.getReturnType()));
methodBuilder.addParameters(ParameterSpec.parametersOf(method));
methodBuilder.varargs(method.isVarArgs());
for (TypeMirror thrownType : method.getThrownTypes()) {
methodBuilder.addException(TypeName.get(thrownType));
}
return methodBuilder;
}
/**
* Returns a new method spec builder that overrides {@code method}.
*
* <p>This will copy its visibility modifiers, type parameters, return type, name, parameters, and
* throws declarations. An {@link Override} annotation will be added.
*
* <p>Note that in JavaPoet 1.2 through 1.7 this method retained annotations from the method and
* parameters of the overridden method. Since JavaPoet 1.8 annotations must be added separately.
*/
public static Builder overriding(ExecutableElement method) {
checkNotNull(method, "method == null");
Set<Modifier> modifiers = method.getModifiers();
if (modifiers.contains(Modifier.PRIVATE)
|| modifiers.contains(Modifier.FINAL)
|| modifiers.contains(Modifier.STATIC)) {
throw new IllegalArgumentException("cannot override method with modifiers: " + modifiers);
}
String methodName = method.getSimpleName().toString();
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(methodName);
methodBuilder.addAnnotation(Override.class);
modifiers = new LinkedHashSet<>(modifiers);
modifiers.remove(Modifier.ABSTRACT);
modifiers.remove(Util.DEFAULT); // LinkedHashSet permits null as element for Java 7
methodBuilder.addModifiers(modifiers);
for (TypeParameterElement typeParameterElement : method.getTypeParameters()) {
TypeVariable var = (TypeVariable) typeParameterElement.asType();
methodBuilder.addTypeVariable(TypeVariableName.get(var));
}
methodBuilder.returns(TypeName.get(method.getReturnType()));
methodBuilder.addParameters(ParameterSpec.parametersOf(method));
methodBuilder.varargs(method.isVarArgs());
for (TypeMirror thrownType : method.getThrownTypes()) {
methodBuilder.addException(TypeName.get(thrownType));
}
return methodBuilder;
}
private static boolean isValidClassTypeParam(ExecutableElement elt, TypeInfo type) {
if (type.getKind() == ClassKind.CLASS_TYPE && type.isParameterized()) {
ParameterizedTypeInfo parameterized = (ParameterizedTypeInfo) type;
TypeInfo arg = parameterized.getArg(0);
if (arg.isVariable()) {
TypeVariableInfo variable = (TypeVariableInfo) arg;
for (TypeParameterElement typeParamElt : elt.getTypeParameters()) {
if (typeParamElt.getSimpleName().toString().equals(variable.getName())) {
return true;
}
}
}
}
return false;
}
/**
* Tests whether a given parameter can be given to a static method like
* {@code ImmutableMap.copyOf} to produce a value that can be assigned to the given target type.
*
* <p>For example, suppose we have this method in {@code ImmutableMap}:<br>
* {@code static <K, V> ImmutableMap<K, V> copyOf(Map<? extends K, ? extends V>)}<br>
* and we want to know if we can do this:
*
* <pre>
* {@code ImmutableMap<String, Integer> actualParameter = ...;}
* {@code ImmutableMap<String, Number> target = ImmutableMap.copyOf(actualParameter);}
* </pre>
*
* We will infer {@code K=String}, {@code V=Number} based on the target type, and then rewrite the
* formal parameter type from<br>
* {@code Map<? extends K, ? extends V>} to<br>
* {@code Map<? extends String, ? extends Number>}. Then we can check whether
* {@code actualParameter} is assignable to that.
*
* <p>The logic makes some simplifying assumptions, which are met for the {@code copyOf} and
* {@code of} methods that we use this for. The method must be static, it must have exactly one
* parameter, and it must have type parameters without bounds that are the same as the type
* parameters of its return type. We can see that these assumptions are met for the
* {@code ImmutableMap.copyOf} example above.
*/
static boolean canAssignStaticMethodResult(
ExecutableElement method,
TypeMirror actualParameterType,
TypeMirror targetType,
Types typeUtils) {
if (!targetType.getKind().equals(TypeKind.DECLARED)
|| !method.getModifiers().contains(Modifier.STATIC)
|| method.getParameters().size() != 1) {
return false;
}
List<? extends TypeParameterElement> typeParameters = method.getTypeParameters();
List<? extends TypeMirror> targetTypeArguments =
MoreTypes.asDeclared(targetType).getTypeArguments();
if (typeParameters.size() != targetTypeArguments.size()) {
return false;
}
Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>();
for (int i = 0; i < typeParameters.size(); i++) {
TypeVariable v = MoreTypes.asTypeVariable(typeParameters.get(i).asType());
typeVariables.put(MoreTypes.equivalence().wrap(v), targetTypeArguments.get(i));
}
TypeMirror formalParameterType = method.getParameters().get(0).asType();
SubstitutionVisitor substitutionVisitor = new SubstitutionVisitor(typeVariables, typeUtils);
TypeMirror substitutedParameterType = substitutionVisitor.visit(formalParameterType, null);
if (substitutedParameterType.getKind().equals(TypeKind.WILDCARD)) {
// If the target type is Optional<? extends Foo> then <T> T Optional.of(T) will give us
// ? extends Foo here, and typeUtils.isAssignable will return false. But we can in fact
// give a Foo as an argument, so we just replace ? extends Foo with Foo.
WildcardType wildcard = MoreTypes.asWildcard(substitutedParameterType);
if (wildcard.getExtendsBound() != null) {
substitutedParameterType = wildcard.getExtendsBound();
}
}
return typeUtils.isAssignable(actualParameterType, substitutedParameterType);
}
private MethodSpec buildOpMethod(
String methodName, TypeElement opClass, ExecutableElement endpointMethod,
boolean describeByClass, boolean deprecated) {
MethodSpec.Builder builder =
MethodSpec.methodBuilder(methodName)
.addModifiers(Modifier.PUBLIC)
.returns(TypeName.get(endpointMethod.getReturnType()))
.varargs(endpointMethod.isVarArgs())
.addJavadoc("$L", buildOpMethodJavadoc(opClass, endpointMethod, describeByClass));
if (deprecated) {
builder.addAnnotation(Deprecated.class);
}
for (TypeParameterElement tp : endpointMethod.getTypeParameters()) {
TypeVariableName tvn = TypeVariableName.get((TypeVariable) tp.asType());
builder.addTypeVariable(tvn);
}
for (TypeMirror thrownType : endpointMethod.getThrownTypes()) {
builder.addException(TypeName.get(thrownType));
}
StringBuilder call = new StringBuilder();
if (!NoType.class.isAssignableFrom(endpointMethod.getReturnType().getClass())) {
call.append("return ");
}
call.append("$T.")
.append(endpointMethod.getSimpleName())
.append("(scope");
boolean first = true;
for (VariableElement param : endpointMethod.getParameters()) {
ParameterSpec p = ParameterSpec.get(param);
if (first) {
first = false;
continue;
}
call.append(", ");
call.append(p.name);
builder.addParameter(p);
}
call.append(")");
builder.addStatement(call.toString(), ClassName.get(opClass));
return builder.build();
}
void validateFactoryMethod(TypeElement classElement, DomainMeta domainMeta) {
outer:
for (ExecutableElement method : ElementFilter.methodsIn(classElement.getEnclosedElements())) {
if (!method.getSimpleName().contentEquals(domainMeta.getFactoryMethod())) {
continue;
}
if (method.getModifiers().contains(Modifier.PRIVATE)) {
continue;
}
if (!method.getModifiers().contains(Modifier.STATIC)) {
continue;
}
if (method.getParameters().size() != 1) {
continue;
}
TypeMirror parameterType = method.getParameters().get(0).asType();
if (!ctx.getMoreTypes().isAssignableWithErasure(domainMeta.getValueType(), parameterType)) {
continue;
}
TypeMirror returnType = ctx.getMoreTypes().erasure(method.getReturnType());
if (!ctx.getMoreTypes().isAssignableWithErasure(returnType, domainMeta.getType())) {
continue;
}
List<? extends TypeParameterElement> classTypeParams = classElement.getTypeParameters();
List<? extends TypeParameterElement> methodTypeParams = method.getTypeParameters();
if (classTypeParams.size() != methodTypeParams.size()) {
continue;
}
for (Iterator<? extends TypeParameterElement> cit = classTypeParams.iterator(),
mit = methodTypeParams.iterator();
cit.hasNext() && mit.hasNext(); ) {
TypeParameterElement classTypeParam = cit.next();
TypeParameterElement methodTypeParam = mit.next();
if (!ctx.getMoreTypes()
.isSameTypeWithErasure(classTypeParam.asType(), methodTypeParam.asType())) {
continue outer;
}
}
return;
}
throw new AptException(
Message.DOMA4106,
classElement,
new Object[] {
domainMeta.getFactoryMethod(), classElement.asType(), domainMeta.getValueType()
});
}
/**
* Returns a new method spec builder that overrides {@code method}.
*
* <p>This will copy its visibility modifiers, type parameters, return type, name, parameters, and
* throws declarations. An {@link Override} annotation will be added.
*
* <p>Note that in JavaPoet 1.2 through 1.7 this method retained annotations from the method and
* parameters of the overridden method. Since JavaPoet 1.8 annotations must be added separately.
*/
public static Builder overriding(ExecutableElement method) {
checkNotNull(method, "method == null");
Element enclosingClass = method.getEnclosingElement();
if (enclosingClass.getModifiers().contains(Modifier.FINAL)) {
throw new IllegalArgumentException("Cannot override method on final class " + enclosingClass);
}
Set<Modifier> modifiers = method.getModifiers();
if (modifiers.contains(Modifier.PRIVATE)
|| modifiers.contains(Modifier.FINAL)
|| modifiers.contains(Modifier.STATIC)) {
throw new IllegalArgumentException("cannot override method with modifiers: " + modifiers);
}
String methodName = method.getSimpleName().toString();
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(methodName);
methodBuilder.addAnnotation(Override.class);
modifiers = new LinkedHashSet<>(modifiers);
modifiers.remove(Modifier.ABSTRACT);
modifiers.remove(Modifier.DEFAULT);
methodBuilder.addModifiers(modifiers);
for (TypeParameterElement typeParameterElement : method.getTypeParameters()) {
TypeVariable var = (TypeVariable) typeParameterElement.asType();
methodBuilder.addTypeVariable(TypeVariableName.get(var));
}
methodBuilder.returns(TypeName.get(method.getReturnType()));
methodBuilder.addParameters(ParameterSpec.parametersOf(method));
methodBuilder.varargs(method.isVarArgs());
for (TypeMirror thrownType : method.getThrownTypes()) {
methodBuilder.addException(TypeName.get(thrownType));
}
return methodBuilder;
}