private Type eraseBound( Type t, Type bound ) { if( bound == null || bound instanceof NoType ) { return bound; } Type erasedBound; if( bound.contains( t ) ) { erasedBound = visit( _types.erasure( bound ) ); } else { erasedBound = visit( bound ); } return erasedBound; }
private SrcType makeNestedType( Type type ) { String fqn = type.toString(); Type enclosingType = type.getEnclosingType(); SrcType srcType; if( enclosingType != null && !(enclosingType instanceof NoType) && fqn.length() > enclosingType.toString().length() ) { String simpleName = fqn.substring( enclosingType.toString().length() + 1 ); srcType = new SrcType( simpleName ); srcType.setEnclosingType( makeNestedType( enclosingType ) ); } else { srcType = new SrcType( fqn ); } return srcType; }
private SrcType makeTypeVarType( Symbol.TypeVariableSymbol typeVar ) { StringBuilder sb = new StringBuilder( typeVar.type.toString() ); Type lowerBound = typeVar.type.getLowerBound(); if( lowerBound != null && !(lowerBound instanceof NullType) ) { sb.append( " super " ).append( lowerBound.toString() ); } else { Type upperBound = typeVar.type.getUpperBound(); if( upperBound != null && !(upperBound instanceof NoType) && !upperBound.toString().equals( Object.class.getName() ) ) { sb.append( " extends " ).append( upperBound.toString() ); } } return new SrcType( sb.toString() ); }
public TypeRef apply(TypeMirror item) { if (item instanceof NoType) { return new VoidRef(); } Element element = CodegenContext.getContext().getTypes().asElement(item); TypeDef known = element != null ? CodegenContext.getContext().getDefinitionRepository().getDefinition(element.toString()) : null; if (known == null && element instanceof TypeElement) { known = TYPEDEF.apply((TypeElement) element); } TypeRef typeRef = item.accept(new TypeRefTypeVisitor(), 0); if (typeRef instanceof ClassRef && known != null) { return new ClassRefBuilder((ClassRef) typeRef).withDefinition(known).build(); } return typeRef; }
/** * Checks if the given {@link Element} is, implements or extends the given target type. * * @param type the element to analyze * @param targetType the type to check * @return <code>true</code> if the given {@link Element} corresponds to a type that implements * {@link List}, <code>false</code> otherwise. */ public static boolean isAssignable(final DeclaredType type, final Class<?> targetType) { if (type instanceof NoType) { return false; } if (type.asElement().toString().equals(targetType.getName())) { return true; } final TypeElement element = (TypeElement) type.asElement(); final boolean implementation = element.getInterfaces().stream() .filter(interfaceMirror -> interfaceMirror.getKind() == TypeKind.DECLARED) .map(interfaceMirror -> (DeclaredType) interfaceMirror) .map(declaredInterface -> declaredInterface.asElement()) .anyMatch(declaredElement -> declaredElement.toString().equals(targetType.getName())); if (implementation) { return true; } if (element.getSuperclass().getKind() == TypeKind.DECLARED) { return isAssignable((DeclaredType)(element.getSuperclass()), targetType); } return false; }
/** * Check if the given Element extends a given type. A fully qualified name of another type * to check for must be given. Throws an IllegalArgumentException if Element is not an instance of * TypeElement. The method will recursively climb up the type hierarchy until it reaches either * the desired type or a root type. * * @param element element to perform the check for * @param superType fully qualified name of a type * @return true if given element represents a type that extends another type with the given fully * qualified name * @throws java.lang.IllegalArgumentException if element is not an instance of TypeElement */ public static boolean checkIfExtends(Element element, String superType) { if (!(element instanceof TypeElement)) { throw new IllegalArgumentException("Can only check if TypeElement extends a certain superType"); } TypeElement typeElement = (TypeElement) element; if (typeElement.getSuperclass() instanceof NoType) { return false; } else if (((DeclaredType) typeElement.getSuperclass()).asElement().toString().equals(superType)) { return true; } else { return checkIfExtends(((DeclaredType) typeElement.getSuperclass()).asElement(), superType); } }
public static boolean instanceOf(Types types, TypeMirror type, String className) { //System.out.println("instanceOf : "+type.toString()+":"+className); String baseType = type.toString(); if (type instanceof DeclaredType) { baseType = ((DeclaredType)type).asElement().toString(); } //System.out.println("BaseType: "+baseType); if (baseType.equals(className)) { return true; } TypeElement elem = (TypeElement) types.asElement(type); for (TypeMirror i : elem.getInterfaces()) { if (instanceOf(types,i,className)) { return true; } } TypeMirror sup = elem.getSuperclass(); if (sup instanceof NoType) { return false; } return (instanceOf(types,sup,className)); }
@Test public void testAsType() throws IOException { compile("class Foo { }"); TypeElement fooElement = elements.getTypeElement("Foo"); TypeMirror fooTypeMirror = fooElement.asType(); assertEquals(TypeKind.DECLARED, fooTypeMirror.getKind()); DeclaredType fooDeclaredType = (DeclaredType) fooTypeMirror; assertSame(fooElement, fooDeclaredType.asElement()); assertEquals(0, fooDeclaredType.getTypeArguments().size()); TypeMirror enclosingType = fooDeclaredType.getEnclosingType(); assertEquals(TypeKind.NONE, enclosingType.getKind()); assertTrue(enclosingType instanceof NoType); }
@Test public void testAsTypeGeneric() throws IOException { compile("class Foo<T> { }"); TypeElement fooElement = elements.getTypeElement("Foo"); TypeMirror fooTypeMirror = fooElement.asType(); assertEquals(TypeKind.DECLARED, fooTypeMirror.getKind()); DeclaredType fooDeclaredType = (DeclaredType) fooTypeMirror; assertSame(fooElement, fooDeclaredType.asElement()); List<? extends TypeMirror> typeArguments = fooDeclaredType.getTypeArguments(); assertEquals("T", ((TypeVariable) typeArguments.get(0)).asElement().getSimpleName().toString()); assertEquals(1, typeArguments.size()); TypeMirror enclosingType = fooDeclaredType.getEnclosingType(); assertEquals(TypeKind.NONE, enclosingType.getKind()); assertTrue(enclosingType instanceof NoType); }
@Test public void testGetDeclaredTypeTopLevelNoGenerics() throws IOException { compile("class Foo { }"); TypeElement fooElement = elements.getTypeElement("Foo"); TypeMirror fooTypeMirror = types.getDeclaredType(fooElement); assertEquals(TypeKind.DECLARED, fooTypeMirror.getKind()); DeclaredType fooDeclaredType = (DeclaredType) fooTypeMirror; assertNotSame(fooElement.asType(), fooDeclaredType); assertSame(fooElement, fooDeclaredType.asElement()); assertEquals(0, fooDeclaredType.getTypeArguments().size()); TypeMirror enclosingType = fooDeclaredType.getEnclosingType(); assertEquals(TypeKind.NONE, enclosingType.getKind()); assertTrue(enclosingType instanceof NoType); }
@Test public void testGetDeclaredTypeTopLevelRawType() throws IOException { compile("class Foo<T> { }"); TypeElement fooElement = elements.getTypeElement("Foo"); TypeMirror fooTypeMirror = types.getDeclaredType(fooElement); assertEquals(TypeKind.DECLARED, fooTypeMirror.getKind()); DeclaredType fooDeclaredType = (DeclaredType) fooTypeMirror; assertNotSame(fooElement.asType(), fooDeclaredType); assertSame(fooElement, fooDeclaredType.asElement()); assertEquals(0, fooDeclaredType.getTypeArguments().size()); TypeMirror enclosingType = fooDeclaredType.getEnclosingType(); assertEquals(TypeKind.NONE, enclosingType.getKind()); assertTrue(enclosingType instanceof NoType); }
private Set<MethodSpec> getMethods(Types typeUtils) { Set<MethodSpec> methods = new HashSet<>(); MethodSpec constructor = MethodSpec.constructorBuilder() .addModifiers(Modifier.PUBLIC) .addParameter(classTypeName, MEMBER_FIELD_NAME) .addStatement("this.$N = $N", MEMBER_FIELD_NAME, MEMBER_FIELD_NAME) .build(); methods.add(constructor); Set<Element> allElements = new HashSet<>(); allElements.addAll(element.getEnclosedElements()); for (TypeMirror typeMirror : element.getInterfaces()) { allElements.addAll(typeUtils.asElement(typeMirror).getEnclosedElements()); } for (Element e : allElements) { if (!(e instanceof ExecutableElement)) { continue; } ExecutableElement method = (ExecutableElement) e; String methodName = method.getSimpleName().toString(); if ("<init>".equals(methodName)) { // skip constructors continue; } Set<Modifier> modifiers = new HashSet<>(method.getModifiers()); if (modifiers.contains(Modifier.PRIVATE) || modifiers.contains(Modifier.STATIC) || modifiers.contains(Modifier.FINAL)) { continue; } modifiers.remove(Modifier.ABSTRACT); modifiers.add(Modifier.SYNCHRONIZED); MethodSpec.Builder spec = MethodSpec.methodBuilder(methodName) .addModifiers(modifiers); List<? extends TypeMirror> thrownTypes = method.getThrownTypes(); for (TypeMirror throwable : thrownTypes) { spec = spec.addException(TypeName.get(throwable)); } String arguments = ""; List<? extends VariableElement> parameters = method.getParameters(); for (VariableElement parameter : parameters) { arguments += parameter.getSimpleName().toString(); if (parameters.indexOf(parameter) != parameters.size() - 1) { arguments += ", "; } spec.addParameter(ParameterSpec.get(parameter)); } if (method.getReturnType() instanceof NoType) { spec = spec.addStatement("$N.$N($L)", MEMBER_FIELD_NAME, methodName, arguments); } else { spec = spec.addStatement("return $N.$N($L)", MEMBER_FIELD_NAME, methodName, arguments) .returns(TypeName.get(method.getReturnType())); } methods.add(spec.build()); } return methods; }
private TypeElement getSuperClassForDataBinding(TypeElement te) { TypeMirror superclass = te.getSuperclass(); String superName = superclass.toString(); if(superclass instanceof NoType){ //no super. }else if(superName.startsWith("java.") || superName.startsWith("android.")){ // no super too. }else{ TypeElement newTe = new FieldData.TypeCompat(mContext.getTypes(), superclass).getElementAsType(); DataBindingInfo info = mInfoMap.get(superName); if(info == null){ //-------------- handle cross modules ------------ //by class annotation if(hasDataBindingClassAnnotation(newTe)){ return newTe; } //by field annotation List<VariableElement> elements = ElementFilter.fieldsIn(newTe.getEnclosedElements()); if(elements.size() > 0){ for(VariableElement ve: elements){ if(hasDataBindingFieldAnnotation(ve)){ return newTe; } } } //may super's N class is using data-binding return getSuperClassForDataBinding(newTe); }else{ //found return newTe; } } return null; }
/** * Returns a {@link NoType} if the {@link TypeMirror} represents an non-type such * as void, or package, etc. or throws an {@link IllegalArgumentException}. */ public static NoType asNoType(TypeMirror maybeNoType) { return maybeNoType.accept(new CastingTypeVisitor<NoType>() { @Override public NoType visitNoType(NoType noType, String p) { return noType; } }, "non-type"); }
private boolean hasPotentialMethod( Symbol.ClassSymbol rootClassSymbol, String name, int paramCount ) { if( rootClassSymbol == null || rootClassSymbol instanceof NoType ) { return false; } for( Symbol member : IDynamicJdk.instance().getMembers( rootClassSymbol, e -> e.flatName().toString().equals( name ) ) ) { Symbol.MethodSymbol methodSym = (Symbol.MethodSymbol)member; if( methodSym.getParameters().size() == paramCount ) { return true; } } if( hasPotentialMethod( (Symbol.ClassSymbol)rootClassSymbol.getSuperclass().tsym, name, paramCount ) ) { return true; } for( Type iface : rootClassSymbol.getInterfaces() ) { if( hasPotentialMethod( (Symbol.ClassSymbol)iface.tsym, name, paramCount ) ) { return true; } } return false; }
@Test void unknownTypeFails() { AssertionError e = expectThrows( AssertionError.class, () -> JavaMirrors.of(Tests.proxy(PrimitiveType.class, (p, m, a) -> TypeKind.ERROR))); assertTrue(e.toString().contains("Unsupported primitive type")); e = expectThrows( AssertionError.class, () -> JavaMirrors.of(Tests.proxy(NoType.class, (p, m, a) -> TypeKind.ERROR))); assertTrue(e.toString().contains("Unsupported no type")); }
@Override public String visitDeclared(DeclaredType type, Void v) { Name typeName = Processors.qualifiedName(type); TypeElement typeElement = (TypeElement) type.asElement(); if (typeName.contentEquals("java.lang.Object")) { return "new " + ClassNames.VAR + "()"; } if (typeName.contentEquals("java.lang.Void")) { return "null"; } List<String> subInstantiations = new ArrayList<>(); for (TypeMirror typeArgument : type.getTypeArguments()) { subInstantiations.add(visit(typeArgument)); } if (typeElement.getModifiers().contains(Modifier.ABSTRACT) || (typeElement.getSuperclass() instanceof NoType)) { // typeElement is abstract or an interface return typeName + ".of(" + Processors.join(", ", subInstantiations) + ")"; } if (subInstantiations.isEmpty()) { return "new " + typeName + "()"; } return "new " + typeName + "<>(" + Processors.join(", ", subInstantiations) + ")"; }
public NoType getNoType(TypeKind kind) { switch (kind) { case NONE: return NoTypeImpl.NO_TYPE_NONE; case VOID: return NoTypeImpl.NO_TYPE_VOID; case PACKAGE: return NoTypeImpl.NO_TYPE_PACKAGE; default: throw new IllegalArgumentException(); } }
/** * Checks if this AnnotatedAdapter has another AnnotatedAdapter as super class. Therfore the * binder interface must extends from this one. */ public AdapterInfo getAnnotatedAdapterSuperClass(Map<String, AdapterInfo> adaptersMap) { if (searchedForSuperAnnotatedAdapterClass) { return superAnnotatedAdapterClass; } searchedForSuperAnnotatedAdapterClass = true; // Search from bottom up along inheritance three for the fist Annotated adapter class we find TypeElement currentClass = adapterClass; while (currentClass != null) { TypeMirror currentMirror = currentClass.getSuperclass(); if (currentMirror instanceof NoType || currentMirror.getKind() == TypeKind.NONE) { // java.lang.Object has been found, there is no other super class return null; } AdapterInfo superAdapter = adaptersMap.get(currentMirror.toString()); if (superAdapter != null) { // "Cache" the found super class for performance reasons superAnnotatedAdapterClass = superAdapter; return superAnnotatedAdapterClass; } // Continue with the super class currentClass = elementUtils.getTypeElement(currentMirror.toString()); } return null; }
@Override public NoType getNoType(TypeKind kind) { Objects.requireNonNull(kind); if (kind == TypeKind.VOID) { return NoTypeImpl.VOID; } else if (kind == TypeKind.NONE) { return NoTypeImpl.NONE; } else { throw new IllegalArgumentException(String.format("Expected one of %s, but got %s.", Arrays.asList(TypeKind.VOID, TypeKind.NONE), kind)); } }
@Test public void testToString() { // PrimitiveType for (TypeKind primitive: Arrays.asList(TypeKind.DOUBLE, TypeKind.FLOAT, TypeKind.LONG, TypeKind.INT, TypeKind.SHORT, TypeKind.BYTE, TypeKind.CHAR, TypeKind.BOOLEAN)) { PrimitiveType primitiveType = types.getPrimitiveType(primitive); Assert.assertEquals(types.getPrimitiveType(primitive).toString(), types.toString(primitiveType)); } // DeclaredType DeclaredType declaredType = (DeclaredType) types.typeMirror(Integer.class); Assert.assertEquals(declaredType.toString(), types.toString(declaredType)); // IntersectionType IntersectionType intersectionType = types.getIntersectionType(types.typeMirror(Serializable.class), types.typeMirror(Cloneable.class)); Assert.assertEquals(intersectionType.toString(), types.toString(intersectionType)); // WildcardType WildcardType wildcardType = types.getWildcardType(types.typeMirror(Integer.class), null); Assert.assertEquals(wildcardType.toString(), types.toString(wildcardType)); // NullType NullType nullType = types.getNullType(); Assert.assertEquals(nullType.toString(), types.toString(nullType)); // NoType NoType noType = types.getNoType(TypeKind.VOID); Assert.assertEquals(noType.toString(), types.toString(noType)); // TypeVariable TypeVariable typeVariable = (TypeVariable) types.typeElement(List.class).getTypeParameters().get(0).asType(); Assert.assertEquals(typeVariable.toString(), types.toString(typeVariable)); }
@Override public Void visitNoType(NoType t, StringBuilderAndState<TypeMirror> state) { switch (t.getKind()) { case VOID: state.bld.append("void"); break; case PACKAGE: state.bld.append("package"); break; default: break; } return null; }
@Override public AnnotatedNoType getCopy(boolean copyAnnotations) { AnnotatedNoType type = new AnnotatedNoType((NoType) actualType, atypeFactory); if (copyAnnotations) type.addAnnotations(annotations); return type; }
@Override public Void visitNoType(NoType t, Void p) { if ( t.getKind() == TypeKind.VOID ) { buf.append('V'); return null; } else { return defaultAction(t, p); } }
@Override public <R, P> R accept(TypeVisitor<R, P> v, P p) { switch (kind) { case BOOLEAN: case BYTE: case SHORT: case INT: case LONG: case CHAR: case FLOAT: case DOUBLE: return v.visitPrimitive((PrimitiveType) this, p); case PACKAGE: case VOID: case NONE: return v.visitNoType((NoType) this, p); case NULL: return v.visitNull((NullType) this, p); case ARRAY: return v.visitArray((ArrayType) this, p); case DECLARED: return v.visitDeclared((DeclaredType) this, p); case ERROR: return v.visitError((ErrorType) this, p); case TYPEVAR: return v.visitTypeVariable((TypeVariable) this, p); case WILDCARD: return v.visitWildcard((WildcardType) this, p); case EXECUTABLE: return v.visitExecutable((ExecutableType) this, p); case OTHER: return v.visit(this, p); case UNION: return v.visitUnion((UnionType) this, p); case INTERSECTION: return v.visitIntersection((IntersectionType) this, p); default: throw new AssertionError(String.format("Unknown TypeKind: %s", kind)); } }
@Override public Void visitNoType(NoType t, SignatureVisitor visitor) { if (t.getKind() == TypeKind.VOID) { visitor.visitBaseType(descriptorFactory.getDescriptor(t).charAt(0)); return null; } return defaultAction(t, visitor); }
private static TypeMirror noType() { return new NoType() { @Override public <R, P> R accept(TypeVisitor<R, P> v, P p) { throw new UnsupportedOperationException(); } @Override public TypeKind getKind() { throw new UnsupportedOperationException(); } }; }
@Override public Type visitNoType(NoType t, Type.Parameters p) { return Type.Primitive.VOID; }
public Boolean visitNoType(NoType arg0, Void arg1) { return false; }
@Override public Boolean visitNoType(NoType t, Boolean p) { return false; }
@Override public Boolean visitNoType(NoType t, Void o) { return true; }
@Override public TypeMirror visitNoType(NoType type, Types types) { return type; }
private static boolean hasCallMethod( BasicJavacTask javacTask, Symbol.ClassSymbol classSymbol ) { Name call = Names.instance( javacTask.getContext() ).fromString( "call" ); Iterable<Symbol> elems = IDynamicJdk.instance().getMembersByName( classSymbol, call ); for( Symbol s : elems ) { if( s instanceof Symbol.MethodSymbol ) { List<Symbol.VarSymbol> parameters = ((Symbol.MethodSymbol)s).getParameters(); if( parameters.size() != 6 ) { return false; } Symtab symbols = Symtab.instance( javacTask.getContext() ); Types types = Types.instance( javacTask.getContext() ); return types.erasure( parameters.get( 0 ).asType() ).equals( types.erasure( symbols.classType ) ) && parameters.get( 1 ).asType().equals( symbols.stringType ) && parameters.get( 2 ).asType().equals( symbols.stringType ) && types.erasure( parameters.get( 3 ).asType() ).equals( types.erasure( symbols.classType ) ) && parameters.get( 4 ).asType() instanceof Type.ArrayType && types.erasure( ((Type.ArrayType)parameters.get( 4 ).asType()).getComponentType() ).equals( types.erasure( symbols.classType ) ) && parameters.get( 5 ).asType() instanceof Type.ArrayType && ((Type.ArrayType)parameters.get( 5 ).asType()).getComponentType().equals( symbols.objectType ); } } Type superclass = classSymbol.getSuperclass(); if( !(superclass instanceof NoType) ) { if( hasCallMethod( javacTask, (Symbol.ClassSymbol)superclass.tsym ) ) { return true; } } for( Type iface : classSymbol.getInterfaces() ) { if( hasCallMethod( javacTask, (Symbol.ClassSymbol)iface.tsym ) ) { return true; } } return false; }