public TypeParams(TypeMirror type) { typeName = type.toString(); if (typeName.contains("<")) { typeName = typeName.substring(0, typeName.indexOf("<")); } if (type instanceof DeclaredType) { DeclaredType declaredType = (DeclaredType) type; if (!declaredType.getTypeArguments().isEmpty()) { for (TypeMirror genericMirrorType : declaredType.getTypeArguments()) { genericTypes.add(new TypeParams(genericMirrorType)); } } } }
@Override public void writeFieldReadStatement( VariableElement field, Collection<ExecutableElement> postCreateChildMethods, JavaWriter writer) throws IOException { DeclaredType type = (DeclaredType) field.asType(); TypeMirror itemType = type.getTypeArguments().get(0); TypeMirror itemTypeErasure = processingEnv.getTypeUtils().erasure(itemType); String collectionInitializer; try { collectionInitializer = initializers.findCollectionInitializer(type); } catch (InvalidTypeException e) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), field); collectionInitializer = "null"; } writer.beginControlFlow("if (bundle.containsKey(\"%s\"))", field.getSimpleName()); writer.emitStatement("object.%s = %s", field.getSimpleName(), collectionInitializer); writer.emitStatement( "%1$s.readCollectionFromBundle(object.%2$s, bundle, %3$s.class, \"%2$s\")", CollectionBundler.class.getCanonicalName(), field.getSimpleName(), itemTypeErasure); writePostCreateChildMethodCalls(field, itemType, postCreateChildMethods, writer); writer.endControlFlow(); }
/** * Finds the map type for the specified type mirror, if it exists. * * @param typeMirror The type mirror. * @param context The context * @return The map type or null. */ public static MapType findMapType(TypeMirror typeMirror, EnunciateJacksonContext context) { if (!(typeMirror instanceof DeclaredType)) { return null; } DeclaredType declaredType = (DeclaredType) typeMirror; TypeElement element = (TypeElement) declaredType.asElement(); if (element == null) { return null; } else { String fqn = element.getQualifiedName().toString(); @SuppressWarnings("unchecked") Map<String, MapType> mapTypes = (Map<String, MapType>) context.getContext().getProperty(PROPERTY_MAP_TYPES); if (mapTypes == null) { mapTypes = new HashMap<String, MapType>(); context.getContext().setProperty(PROPERTY_MAP_TYPES, mapTypes); } MapType mapType = mapTypes.get(fqn); if (mapType != null) { return mapType; } else { DeclaredType declaredMapType = findMapTypeDeclaration(declaredType, context); if (declaredMapType == null) { return null; } MapType newMapType = new MapType(declaredType, context.getContext().getProcessingEnvironment()); mapTypes.put(fqn, newMapType); TypeMirror keyType = null; TypeMirror valueType = null; List<? extends TypeMirror> typeArgs = declaredMapType.getTypeArguments(); if ((typeArgs != null) && (typeArgs.size() == 2)) { Iterator<? extends TypeMirror> argIt = typeArgs.iterator(); keyType = argIt.next(); valueType = argIt.next(); } if ((keyType == null) || (valueType == null)) { TypeMirror objectType = TypeMirrorUtils.objectType(context.getContext().getProcessingEnvironment()); keyType = objectType; valueType = objectType; } TypeMirror mapKeyType = findMapType(keyType, context); newMapType.keyType = mapKeyType == null ? keyType : mapKeyType; TypeMirror mapValueType = findMapType(valueType, context); newMapType.valueType = mapValueType == null ? valueType : mapValueType; return newMapType; } } }
private List<Type> getTypeParameters(TypeMirror mirror, boolean isImplementationType) { if (mirror.getKind() != TypeKind.DECLARED) { return java.util.Collections.emptyList(); } DeclaredType declaredType = (DeclaredType) mirror; List<Type> typeParameters = new ArrayList<Type>(declaredType.getTypeArguments().size()); for (TypeMirror typeParameter : declaredType.getTypeArguments()) { if (isImplementationType) { typeParameters.add(getType(typeParameter).getTypeBound()); } else { typeParameters.add(getType(typeParameter)); } } return typeParameters; }
@Override public TypeElement visitDeclared(DeclaredType t, Void p) { if (t.asElement() instanceof TypeElement) { TypeElement typeElement = (TypeElement) t.asElement(); switch (typeElement.getKind()) { case ENUM: return skipEnum ? null : typeElement; case CLASS: return typeElement; case INTERFACE: return visit(t.getTypeArguments().get(t.getTypeArguments().size() - 1)); default: throw new IllegalArgumentException("Illegal type " + typeElement); } } else { return null; } }
@Override public JsonType visitDeclared(DeclaredType declaredType, Void o) { if (isJsonPrimitive(declaredType)) { // 'primitive'-ish things return new JsonPrimitive(declaredType.toString()); } else if (isInstanceOf(declaredType, Collection.class)) { if (declaredType.getTypeArguments().size() == 0) { return new JsonArray(new JsonPrimitive(Object.class.getName())); } else { TypeMirror elem = declaredType.getTypeArguments().get(0); return new JsonArray(elem.accept(this, o)); } } else if (isInstanceOf(declaredType, Map.class)) { if (declaredType.getTypeArguments().size() == 0) { return new JsonDict( new JsonPrimitive(Object.class.getName()), new JsonPrimitive(Object.class.getName())); } else { TypeMirror key = declaredType.getTypeArguments().get(0); TypeMirror val = declaredType.getTypeArguments().get(1); return new JsonDict(key.accept(this, o), val.accept(this, o)); } } else { TypeElement element = (TypeElement) declaredType.asElement(); if (element.getKind() == ElementKind.ENUM) { List<String> enumConstants = new ArrayList(); for (Element e : element.getEnclosedElements()) { if (e.getKind() == ElementKind.ENUM_CONSTANT) { enumConstants.add(e.toString()); } } JsonPrimitive primitive = new JsonPrimitive(String.class.getName()); // TODO is this always a string? primitive.setRestrictions(enumConstants); return primitive; } else { return buildType(declaredType, element); } } }
private String getArrayListType(DeclaredType type) throws InvalidTypeException { TypeMirror arg = type.getTypeArguments().get(0); if (types.isAssignable(arg, integerType)) { return "IntegerArrayList"; } try { return getAggregateType(arg).concat("ArrayList"); } catch (InvalidTypeException e) { throw new InvalidTypeException(type); } }
@Override public void writeFieldWriteStatement(VariableElement field, JavaWriter writer) throws IOException { DeclaredType type = (DeclaredType) field.asType(); TypeMirror itemType = type.getTypeArguments().get(0); TypeMirror itemTypeErasure = processingEnv.getTypeUtils().erasure(itemType); writer.beginControlFlow("if (object.%s != null)", field.getSimpleName()); writer.emitStatement( "%1$s.writeCollectionToBundle(object.%2$s, bundle, %3$s.class, \"%2$s\")", CollectionBundler.class.getCanonicalName(), field.getSimpleName(), itemTypeErasure); writer.endControlFlow(); }
private JsonType newJsonType(TypeMirror typeMirror) { if (isJsonPrimitive(typeMirror)) { return new JsonPrimitive(typeMirror.toString()); } else if (typeMirror.getKind() == TypeKind.DECLARED) { // some sort of object... walk it DeclaredType type = (DeclaredType) typeMirror; return newJsonType(type, type.getTypeArguments(), new HashSet<DeclaredType>()); } else if (typeMirror.getKind() == TypeKind.VOID) { return null; } else if (typeMirror.getKind() == TypeKind.ARRAY) { return newJsonType(((ArrayType) typeMirror).getComponentType()); } else { throw new UnsupportedOperationException(typeMirror.toString()); } }
@Override public String visitDeclared(DeclaredType mirror, Void p) { Name name = mirror.asElement().getSimpleName(); final String prefix; Element enclosingElement = mirror.asElement().getEnclosingElement(); if (mirror.getEnclosingType().getKind() != TypeKind.NONE) { prefix = visit(mirror.getEnclosingType()) + "."; } else if (enclosingElement.getKind() == ElementKind.PACKAGE) { PackageElement pkg = (PackageElement) enclosingElement; prefix = getPrefixForTopLevelClass(pkg.getQualifiedName().toString(), name); } else if (enclosingElement.getKind().isClass() || enclosingElement.getKind().isInterface()) { prefix = shorten((TypeElement) enclosingElement) + "."; } else { prefix = enclosingElement.toString() + "."; } final String suffix; if (!mirror.getTypeArguments().isEmpty()) { List<String> shortTypeArguments = Lists.transform(mirror.getTypeArguments(), this); suffix = "<" + Joiner.on(", ").join(shortTypeArguments) + ">"; } else { suffix = ""; } return prefix + name + suffix; }
private void appendTypeArguments(TypeMirror type, DeclaredType declaredType) { List<? extends TypeMirror> arguments = declaredType.getTypeArguments(); if (!arguments.isEmpty()) { buffer.append('<'); boolean notFirst = false; for (TypeMirror argument : arguments) { if (notFirst) { buffer.append(',').append(' '); } notFirst = true; int mark = buffer.length(); caseType(argument); cutTypeArgument(type, mark); } buffer.append('>'); } }
private boolean isSubtypeOfType(TypeMirror typeMirror, String otherType) { if (otherType.equals(typeMirror.toString())) { return true; } if (typeMirror.getKind() != TypeKind.DECLARED) { return false; } DeclaredType declaredType = (DeclaredType) typeMirror; List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments(); if (typeArguments.size() > 0) { StringBuilder typeString = new StringBuilder(declaredType.asElement().toString()); typeString.append('<'); for (int i = 0; i < typeArguments.size(); i++) { if (i > 0) { typeString.append(','); } typeString.append('?'); } typeString.append('>'); if (typeString.toString().equals(otherType)) { return true; } } Element element = declaredType.asElement(); if (!(element instanceof TypeElement)) { return false; } TypeElement typeElement = (TypeElement) element; TypeMirror superType = typeElement.getSuperclass(); if (isSubtypeOfType(superType, otherType)) { return true; } for (TypeMirror interfaceType : typeElement.getInterfaces()) { if (isSubtypeOfType(interfaceType, otherType)) { return true; } } return false; }
@Override public Optional<CodeGenerator> create(Config config) { // No @Nullable properties if (!config.getProperty().getNullableAnnotations().isEmpty()) { return Optional.absent(); } if (config.getProperty().getType().getKind() == TypeKind.DECLARED) { DeclaredType type = (DeclaredType) config.getProperty().getType(); if (erasesToAnyOf(type, Set.class, ImmutableSet.class)) { TypeMirror elementType = upperBound(config.getElements(), type.getTypeArguments().get(0)); Optional<TypeMirror> unboxedType; try { unboxedType = Optional.<TypeMirror>of(config.getTypes().unboxedType(elementType)); } catch (IllegalArgumentException e) { unboxedType = Optional.absent(); } return Optional.of(new CodeGenerator(config.getProperty(), elementType, unboxedType)); } } return Optional.absent(); }
private Type getImplementationType(TypeMirror mirror) { if (mirror.getKind() != TypeKind.DECLARED) { return null; } DeclaredType declaredType = (DeclaredType) mirror; Type implementationType = implementationTypes.get( ((TypeElement) declaredType.asElement()).getQualifiedName().toString()); if (implementationType != null) { return new Type( typeUtils, elementUtils, this, typeUtils.getDeclaredType( implementationType.getTypeElement(), declaredType.getTypeArguments().toArray(new TypeMirror[] {})), implementationType.getTypeElement(), getTypeParameters(mirror, true), null, null, implementationType.getPackageName(), implementationType.getName(), implementationType.getFullyQualifiedName(), implementationType.isInterface(), implementationType.isEnumType(), implementationType.isIterableType(), implementationType.isCollectionType(), implementationType.isMapType(), isImported(implementationType.getName(), implementationType.getFullyQualifiedName())); } return null; }
@Override public Collection<TypeMirror> getActualTypeArguments() { Debug.implemented("Collection<TypeMirror>"); return convert(internalDeclaredType.getTypeArguments(), TypeMirror.class); }
private void parseBindMany( Element element, Map<TypeElement, BindingClass> targetClassMap, Set<String> erasedTargetNames) { boolean hasError = false; TypeElement enclosingElement = (TypeElement) element.getEnclosingElement(); // Verify that the type is a List or an array. TypeMirror elementType = element.asType(); String erasedType = doubleErasure(elementType); TypeMirror viewType = null; FieldCollectionViewBinding.Kind kind = null; if (elementType.getKind() == TypeKind.ARRAY) { ArrayType arrayType = (ArrayType) elementType; viewType = arrayType.getComponentType(); kind = FieldCollectionViewBinding.Kind.ARRAY; } else if (LIST_TYPE.equals(erasedType)) { DeclaredType declaredType = (DeclaredType) elementType; List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments(); if (typeArguments.size() != 1) { error( element, "@%s List must have a generic component. (%s.%s)", Bind.class.getSimpleName(), enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } else { viewType = typeArguments.get(0); } kind = FieldCollectionViewBinding.Kind.LIST; } else { throw new AssertionError(); } if (viewType != null && viewType.getKind() == TypeKind.TYPEVAR) { TypeVariable typeVariable = (TypeVariable) viewType; viewType = typeVariable.getUpperBound(); } // Verify that the target type extends from View. if (viewType != null && !isSubtypeOfType(viewType, VIEW_TYPE) && !isInterface(viewType)) { error( element, "@%s List or array type must extend from View or be an interface. (%s.%s)", Bind.class.getSimpleName(), enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } if (hasError) { return; } // Assemble information on the field. String name = element.getSimpleName().toString(); int[] ids = element.getAnnotation(Bind.class).value(); if (ids.length == 0) { error( element, "@%s must specify at least one ID. (%s.%s)", Bind.class.getSimpleName(), enclosingElement.getQualifiedName(), element.getSimpleName()); return; } Integer duplicateId = findDuplicate(ids); if (duplicateId != null) { error( element, "@%s annotation contains duplicate ID %d. (%s.%s)", Bind.class.getSimpleName(), duplicateId, enclosingElement.getQualifiedName(), element.getSimpleName()); } assert viewType != null; // Always false as hasError would have been true. String type = viewType.toString(); boolean required = isRequiredBinding(element); BindingClass bindingClass = getOrCreateTargetClass(targetClassMap, enclosingElement); FieldCollectionViewBinding binding = new FieldCollectionViewBinding(name, type, kind, required); bindingClass.addFieldCollection(ids, binding); erasedTargetNames.add(enclosingElement.toString()); }
private void parseInjectViews( Element element, Map<TypeElement, ViewInjector> targetClassMap, Set<String> erasedTargetNames) { boolean hasError = false; TypeElement enclosingElement = (TypeElement) element.getEnclosingElement(); // Verify that the type is a List or an array. TypeMirror elementType = element.asType(); String erasedType = doubleErasure(elementType); TypeMirror viewType = null; CollectionBinding.Kind kind = null; if (elementType.getKind() == TypeKind.ARRAY) { ArrayType arrayType = (ArrayType) elementType; viewType = arrayType.getComponentType(); kind = CollectionBinding.Kind.ARRAY; } else if (LIST_TYPE.equals(erasedType)) { DeclaredType declaredType = (DeclaredType) elementType; List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments(); if (typeArguments.size() != 1) { error( element, "@InjectViews List must have a generic component. (%s.%s)", enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } else { viewType = typeArguments.get(0); } kind = CollectionBinding.Kind.LIST; } else { error( element, "@InjectViews must be a List or array. (%s.%s)", enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } if (viewType instanceof TypeVariable) { TypeVariable typeVariable = (TypeVariable) viewType; viewType = typeVariable.getUpperBound(); } // Verify that the target type extends from View. if (viewType != null && !isSubtypeOfType(viewType, VIEW_TYPE) && !isInterface(viewType)) { error( element, "@InjectViews type must extend from View or be an interface. (%s.%s)", enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } // Verify common generated code restrictions. hasError |= isInaccessibleViaGeneratedCode(InjectViews.class, "fields", element); hasError |= isBindingInWrongPackage(InjectViews.class, element); if (hasError) { return; } // Assemble information on the injection point. String name = element.getSimpleName().toString(); int[] ids = element.getAnnotation(InjectViews.class).value(); if (ids.length == 0) { error( element, "@InjectViews must specify at least one ID. (%s.%s)", enclosingElement.getQualifiedName(), element.getSimpleName()); return; } Integer duplicateId = findDuplicate(ids); if (duplicateId != null) { error( element, "@InjectViews annotation contains duplicate ID %d. (%s.%s)", duplicateId, enclosingElement.getQualifiedName(), element.getSimpleName()); } assert viewType != null; // Always false as hasError would have been true. String type = viewType.toString(); boolean required = element.getAnnotation(Optional.class) == null; ViewInjector viewInjector = getOrCreateTargetClass(targetClassMap, enclosingElement); CollectionBinding binding = new CollectionBinding(name, type, kind, required); viewInjector.addCollection(ids, binding); erasedTargetNames.add(enclosingElement.toString()); }
private boolean needToCastSparseParcelableArray(DeclaredType type) { List<? extends TypeMirror> typeArguments = type.getTypeArguments(); return !types.isAssignable(typeArguments.get(0), parcelableType); }
@Override public JsonElement visitList(DeclaredType t, Element el) { JsonElement jsonElement; String converterClassName = getConverterClassName(el); if (converterClassName != null) { jsonElement = genJsonElement(t, el, Kind.CONVERTER); } else { List<? extends TypeMirror> generics = t.getTypeArguments(); if (generics.size() != 1) { Log.e("expected single type generics.", el); encountError = true; return defaultAction(t, el); } TypeMirror tm = generics.get(0); if (tm instanceof WildcardType) { WildcardType wt = (WildcardType) tm; TypeMirror extendsBound = wt.getExtendsBound(); if (extendsBound != null) { tm = extendsBound; } TypeMirror superBound = wt.getSuperBound(); if (superBound != null) { Log.e("super is not supported.", el); encountError = true; return defaultAction(t, el); } } Element type = processingEnv.getTypeUtils().asElement(tm); JsonModel hash = type.getAnnotation(JsonModel.class); if (hash == null) { Log.e("expect for use decorated class by JsonModel annotation.", el); encountError = true; return defaultAction(t, el); } jsonElement = new JsonElement(); jsonElement.setKey(getElementKeyString(el)); JsonKey key = el.getAnnotation(JsonKey.class); String setter = getElementSetter(el); if (key.in() && setter == null) { Log.e("can't find setter method", el); encountError = true; return defaultAction(t, el); } String getter = getElementGetter(el); if (key.out() && getter == null) { Log.e("can't find getter method", el); encountError = true; return defaultAction(t, el); } jsonElement.setIn(key.in()); jsonElement.setSetter(setter); jsonElement.setOut(key.out()); jsonElement.setGetter(getter); jsonElement.setModelName(tm.toString()); jsonElement.setKind(Kind.LIST); } return jsonElement; }
@Override public List<? extends TypeMirror> getTypeArguments() { return declaredType.getTypeArguments(); }
void addMethod(ModuleMetaModel context, AnnotationKey key2, AnnotationState annotation) { // String id = (String) annotation.get("id"); ExecutableElement methodElt = (ExecutableElement) context.processingContext.get(key2.getElement()); // for (Phase phase : Phase.values()) { if (phase.annotation.getName().equals(key2.getType().toString())) { ElementHandle.Method origin = (ElementHandle.Method) key2.getElement(); // First remove the previous method Key<MethodMetaModel> key = Key.of(origin, MethodMetaModel.class); if (getChild(key) == null) { // Parameters ArrayList<ParameterMetaModel> parameters = new ArrayList<ParameterMetaModel>(); List<? extends TypeMirror> parameterTypeMirrors = ((ExecutableType) methodElt.asType()).getParameterTypes(); List<? extends VariableElement> parameterVariableElements = methodElt.getParameters(); for (int i = 0; i < parameterTypeMirrors.size(); i++) { VariableElement parameterVariableElt = parameterVariableElements.get(i); TypeMirror parameterTypeMirror = parameterTypeMirrors.get(i); String typeLiteral = context.processingContext.getLiteralName(parameterTypeMirror); // String parameterName = parameterVariableElt.getSimpleName().toString(); // Determine cardinality TypeMirror parameterSimpleTypeMirror; Cardinality parameterCardinality; switch (parameterTypeMirror.getKind()) { case DECLARED: DeclaredType dt = (DeclaredType) parameterTypeMirror; TypeElement col = context.processingContext.getTypeElement("java.util.List"); TypeMirror tm = context.processingContext.erasure(col.asType()); TypeMirror err = context.processingContext.erasure(dt); // context.env.isSubtype(err, tm) if (err.equals(tm)) { if (dt.getTypeArguments().size() != 1) { throw CONTROLLER_METHOD_PARAMETER_NOT_RESOLVED.failure(parameterVariableElt); } else { parameterCardinality = Cardinality.LIST; parameterSimpleTypeMirror = dt.getTypeArguments().get(0); } } else { parameterCardinality = Cardinality.SINGLE; parameterSimpleTypeMirror = parameterTypeMirror; } break; case ARRAY: // Unwrap array ArrayType arrayType = (ArrayType) parameterTypeMirror; parameterCardinality = Cardinality.ARRAY; parameterSimpleTypeMirror = arrayType.getComponentType(); break; default: throw CONTROLLER_METHOD_PARAMETER_NOT_RESOLVED.failure(parameterVariableElt); } if (parameterSimpleTypeMirror.getKind() != TypeKind.DECLARED) { throw CONTROLLER_METHOD_PARAMETER_NOT_RESOLVED.failure(parameterVariableElt); } // TypeElement te = (TypeElement) context.processingContext.asElement(parameterSimpleTypeMirror); ElementHandle.Type a = ElementHandle.Type.create(te); // if (te.toString().equals("java.lang.String") || te.getAnnotation(Mapped.class) != null) { // Not sure we should use @Param for this (i.e for now it looks hackish) // however it does make sense later to use the regex part for non router // parameters Param param = parameterVariableElt.getAnnotation(Param.class); String alias = param != null && param.name().length() > 0 ? param.name() : null; parameters.add( new PhaseParameterMetaModel( parameterName, parameterCardinality, a, typeLiteral, alias)); } else { parameters.add(new ContextualParameterMetaModel(parameterName, typeLiteral)); } } // MethodMetaModel method = new MethodMetaModel( origin, id, phase, methodElt.getSimpleName().toString(), parameters); addChild(key, method); modified = true; } break; } } }