private TypeMirror createStringTypeMirror() { TypeElement element = typeElement; while (element.getSuperclass().getKind() != TypeKind.NONE) { logger.finest("finding toString in " + element); element = (TypeElement) ((DeclaredType) element.getSuperclass()).asElement(); } for (Element enclosed : typeElement.getEnclosedElements()) { if (enclosed.getKind() == ElementKind.METHOD) { ExecutableElement method = (ExecutableElement) enclosed; if (method.getSimpleName().contentEquals("toString")) { return method.getReturnType(); } } } throw new IllegalStateException("Cannot find toString method in Object"); } private static boolean find(String interfaceName, TypeElement typeElement) {
private boolean hasActivityOptions(TypeElement type, int optionsParamPosition) { if (type == null) { return false; } for (ExecutableElement element : ElementFilter.methodsIn(elementUtils.getAllMembers(type))) { if (element.getSimpleName().contentEquals("startActivity")) { List<? extends VariableElement> parameters = element.getParameters(); if (parameters.size() == optionsParamPosition + 1) { VariableElement parameter = parameters.get(optionsParamPosition); if (parameter.asType().toString().equals(CanonicalNameConstants.BUNDLE)) { return true; } } } } return false; }
private TypeElement visitInterface(DeclaredType t) { if (t.getTypeArguments().isEmpty()) { return (TypeElement) t.asElement(); } else { int count = t.getTypeArguments().size(); if (t.asElement().toString().startsWith("java.util")) { return t.getTypeArguments().get(count - 1).accept(this, null); } else { return (TypeElement) t.asElement(); } } }
public void returnTypeIsVoidOrBoolean(ExecutableElement executableElement, ElementValidation valid) { TypeMirror returnType = executableElement.getReturnType(); TypeKind returnKind = returnType.getKind(); if (returnKind != TypeKind.BOOLEAN && returnKind != TypeKind.VOID && !returnType.toString().equals(CanonicalNameConstants.BOOLEAN)) { valid.addError("%s can only be used on a method with a boolean or a void return type"); } }
private void parseResourceInt(Element element, Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) { boolean hasError = false; TypeElement enclosingElement = (TypeElement) element.getEnclosingElement(); // Verify that the target type is int. if (element.asType().getKind() != TypeKind.INT) { error(element, "@%s field type must be 'int'. (%s.%s)", BindInt.class.getSimpleName(), enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } // Verify common generated code restrictions. hasError |= isInaccessibleViaGeneratedCode(BindInt.class, "fields", element); hasError |= isBindingInWrongPackage(BindInt.class, element); if (hasError) { return; } // Assemble information on the field. String name = element.getSimpleName().toString(); int id = element.getAnnotation(BindInt.class).value(); Id resourceId = elementToId(element, BindInt.class, id); BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement); builder.addResource( new FieldResourceBinding(resourceId, name, FieldResourceBinding.Type.INT)); erasedTargetNames.add(enclosingElement); }
/** * Check if the given class or any of its super classes have a super method with the given name. * Private methods are ignored since the generated subclass can't call super on those. */ protected boolean hasSuperMethod(TypeElement classElement, Element attribute) { if (!Utils.isEpoxyModel(classElement.asType())) { return false; } for (Element subElement : classElement.getEnclosedElements()) { if (subElement.getKind() == ElementKind.METHOD) { ExecutableElement method = (ExecutableElement) subElement; if (!method.getModifiers().contains(Modifier.PRIVATE) && method.getSimpleName().toString().equals(attribute.getSimpleName().toString()) && method.getParameters().size() == 1 && method.getParameters().get(0).asType().equals(attribute.asType())) { return true; } } } Element superClass = typeUtils.asElement(classElement.getSuperclass()); return (superClass instanceof TypeElement) && hasSuperMethod((TypeElement) superClass, attribute); }
/** * Get information about methods returning class type of the original class so we can duplicate * them in the generated class for chaining purposes */ protected void collectMethodsReturningClassType(TypeElement modelClass, Types typeUtils) { TypeElement clazz = modelClass; while (clazz.getSuperclass().getKind() != TypeKind.NONE) { for (Element subElement : clazz.getEnclosedElements()) { Set<Modifier> modifiers = subElement.getModifiers(); if (subElement.getKind() == ElementKind.METHOD && !modifiers.contains(Modifier.PRIVATE) && !modifiers.contains(Modifier.FINAL) && !modifiers.contains(Modifier.STATIC)) { TypeMirror methodReturnType = ((ExecutableType) subElement.asType()).getReturnType(); if (methodReturnType.equals(clazz.asType()) || typeUtils.isSubtype(clazz.asType(), methodReturnType)) { ExecutableElement castedSubElement = ((ExecutableElement) subElement); List<? extends VariableElement> params = castedSubElement.getParameters(); String methodName = subElement.getSimpleName().toString(); if (methodName.equals(RESET_METHOD) && params.isEmpty()) { continue; } methodsReturningClassType.add(new MethodInfo(methodName, modifiers, buildParamSpecs(params), castedSubElement.isVarArgs())); } } } clazz = (TypeElement) typeUtils.asElement(clazz.getSuperclass()); } }
private void parseResourceDrawable(Element element, Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) { boolean hasError = false; TypeElement enclosingElement = (TypeElement) element.getEnclosingElement(); // Verify that the target type is Drawable. if (!DRAWABLE_TYPE.equals(element.asType().toString())) { error(element, "@%s field type must be 'Drawable'. (%s.%s)", BindDrawable.class.getSimpleName(), enclosingElement.getQualifiedName(), element.getSimpleName()); hasError = true; } // Verify common generated code restrictions. hasError |= isInaccessibleViaGeneratedCode(BindDrawable.class, "fields", element); hasError |= isBindingInWrongPackage(BindDrawable.class, element); if (hasError) { return; } // Assemble information on the field. String name = element.getSimpleName().toString(); int id = element.getAnnotation(BindDrawable.class).value(); int tint = element.getAnnotation(BindDrawable.class).tint(); Map<Integer, Id> resourceIds = elementToIds(element, BindDrawable.class, new int[] {id, tint}); BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement); builder.addResource(new FieldDrawableBinding(resourceIds.get(id), name, resourceIds.get(tint))); erasedTargetNames.add(enclosingElement); }
Element possibleCopyMethod, boolean onValueType) { if (possibleCopyMethod.getKind() == ElementKind.METHOD) { if (!valueAttribute.containingType.names().possibleAttributeBuilder(possibleCopyMethod.getSimpleName())) { return false; .getTypeUtils(); if (candidateCopyMethod.getParameters().size() == 1 && typeUtils.isSameType( candidateCopyMethod.getParameters().get(0).asType(), valueAttribute.containedTypeElement.asType())) { TypeKind kind = candidateCopyMethod.getReturnType().getKind(); return !kind.isPrimitive() && kind != TypeKind.ARRAY; && !candidateCopyMethod.getModifiers().contains(Modifier.STATIC)) { TypeKind kind = candidateCopyMethod.getReturnType().getKind(); return !kind.isPrimitive() && kind != TypeKind.ARRAY; } else if (!onValueType && possibleCopyMethod.getKind() == ElementKind.CONSTRUCTOR) { return candidateConstructor.getParameters().size() == 1 && candidateConstructor.getParameters().get(0).asType().equals(valueAttribute.containedTypeElement.asType());
TypeElement drawableType = elements.getTypeElement(ClassNames.DRAWABLE_NAME); for (Element enclosedElement : element.getEnclosedElements()) { if (enclosedElement.getKind() != ElementKind.METHOD) { continue; OnCreateMountContent annotation = enclosedElement.getAnnotation(OnCreateMountContent.class); if (annotation != null) { if (annotation.mountingType() == MountingType.VIEW) { return ClassNames.COMPONENT_LIFECYCLE_MOUNT_TYPE_DRAWABLE; TypeMirror returnType = ((ExecutableElement) enclosedElement).getReturnType(); while (returnType.getKind() != TypeKind.NONE && returnType.getKind() != TypeKind.VOID) { final TypeElement returnElement = (TypeElement) ((DeclaredType) returnType).asElement(); returnType = returnElement.getSuperclass(); } catch (RuntimeException e) { throw new ComponentsProcessingException(
/** * Returns true if there's a public way to build the value type with an instance no-arg method. * * @param attribute value attribute to check. * @param possibleBuildMethod method which matches {@link StyleMirror#attributeBuilder()} * @return true if this is the possibleBuildMethod can build the value type. */ private static boolean isPossibleBuildMethod(ValueAttribute attribute, Element possibleBuildMethod) { if (possibleBuildMethod.getKind() != ElementKind.METHOD) { return false; } if (!attribute.containingType.names().possibleAttributeBuilder(possibleBuildMethod.getSimpleName())) { return false; } Types typeUtils = attribute.containingType.constitution.protoclass() .environment() .processing() .getTypeUtils(); ExecutableElement candidateBuildMethod = (ExecutableElement) possibleBuildMethod; return !candidateBuildMethod.getModifiers().contains(Modifier.STATIC) && candidateBuildMethod.getModifiers().contains(Modifier.PUBLIC) && candidateBuildMethod.getTypeParameters().isEmpty() && candidateBuildMethod.getReturnType().getKind() == TypeKind.DECLARED && typeUtils.isSameType(candidateBuildMethod.getReturnType(), attribute.containedTypeElement.asType()); }
private boolean isMethodProcessable(ExecutableElement element) { // if an immutable type with an implementation provided skip it if (!isUnimplementable() && element().getKind().isClass() && isImmutable() && !element.getModifiers().contains(Modifier.ABSTRACT)) { if (!ImmutableAnnotationKind.of(element()).isPresent() || !ImmutableAnnotationKind.of(element()).get().hasAnyMemberAnnotation(element)) { return false; } } String name = element.getSimpleName().toString(); // skip kotlin data class methods with component1, component2.. names if (isUnimplementable() && name.startsWith("component") && name.length() > "component".length()) { return false; } TypeMirror type = element.getReturnType(); boolean isInterface = element().getKind().isInterface(); boolean isTransient = Mirrors.findAnnotationMirror(element, Transient.class).isPresent(); // must be a getter style method with no args, can't return void or itself or its builder return type.getKind() != TypeKind.VOID && element.getParameters().isEmpty() && (isImmutable() || isInterface || !element.getModifiers().contains(Modifier.FINAL)) && (!isImmutable() || !type.equals(element().asType())) && !type.equals(builderType().orElse(null)) && !element.getModifiers().contains(Modifier.STATIC) && !element.getModifiers().contains(Modifier.DEFAULT) && (!isTransient || isInterface) && !name.equals("toString") && !name.equals("hashCode"); }
private void handleEmbeddedType(Element element, Set<TypeElement> elements) { TypeMirror type = element.asType(); if (element.getKind() == ElementKind.METHOD) { type = ((ExecutableElement) element).getReturnType(); } String typeName = type.toString(); if (typeName.startsWith(Collection.class.getName()) || typeName.startsWith(List.class.getName()) || typeName.startsWith(Set.class.getName())) { type = ((DeclaredType) type).getTypeArguments().get(0); } else if (typeName.startsWith(Map.class.getName())) { type = ((DeclaredType) type).getTypeArguments().get(1); } TypeElement typeElement = typeExtractor.visit(type); if (typeElement != null && !TypeUtils.hasAnnotationOfType(typeElement, conf.getEntityAnnotations())) { if (!typeElement.getQualifiedName().toString().startsWith("java.")) { elements.add(typeElement); } } }
@Override public Optional<ExecutableElement> factoryMethod() { Optional<ExecutableElement> staticFactory = ElementFilter.methodsIn(element().getEnclosedElements()).stream() .filter(element -> element.getModifiers().contains(Modifier.STATIC)) .filter(element -> element.getSimpleName().toString().equalsIgnoreCase("create")) .filter(element -> element.getParameters().size() > 0) .filter(element -> element.getReturnType().equals(element().asType())) .findAny(); Optional<ExecutableElement> constructor = ElementFilter.constructorsIn(element().getEnclosedElements()).stream() .filter(element -> element.getParameters().size() > 0) .findAny(); return staticFactory.isPresent() ? staticFactory : constructor; }
/** * @return The first element matching the given method in the class's hierarchy, or null if there * is no match. */ static ExecutableElement getMethodOnClass(TypeElement clazz, MethodSpec method, Types typeUtils, Elements elements) { if (clazz.asType().getKind() != TypeKind.DECLARED) { return null; } for (Element subElement : clazz.getEnclosedElements()) { if (subElement.getKind() == ElementKind.METHOD) { ExecutableElement methodElement = ((ExecutableElement) subElement); if (!methodElement.getSimpleName().toString().equals(method.name)) { continue; } if (!areParamsTheSame(methodElement, method, typeUtils, elements)) { continue; } return methodElement; } } TypeElement superClazz = getParentClassElement(clazz, typeUtils); if (superClazz == null) { return null; } return getMethodOnClass(superClazz, method, typeUtils, elements); }
@Override public void process(Element element, HasOnActivityResult holder) throws Exception { String methodName = element.getSimpleName().toString(); ExecutableElement executableElement = (ExecutableElement) element; List<? extends VariableElement> parameters = executableElement.getParameters(); int requestCode = executableElement.getAnnotation(OnActivityResult.class).value(); JBlock onResultBlock = holder.getOnActivityResultCaseBlock(requestCode).blockSimple(); IJExpression activityRef = holder.getGeneratedClass().staticRef("this"); JInvocation onResultInvocation = JExpr.invoke(activityRef, methodName); JVar intent = holder.getOnActivityResultDataParam(); JVar extras = null; for (VariableElement parameter : parameters) { TypeMirror parameterType = parameter.asType(); if (parameter.getAnnotation(OnActivityResult.Extra.class) != null) { if (extras == null) { extras = onResultBlock.decl(getClasses().BUNDLE, "extras_", JOp.cond(intent.ne(_null()).cand(intent.invoke("getExtras").ne(_null())), intent.invoke("getExtras"), _new(getClasses().BUNDLE))); } IJExpression extraParameter = extraHandler.getExtraValue(parameter, extras, onResultBlock, holder); onResultInvocation.arg(extraParameter); } else if (CanonicalNameConstants.INTENT.equals(parameterType.toString())) { onResultInvocation.arg(intent); } else if (parameterType.getKind().equals(TypeKind.INT) // || CanonicalNameConstants.INTEGER.equals(parameterType.toString())) { onResultInvocation.arg(holder.getOnActivityResultResultCodeParam()); } } onResultBlock.add(onResultInvocation); }
public void isPrefMethod(Element element, ElementValidation valid) { if (!element.getKind().equals(ElementKind.METHOD)) { valid.addError("Only methods are allowed in an %s annotated interface"); } else { ExecutableElement executableElement = (ExecutableElement) element; String methodName = executableElement.getSimpleName().toString(); if (executableElement.getParameters().size() > 0) { valid.addError("Method " + methodName + " should have no parameters in an %s annotated interface"); } else { String returnType = executableElement.getReturnType().toString(); if (!VALID_PREF_RETURN_TYPES.contains(returnType)) { valid.addError("Method " + methodName + " should only return preference simple types in an %s annotated interface"); } else { if (INVALID_PREF_METHOD_NAMES.contains(methodName)) { valid.addError("The method name " + methodName + " is forbidden in an %s annotated interface"); } else { return; } } } } valid.invalidate(); }
public void isSharedPreference(Element element, ElementValidation valid) { TypeMirror type = element.asType(); if (element instanceof ExecutableElement) { element = ((ExecutableElement) element).getParameters().get(0); type = element.asType(); if (type instanceof ErrorType || type.getKind() == TypeKind.ERROR) { String elementTypeName = type.toString(); TypeElement sharedPrefTypeElement = (TypeElement) sharedPrefElement; String sharedPrefQualifiedName = sharedPrefTypeElement.getQualifiedName().toString();
static boolean isValid(ExecutableElement elem, Messager messager) { return ensure(elem, doesNotThrow(elem), messager, () -> "@" + "Unapply method should not throw (checked) exceptions.") && ensure(elem, !elem.isDefault(), messager, () -> "@" + "Unapply method needs to be declared in a class, not an interface.") && ensure(elem, !elem.isVarArgs(), messager, () -> "@" + "Unapply method has varargs.") && ensure(elem, elem.getParameters().size() == 1, messager, () -> "Unapply method must have exactly one parameter of the object to be deconstructed.") && ensure(elem, elem.getParameters().get(0).asType().getKind() == TypeKind.DECLARED, messager, () -> "Unapply method parameter must be a declared type.") && ensure(elem, elem.getReturnType().toString().startsWith("io.vavr.Tuple"), messager, () -> "Return type of unapply method must be a Tuple.") && ensure(elem, !elem.getReturnType().toString().endsWith("Tuple"), messager, () -> "Return type is no Tuple implementation.") && ensure(elem, hasAll(elem, STATIC), messager, () -> "Unapply method needs to be static.") && ensure(elem, hasNone(elem, PRIVATE, PROTECTED, ABSTRACT), messager, () -> "Unapply method may not be private or protected."); }
protected SortedMap<String, JVar> addMethodParams(ExecutableElement executableElement, RestHolder restHolder, JMethod method) { List<? extends VariableElement> params = executableElement.getParameters(); SortedMap<String, JVar> methodParams = new TreeMap<>(); for (VariableElement parameter : params) { String paramName = parameter.getSimpleName().toString(); String paramType = parameter.asType().toString(); JVar param; if (parameter.asType().getKind().isPrimitive()) { param = method.param(getCodeModel().parseType(paramType), paramName); } else { AbstractJClass parameterClass = codeModelHelper.typeMirrorToJClass(parameter.asType()); param = method.param(parameterClass, paramName); } methodParams.put(paramName, param); } return methodParams; }