下面列出了javax.lang.model.type.IntersectionType#javax.lang.model.element.TypeParameterElement 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private int getFactoryProxyIndex(TypeName gtname) throws AnnotationProcessingException {
int ret = -1;
boolean found = false;
if (gtname instanceof TypeVariableName) {
for (TypeParameterElement tpe : m_elem.getTypeParameters()) {
++ret;
if (tpe.toString().equals(gtname.toString())) {
found = true;
break;
}
}
if (!found) {
throw new AnnotationProcessingException(null, "%s type is not found during factory proxy query.",
gtname.toString());
}
} else {
throw new AnnotationProcessingException(null, "%s type is not generic type for factory proxy query.",
gtname.toString());
}
return ret;
}
private void buildTypeArguments(DeclaredType type, StringBuilder sb) {
Element elem = type.asElement();
List<? extends TypeMirror> typeArguments = type.getTypeArguments();
if (!typeArguments.isEmpty()) {
sb.append('<');
for (TypeMirror typeArg : typeArguments) {
TypeParameterElement typeParam = TypeUtil.asTypeParameterElement(typeArg);
if (typeParam != null && elem.equals(typeParam.getEnclosingElement())) {
// The type param is directly declared by the type being emitted so we don't need to fully
// qualify it as buildTypeSignature() would.
sb.append('T');
sb.append(ElementUtil.getName(typeParam));
sb.append(';');
} else {
buildTypeSignature(typeArg, sb);
}
}
sb.append('>');
}
}
/** Get the type variables from the given {@link TypeElement}. */
public static List<TypeVariableName> getTypeVariables(TypeElement typeElement) {
final List<? extends TypeParameterElement> typeParameters = typeElement.getTypeParameters();
final int typeParameterCount = typeParameters.size();
final List<TypeVariableName> typeVariables = new ArrayList<>(typeParameterCount);
for (TypeParameterElement typeParameterElement : typeParameters) {
final int boundTypesCount = typeParameterElement.getBounds().size();
final TypeName[] boundsTypeNames = new TypeName[boundTypesCount];
for (int i = 0; i < boundTypesCount; i++) {
boundsTypeNames[i] = TypeName.get(typeParameterElement.getBounds().get(i));
}
final TypeVariableName typeVariable =
TypeVariableName.get(typeParameterElement.getSimpleName().toString(), boundsTypeNames);
typeVariables.add(typeVariable);
}
return typeVariables;
}
@Override
public StandaloneTypeMirror asType() {
if (typeMirror == null) {
typeMirror =
new StandaloneExecutableType(
getReturnType(),
getTypeParameters().stream()
.map(TypeParameterElement::asType)
.map(type -> (TypeVariable) type)
.collect(Collectors.toList()),
getParameters().stream().map(VariableElement::asType).collect(Collectors.toList()),
getThrownTypes(),
getAnnotationMirrors());
}
return typeMirror;
}
/**
* The type parameters to place on the builder, with the "extends ..." bounds.
*/
String alligatorWithBounds() {
List<TypeParameterElement> allParameters = allParameters();
if (allParameters.isEmpty()) {
return "";
}
StringBuilder alligator = new StringBuilder("<");
String separator = "";
for (TypeParameterElement param : allParameters) {
alligator.append(separator);
separator = ", ";
alligator.append(param.toString());
for (TypeMirror bound : param.getBounds()) {
alligator.append(" extends ").append(bound);
}
}
return alligator.append(">").toString();
}
@Test
public void testMultipleTypeParameters() throws IOException {
compile("class Foo<T, U extends java.lang.CharSequence> { }");
TypeMirror objectType = elements.getTypeElement("java.lang.Object").asType();
TypeMirror charSequenceType = elements.getTypeElement("java.lang.CharSequence").asType();
TypeElement fooElement = elements.getTypeElement("Foo");
List<? extends TypeParameterElement> typeParameters = fooElement.getTypeParameters();
assertSame(2, typeParameters.size());
TypeParameterElement tParam = typeParameters.get(0);
List<? extends TypeMirror> bounds = tParam.getBounds();
assertSame(1, bounds.size());
assertSameType(objectType, bounds.get(0));
TypeParameterElement uParam = typeParameters.get(1);
bounds = uParam.getBounds();
assertSame(1, bounds.size());
assertSameType(charSequenceType, bounds.get(0));
}
/**
* Make a TypeVariableName for the given TypeMirror. This form is used internally to avoid
* infinite recursion in cases like {@code Enum<E extends Enum<E>>}. When we encounter such a
* thing, we will make a TypeVariableName without bounds and add that to the {@code typeVariables}
* map before looking up the bounds. Then if we encounter this TypeVariable again while
* constructing the bounds, we can just return it from the map. And, the code that put the entry
* in {@code variables} will make sure that the bounds are filled in before returning.
*/
static TypeVariableName get(
TypeVariable mirror, Map<TypeParameterElement, TypeVariableName> typeVariables) {
TypeParameterElement element = (TypeParameterElement) mirror.asElement();
TypeVariableName typeVariableName = typeVariables.get(element);
if (typeVariableName == null) {
// Since the bounds field is public, we need to make it an unmodifiableList. But we control
// the List that that wraps, which means we can change it before returning.
List<TypeName> bounds = new ArrayList<>();
List<TypeName> visibleBounds = Collections.unmodifiableList(bounds);
typeVariableName = new TypeVariableName(element.getSimpleName().toString(), visibleBounds);
typeVariables.put(element, typeVariableName);
for (TypeMirror typeMirror : element.getBounds()) {
bounds.add(TypeName.get(typeMirror, typeVariables));
}
bounds.remove(OBJECT);
}
return typeVariableName;
}
private int getFactoryProxyIndex(TypeName gtname) throws AnnotationProcessingException {
int ret = -1;
boolean found = false;
if (gtname instanceof TypeVariableName) {
for (TypeParameterElement tpe : m_elem.getTypeParameters()) {
++ret;
if (tpe.toString().equals(gtname.toString())) {
found = true;
break;
}
}
if (!found) {
throw new AnnotationProcessingException(null, "%s type is not found during factory proxy query.",
gtname.toString());
}
} else {
throw new AnnotationProcessingException(null, "%s type is not generic type for factory proxy query.",
gtname.toString());
}
return ret;
}
@Override
public Void visitType(TypeElement element, SignatureVisitor visitor) {
if (!signatureRequired(element)) {
return null;
}
for (TypeParameterElement typeParameterElement : element.getTypeParameters()) {
typeParameterElement.accept(this, visitor);
}
TypeMirror superclass = element.getSuperclass();
if (superclass.getKind() != TypeKind.NONE) {
superclass.accept(typeVisitorAdapter, visitor.visitSuperclass());
} else {
// Interface type; implicit superclass of Object
SignatureVisitor superclassVisitor = visitor.visitSuperclass();
superclassVisitor.visitClassType("java/lang/Object");
superclassVisitor.visitEnd();
}
for (TypeMirror interfaceType : element.getInterfaces()) {
interfaceType.accept(typeVisitorAdapter, visitor.visitInterface());
}
return null;
}
private void completeTypeVarName(Element forElement, String prefix, int substitutionOffset) {
if (prefix.length() > 0) {
if (prefix.charAt(0) == '<') {
prefix = prefix.substring(1, prefix.length());
} else {
// not type param
return;
}
}
List<? extends TypeParameterElement> tparams = (forElement.getKind().isClass() || forElement.getKind().isInterface())
? ((TypeElement) forElement).getTypeParameters()
: ((ExecutableElement) forElement).getTypeParameters();
for (TypeParameterElement typeVariable : tparams) {
String name = typeVariable.getSimpleName().toString();
if (name.startsWith(prefix)) {
items.add(JavadocCompletionItem.createNameItem(
'<' + name + '>', substitutionOffset));
}
}
}
@Override
public Void visitTypeParameter(TypeParameterElement element, SignatureVisitor visitor) {
visitor.visitFormalTypeParameter(element.getSimpleName().toString());
for (TypeMirror boundType : element.getBounds()) {
boolean isClass;
try {
if (boundType.getKind() == TypeKind.DECLARED) {
isClass = ((DeclaredType) boundType).asElement().getKind().isClass();
} else {
isClass = boundType.getKind() == TypeKind.TYPEVAR;
}
} catch (CannotInferException e) {
// We can't know whether an inferred type is a class or interface, but it turns out
// the compiler does not distinguish between them when reading signatures, so we can
// write inferred types as interface bounds. We go ahead and write all bounds as
// interface bounds to make the SourceAbiCompatibleSignatureVisitor possible.
isClass = false;
}
boundType.accept(
typeVisitorAdapter,
isClass ? visitor.visitClassBound() : visitor.visitInterfaceBound());
}
return null;
}
@Test
void getTypeName() {
addProcessor(
new TestProcessor() {
@Override
protected void run() {
TypeMirror intType = ctx.getMoreTypes().getPrimitiveType(TypeKind.INT);
assertEquals("int", ctx.getMoreTypes().getTypeName(intType));
TypeMirror listType = ctx.getMoreElements().getTypeElement(List.class).asType();
assertEquals("java.util.List<E>", ctx.getMoreTypes().getTypeName(listType));
}
},
new TestProcessor() {
@Override
protected void run() {
TypeElement typeElement = ctx.getMoreElements().getTypeElement(NumberList.class);
TypeParameterElement typeParameterElement =
typeElement.getTypeParameters().iterator().next();
assertEquals("E", ctx.getMoreTypes().getTypeName(typeParameterElement.asType()));
}
});
}
TypeMirror inferType(
TypeVariable typeVariable, TypeElement classElement, TypeMirror classMirror) {
DeclaredType declaredType = ctx.getMoreTypes().toDeclaredType(classMirror);
if (declaredType == null) {
return null;
}
List<? extends TypeMirror> args = declaredType.getTypeArguments();
if (args.isEmpty()) {
return null;
}
int argsSize = args.size();
int index = 0;
for (TypeParameterElement typeParam : classElement.getTypeParameters()) {
if (index >= argsSize) {
break;
}
if (ctx.getMoreTypes().isSameTypeWithErasure(typeVariable, typeParam.asType())) {
return args.get(index);
}
index++;
}
return null;
}
private void printFormalTypeParameters(Parameterizable e,
boolean pad) {
List<? extends TypeParameterElement> typeParams = e.getTypeParameters();
if (typeParams.size() > 0) {
writer.print("<");
boolean first = true;
for(TypeParameterElement tpe: typeParams) {
if (!first)
writer.print(", ");
printAnnotationsInline(tpe);
writer.print(tpe.toString());
first = false;
}
writer.print(">");
if (pad)
writer.print(" ");
}
}
void writeType(TypeElement e) {
if (!acceptType.test(task.getElements().getBinaryName(e).toString()))
return ;
try {
analyzeElement(e);
writeTypes(e.getInterfaces());
out.write(e.getNestingKind().toString());
out.write(e.getQualifiedName().toString());
write(e.getSuperclass());
for (TypeParameterElement param : e.getTypeParameters()) {
visit(param, null);
}
List<Element> defs = new ArrayList<>(e.getEnclosedElements()); //XXX: forcing ordering for members - not completely correct!
Collections.sort(defs, (e1, e2) -> e1.toString().compareTo(e2.toString()));
for (Element def : defs) {
visit(def, null);
}
out.write("\n");
} catch (IOException ex) {
ex.printStackTrace();
}
}
private static boolean sameTypeParameters(TypeElement a, TypeElement b) {
int nTypeParameters = a.getTypeParameters().size();
if (nTypeParameters != b.getTypeParameters().size()) {
return false;
}
for (int i = 0; i < nTypeParameters; i++) {
TypeParameterElement aParam = a.getTypeParameters().get(i);
TypeParameterElement bParam = b.getTypeParameters().get(i);
if (!aParam.getSimpleName().equals(bParam.getSimpleName())) {
return false;
}
Set<TypeMirror> autoValueBounds = new TypeMirrorSet(aParam.getBounds());
Set<TypeMirror> builderBounds = new TypeMirrorSet(bParam.getBounds());
if (!autoValueBounds.equals(builderBounds)) {
return false;
}
}
return true;
}
/**
* Convenience method to convert element to string representation for error
* messages
*
* @param element Element to inspect
* @return string representation of element name
*/
public static String getElementType(Element element) {
if (element instanceof TypeElement) {
return "TypeElement";
} else if (element instanceof ExecutableElement) {
return "ExecutableElement";
} else if (element instanceof VariableElement) {
return "VariableElement";
} else if (element instanceof PackageElement) {
return "PackageElement";
} else if (element instanceof TypeParameterElement) {
return "TypeParameterElement";
}
return element.getClass().getSimpleName();
}
private Map<TypeParameterElement, TypeMirror> getChildInstanceOfClassFromGeneric(final TypeElement typeElement, final Class<?> aClass) {
Map<TypeParameterElement, TypeMirror> result = new HashMap<>();
for (TypeParameterElement element : typeElement.getTypeParameters()) {
List<? extends TypeMirror> bounds = element.getBounds();
for (TypeMirror bound : bounds) {
if (bound instanceof DeclaredType && ((DeclaredType) bound).asElement() instanceof TypeElement) {
Collection<TypeMirror> viewsType = getViewsType((TypeElement) ((DeclaredType) bound).asElement());
boolean isViewType = false;
for (TypeMirror viewType : viewsType) {
if (((DeclaredType) viewType).asElement().toString().equals(aClass.getCanonicalName())) {
isViewType = true;
}
}
if (isViewType) {
result.put(element, bound);
break;
}
}
}
}
return result;
}
@Override public Boolean visitTypeVariable(TypeVariable t, Set<TypeParameterElement> visited) {
TypeParameterElement element = (TypeParameterElement) t.asElement();
if (visited.contains(element)) return false;
visited.add(element);
for (TypeMirror bound : element.getBounds()) {
if (bound.accept(this, visited)) return true;
}
return false;
}
@Test
public void testGetTreeNullGetPathRoundtripTypeParameterElement() throws IOException {
compile("class Foo<T, U> { }");
TypeParameterElement tElement = elements.getTypeElement("Foo").getTypeParameters().get(0);
Tree tTree = trees.getTree(tElement);
TreePath tPath = trees.getPath(tElement);
if (JavaVersion.getMajorVersion() < 11) {
assertNull(tTree); // Odd behavior by javac, but we'll match it
}
assertSame(tElement, trees.getElement(tPath));
}
private TypeMirror[] argumentsAsArray(
Map<String, TypeMirror> parametersToArguments, TypeElement adapterElement) {
List<? extends TypeParameterElement> adapterParameters = adapterElement.getTypeParameters();
TypeMirror[] adapterArguments = new TypeMirror[adapterParameters.size()];
for (int i = 0; i < adapterParameters.size(); i++) {
TypeParameterElement parameter = adapterParameters.get(i);
adapterArguments[i] = parametersToArguments.get(parameter.getSimpleName().toString());
if (adapterArguments[i] == null) {
throw new AssertionError("Missing parameter information " + parameter);
}
}
return adapterArguments;
}
@Override public TypeKey visitArray(ArrayType t, Set<TypeParameterElement> visited) {
switch (t.getKind()) {
case BOOLEAN: return PrimitiveArrayKey.BOOLEAN_ARRAY;
case BYTE: return PrimitiveArrayKey.BYTE_ARRAY;
case SHORT: return PrimitiveArrayKey.SHORT_ARRAY;
case INT: return PrimitiveArrayKey.INT_ARRAY;
case LONG: return PrimitiveArrayKey.LONG_ARRAY;
case CHAR: return PrimitiveArrayKey.CHAR_ARRAY;
case FLOAT: return PrimitiveArrayKey.FLOAT_ARRAY;
case DOUBLE: return PrimitiveArrayKey.DOUBLE_ARRAY;
default: return ArrayKey.of(t.getComponentType().accept(this, visited));
}
}
private static void appendTypeParameterWithBounds(
TypeParameterElement typeParameter, StringBuilder sb) {
sb.append(typeParameter.getSimpleName());
String sep = " extends ";
for (TypeMirror bound : typeParameter.getBounds()) {
if (!bound.toString().equals("java.lang.Object")) {
sb.append(sep);
sep = " & ";
sb.append(bound);
}
}
}
public TypeParametersDef getTypeParametersDef(Parameterizable element) {
assertNotNull(element);
List<? extends TypeParameterElement> typeParameters = element.getTypeParameters();
List<String> typeParameterNames = getTypeParameterNames(typeParameters);
Iterator<String> values = typeParameterNames.iterator();
Iterator<? extends TypeParameterElement> keys = typeParameters.iterator();
LinkedHashMap<TypeParameterElement, String> map = new LinkedHashMap<>();
while (keys.hasNext() && values.hasNext()) {
map.put(keys.next(), values.next());
}
return new TypeParametersDef(map);
}
private static TypeName[] getBounds(TypeParameterElement typeParameterElement) {
final TypeName[] bounds = new TypeName[typeParameterElement.getBounds().size()];
for (int i = 0, size = typeParameterElement.getBounds().size(); i < size; i++) {
bounds[i] = TypeName.get(typeParameterElement.getBounds().get(i));
}
return bounds;
}
@Override
public Void visitTypeParameter(TypeParameterElement e, Void p) {
if (e.asType().getKind() == TypeKind.DECLARED) {
types.add(e.asType().toString());
}
return super.visitTypeParameter(e, p);
}
/**
* Makes a tree representing the given {@code TypeParameterElement}.
*
* @param typeParamElem {@code TypeParameterElement} to make a copy of
* @param maker tree maker to use when for creation of the copy
* @return {@code Tree} respresenting the given
* {@code TypeParameterElement}
*/
private static TypeParameterTree makeCopy(TypeParameterElement typeParamElem,
TreeMaker maker) {
return maker.TypeParameter(
typeParamElem.getSimpleName(),
makeDeclaredTypesCopy((List<? extends DeclaredType>)
typeParamElem.getBounds(),
maker));
}
private static String[] collectVars(List<? extends TypeParameterElement> typeParameters) {
String[] vars = new String[typeParameters.size()];
int c = 0;
for (TypeParameterElement p : typeParameters) {
vars[c++] = p.getSimpleName().toString();
}
return vars;
}
@Override
public String generateClass(Context context, String className, String classToExtend,
boolean isFinal) {
String packageName = context.packageName();
TypeElement autoValueClass = context.autoValueClass();
List<? extends TypeParameterElement> typeParameters = autoValueClass.getTypeParameters();
Name superName = autoValueClass.getSimpleName();
Map<String, ExecutableElement> properties = context.properties();
TypeSpec.Builder subclass = TypeSpec.classBuilder(className) //
.addModifiers(isFinal ? Modifier.FINAL : Modifier.ABSTRACT) //
.addMethod(generateConstructor(properties)) //
.addMethod(generateToString(superName, properties));
ClassName superclass = ClassName.get(packageName, classToExtend);
if (typeParameters.isEmpty()) {
subclass.superclass(superclass);
} else {
List<TypeVariableName> typeVariables = new ArrayList<>();
for (TypeParameterElement typeParameter : typeParameters) {
typeVariables.add(TypeVariableName.get(typeParameter));
}
subclass.addTypeVariables(typeVariables)
.superclass(
ParameterizedTypeName.get(superclass, typeVariables.toArray(new TypeName[0])));
}
JavaFile javaFile = JavaFile.builder(packageName, subclass.build()).build();
return javaFile.toString();
}
public void detectInheritance(ProcessingEnvironment env) {
Collection<FeatureNode> featureNodes = getFeatureNodes();
for (FeatureNode featureNode : featureNodes) {
// feature has inheriting features if it is parametrized with generics
List<? extends TypeParameterElement> typeParams =
featureNode.getElement().getTypeParameters();
if (typeParams.size() > 0) {
featureNode.setHasInheritingFeatureNodes(true);
continue;
}
// look up for super-features within collected nodes
TypeMirror superType = featureNode.getElement().getSuperclass();
while (superType.getKind() != TypeKind.NONE) {
for (FeatureNode otherFeatureNode : featureNodes) {
if (featureNode == otherFeatureNode) {
continue;
}
Name otherName = otherFeatureNode.getElement().getQualifiedName();
Name superName = ((TypeElement) env.getTypeUtils()
.asElement(superType)).getQualifiedName();
if (otherName.equals(superName)) {
featureNode.setSuperFeatureNode(otherFeatureNode);
break;
}
}
superType = ((TypeElement) env.getTypeUtils().asElement(superType)).getSuperclass();
}
}
}