Search in sources :

Example 36 with ExecutableType

use of javax.lang.model.type.ExecutableType in project react4j by react4j.

the class ReactProcessor method determineStateValues.

private void determineStateValues(@Nonnull final ComponentDescriptor descriptor) {
    final List<ExecutableElement> methods = ProcessorUtil.getMethods(descriptor.getElement(), processingEnv.getTypeUtils()).stream().filter(m -> null != ProcessorUtil.findAnnotationByType(m, Constants.STATE_ANNOTATION_CLASSNAME)).collect(Collectors.toList());
    final Map<String, StateValueDescriptor> values = new HashMap<>();
    for (final ExecutableElement method : methods) {
        final ExecutableType methodType = (ExecutableType) processingEnv.getTypeUtils().asMemberOf(descriptor.getDeclaredType(), method);
        parseStateValueMethod(method, methodType, values);
    }
    final ArrayList<StateValueDescriptor> stateValues = new ArrayList<>(values.values());
    descriptor.setStateValues(stateValues);
    linkStateMethods(descriptor);
    for (final StateValueDescriptor stateValue : stateValues) {
        if (!stateValue.hasGetter()) {
            throw new ReactProcessorException("@State target defined setter but no getter was defined and no " + "getter could be automatically determined", stateValue.getSetter());
        } else if (!stateValue.hasSetter()) {
            throw new ReactProcessorException("@State target defined getter but no setter was defined and no " + "setter could be automatically determined", stateValue.getGetter());
        }
    }
    for (final StateValueDescriptor stateValue : stateValues) {
        final TypeMirror returnType = stateValue.getGetterType().getReturnType();
        final TypeMirror parameterType = stateValue.getSetterType().getParameterTypes().get(0);
        if (!processingEnv.getTypeUtils().isSameType(parameterType, returnType)) {
            throw new ReactProcessorException("@State property defines a setter and getter with different types." + " Getter type: " + returnType + " Setter type: " + parameterType + ".", stateValue.getGetter());
        }
    }
}
Also used : Arrays(java.util.Arrays) PackageElement(javax.lang.model.element.PackageElement) AbstractProcessor(javax.annotation.processing.AbstractProcessor) Modifier(javax.lang.model.element.Modifier) VariableElement(javax.lang.model.element.VariableElement) HashMap(java.util.HashMap) TypeElement(javax.lang.model.element.TypeElement) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Elements(javax.lang.model.util.Elements) ArrayList(java.util.ArrayList) SupportedSourceVersion(javax.annotation.processing.SupportedSourceVersion) Kind(javax.tools.Diagnostic.Kind) Map(java.util.Map) DeclaredType(javax.lang.model.type.DeclaredType) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) PrintWriter(java.io.PrintWriter) ElementKind(javax.lang.model.element.ElementKind) ExecutableType(javax.lang.model.type.ExecutableType) StringWriter(java.io.StringWriter) Collection(java.util.Collection) ExecutableElement(javax.lang.model.element.ExecutableElement) Set(java.util.Set) IOException(java.io.IOException) Element(javax.lang.model.element.Element) TypeSpec(com.squareup.javapoet.TypeSpec) Processor(javax.annotation.processing.Processor) Types(javax.lang.model.util.Types) Collectors(java.util.stream.Collectors) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeKind(javax.lang.model.type.TypeKind) JavaFile(com.squareup.javapoet.JavaFile) SourceVersion(javax.lang.model.SourceVersion) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) RoundEnvironment(javax.annotation.processing.RoundEnvironment) AutoService(com.google.auto.service.AutoService) ExecutableType(javax.lang.model.type.ExecutableType) HashMap(java.util.HashMap) TypeMirror(javax.lang.model.type.TypeMirror) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList)

Example 37 with ExecutableType

use of javax.lang.model.type.ExecutableType in project react4j by react4j.

the class ReactProcessor method determineCallbacks.

private void determineCallbacks(@Nonnull final ComponentDescriptor descriptor) {
    final List<CallbackDescriptor> callbacks = ProcessorUtil.getMethods(descriptor.getElement(), processingEnv.getTypeUtils()).stream().filter(m -> null != ProcessorUtil.findAnnotationByType(m, Constants.CALLBACK_ANNOTATION_CLASSNAME)).map(m -> createCallbackDescriptor(descriptor, m)).collect(Collectors.toList());
    for (final CallbackDescriptor callback : callbacks) {
        final ExecutableElement method = callback.getMethod();
        final TypeElement callbackType = getCallbackType(method);
        if (ElementKind.INTERFACE != callbackType.getKind()) {
            throw new ReactProcessorException("The @Callback specified an invalid type that is not an interface.", callback.getMethod());
        }
        if (null == ProcessorUtil.findAnnotationByType(callbackType, Constants.JS_FUNCTION_CLASSNAME)) {
            throw new ReactProcessorException("The @Callback specified an invalid type that is not annotated " + "with the annotation jsinterop.annotations.JsFunction.", callback.getMethod());
        }
        final CallbackDescriptor matched = callbacks.stream().filter(h -> h != callback && h.getName().equals(callback.getName())).findAny().orElse(null);
        if (null != matched) {
            throw new ReactProcessorException("The @Callback has the same name as the callback defined by " + matched.getMethod() + ".", callback.getMethod());
        }
        final CallbackDescriptor matched2 = callbacks.stream().filter(h -> h != callback && h.getMethod().getSimpleName().equals(callback.getMethod().getSimpleName())).findAny().orElse(null);
        if (null != matched2) {
            throw new ReactProcessorException("The @Callback has the same method name as the callback defined " + "by " + matched2.getMethod() + ".", callback.getMethod());
        }
        final ExecutableType methodType = callback.getMethodType();
        final List<? extends TypeMirror> parameters = methodType.getParameterTypes();
        if (!parameters.isEmpty()) {
            // Our annotated callback method has parameters so they should exactly align
            // in count and type with the parameters in the callback method
            final ExecutableElement target = callback.getCallbackMethod();
            final List<? extends VariableElement> targetParameters = target.getParameters();
            if (targetParameters.size() != parameters.size()) {
                throw new ReactProcessorException("The @Callback target has " + parameters.size() + " parameters " + "but the type parameter specified a callback with method type " + callback.getCallbackType().getQualifiedName() + " that has a " + "callback method with " + targetParameters.size() + " parameters. The " + "@Callback target should have zero parameters or match the number " + "of parameter in the target method " + target.getSimpleName() + ".", callback.getMethod());
            }
            for (int i = 0; i < parameters.size(); i++) {
                final TypeMirror parameterType = parameters.get(i);
                final VariableElement element = targetParameters.get(i);
                final TypeMirror targetParameterType = element.asType();
                final TypeMirror targetErased = processingEnv.getTypeUtils().erasure(targetParameterType);
                final TypeMirror parameterErased = processingEnv.getTypeUtils().erasure(parameterType);
                if (!processingEnv.getTypeUtils().isAssignable(targetErased, parameterErased)) {
                    throw new ReactProcessorException("The @Callback target parameter named " + callback.getMethod().getParameters().get(i).getSimpleName() + " of type " + parameterType + " is not assignable from target type " + targetParameterType + " of parameter " + element.getSimpleName() + " in method " + callback.getCallbackType().getQualifiedName() + "." + target.getSimpleName() + ".", callback.getMethod());
                }
            }
        }
    }
    descriptor.setCallbacks(callbacks);
}
Also used : Arrays(java.util.Arrays) PackageElement(javax.lang.model.element.PackageElement) AbstractProcessor(javax.annotation.processing.AbstractProcessor) Modifier(javax.lang.model.element.Modifier) VariableElement(javax.lang.model.element.VariableElement) HashMap(java.util.HashMap) TypeElement(javax.lang.model.element.TypeElement) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Elements(javax.lang.model.util.Elements) ArrayList(java.util.ArrayList) SupportedSourceVersion(javax.annotation.processing.SupportedSourceVersion) Kind(javax.tools.Diagnostic.Kind) Map(java.util.Map) DeclaredType(javax.lang.model.type.DeclaredType) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) PrintWriter(java.io.PrintWriter) ElementKind(javax.lang.model.element.ElementKind) ExecutableType(javax.lang.model.type.ExecutableType) StringWriter(java.io.StringWriter) Collection(java.util.Collection) ExecutableElement(javax.lang.model.element.ExecutableElement) Set(java.util.Set) IOException(java.io.IOException) Element(javax.lang.model.element.Element) TypeSpec(com.squareup.javapoet.TypeSpec) Processor(javax.annotation.processing.Processor) Types(javax.lang.model.util.Types) Collectors(java.util.stream.Collectors) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeKind(javax.lang.model.type.TypeKind) JavaFile(com.squareup.javapoet.JavaFile) SourceVersion(javax.lang.model.SourceVersion) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) RoundEnvironment(javax.annotation.processing.RoundEnvironment) AutoService(com.google.auto.service.AutoService) ExecutableType(javax.lang.model.type.ExecutableType) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) VariableElement(javax.lang.model.element.VariableElement)

Example 38 with ExecutableType

use of javax.lang.model.type.ExecutableType in project react4j by react4j.

the class ReactProcessor method determineDefaultPropsMethods.

private void determineDefaultPropsMethods(@Nonnull final ComponentDescriptor descriptor) {
    final Types typeUtils = processingEnv.getTypeUtils();
    final List<ExecutableElement> defaultPropsMethods = ProcessorUtil.getMethods(descriptor.getElement(), typeUtils).stream().filter(m -> null != ProcessorUtil.findAnnotationByType(m, Constants.PROP_DEFAULT_ANNOTATION_CLASSNAME)).collect(Collectors.toList());
    for (final ExecutableElement method : defaultPropsMethods) {
        final String name = derivePropDefaultName(method);
        final PropDescriptor prop = descriptor.findPropNamed(name);
        if (null == prop) {
            throw new ReactProcessorException("@PropDefault target for prop named '" + name + "' has no corresponding " + "@Prop annotated method.", method);
        }
        final ExecutableType methodType = (ExecutableType) typeUtils.asMemberOf(descriptor.getDeclaredType(), method);
        if (!processingEnv.getTypeUtils().isAssignable(methodType.getReturnType(), prop.getMethodType().getReturnType())) {
            throw new ReactProcessorException("@PropDefault target has a return type that is not assignable to the " + "return type of the associated @Prop annotated method.", method);
        }
        prop.setDefaultMethod(method);
    }
}
Also used : Arrays(java.util.Arrays) PackageElement(javax.lang.model.element.PackageElement) AbstractProcessor(javax.annotation.processing.AbstractProcessor) Modifier(javax.lang.model.element.Modifier) VariableElement(javax.lang.model.element.VariableElement) HashMap(java.util.HashMap) TypeElement(javax.lang.model.element.TypeElement) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Elements(javax.lang.model.util.Elements) ArrayList(java.util.ArrayList) SupportedSourceVersion(javax.annotation.processing.SupportedSourceVersion) Kind(javax.tools.Diagnostic.Kind) Map(java.util.Map) DeclaredType(javax.lang.model.type.DeclaredType) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) PrintWriter(java.io.PrintWriter) ElementKind(javax.lang.model.element.ElementKind) ExecutableType(javax.lang.model.type.ExecutableType) StringWriter(java.io.StringWriter) Collection(java.util.Collection) ExecutableElement(javax.lang.model.element.ExecutableElement) Set(java.util.Set) IOException(java.io.IOException) Element(javax.lang.model.element.Element) TypeSpec(com.squareup.javapoet.TypeSpec) Processor(javax.annotation.processing.Processor) Types(javax.lang.model.util.Types) Collectors(java.util.stream.Collectors) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeKind(javax.lang.model.type.TypeKind) JavaFile(com.squareup.javapoet.JavaFile) SourceVersion(javax.lang.model.SourceVersion) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) RoundEnvironment(javax.annotation.processing.RoundEnvironment) AutoService(com.google.auto.service.AutoService) ExecutableType(javax.lang.model.type.ExecutableType) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Types(javax.lang.model.util.Types) ExecutableElement(javax.lang.model.element.ExecutableElement)

Example 39 with ExecutableType

use of javax.lang.model.type.ExecutableType in project react4j by react4j.

the class ReactProcessor method linkStateMethods.

private void linkStateMethods(@Nonnull final ComponentDescriptor descriptor) {
    final List<ExecutableElement> candidates = ProcessorUtil.getMethods(descriptor.getElement(), processingEnv.getTypeUtils()).stream().filter(m -> m.getModifiers().contains(Modifier.ABSTRACT)).filter(m -> null == ProcessorUtil.findAnnotationByType(descriptor.getElement(), Constants.PROP_ANNOTATION_CLASSNAME) && null == ProcessorUtil.findAnnotationByType(descriptor.getElement(), Constants.STATE_ANNOTATION_CLASSNAME)).collect(Collectors.toList());
    for (final ExecutableElement method : candidates) {
        final ExecutableType methodType = (ExecutableType) processingEnv.getTypeUtils().asMemberOf(descriptor.getDeclaredType(), method);
        if (method.getReturnType().getKind() == TypeKind.VOID && 1 == method.getParameters().size()) {
            final String stateName = ProcessorUtil.getPropertyMutatorName(method, ProcessorUtil.SENTINEL_NAME);
            final StateValueDescriptor stateValueNamed = descriptor.findStateValueNamed(stateName);
            if (null != stateValueNamed && !stateValueNamed.hasSetter()) {
                stateValueNamed.setSetter(method, methodType);
            }
        } else if (method.getReturnType().getKind() != TypeKind.VOID && 0 == method.getParameters().size()) {
            final String stateName = ProcessorUtil.getPropertyAccessorName(method, ProcessorUtil.SENTINEL_NAME);
            final StateValueDescriptor stateValueNamed = descriptor.findStateValueNamed(stateName);
            if (null != stateValueNamed && !stateValueNamed.hasGetter()) {
                stateValueNamed.setGetter(method, methodType);
            }
        }
    }
}
Also used : Arrays(java.util.Arrays) PackageElement(javax.lang.model.element.PackageElement) AbstractProcessor(javax.annotation.processing.AbstractProcessor) Modifier(javax.lang.model.element.Modifier) VariableElement(javax.lang.model.element.VariableElement) HashMap(java.util.HashMap) TypeElement(javax.lang.model.element.TypeElement) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Elements(javax.lang.model.util.Elements) ArrayList(java.util.ArrayList) SupportedSourceVersion(javax.annotation.processing.SupportedSourceVersion) Kind(javax.tools.Diagnostic.Kind) Map(java.util.Map) DeclaredType(javax.lang.model.type.DeclaredType) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) PrintWriter(java.io.PrintWriter) ElementKind(javax.lang.model.element.ElementKind) ExecutableType(javax.lang.model.type.ExecutableType) StringWriter(java.io.StringWriter) Collection(java.util.Collection) ExecutableElement(javax.lang.model.element.ExecutableElement) Set(java.util.Set) IOException(java.io.IOException) Element(javax.lang.model.element.Element) TypeSpec(com.squareup.javapoet.TypeSpec) Processor(javax.annotation.processing.Processor) Types(javax.lang.model.util.Types) Collectors(java.util.stream.Collectors) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeKind(javax.lang.model.type.TypeKind) JavaFile(com.squareup.javapoet.JavaFile) SourceVersion(javax.lang.model.SourceVersion) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) RoundEnvironment(javax.annotation.processing.RoundEnvironment) AutoService(com.google.auto.service.AutoService) ExecutableType(javax.lang.model.type.ExecutableType) ExecutableElement(javax.lang.model.element.ExecutableElement)

Example 40 with ExecutableType

use of javax.lang.model.type.ExecutableType in project react4j by react4j.

the class ReactProcessor method determineLifecycleMethods.

private void determineLifecycleMethods(@Nonnull final TypeElement typeElement, @Nonnull final ComponentDescriptor descriptor) {
    /*
     * Get the list of lifecycle methods that have been overridden by typeElement
     * a parent class, or by a default method method implemented by typeElement or
     * a parent class.
     */
    final Collection<ExecutableElement> lifecycleMethods = getComponentLifecycleMethods().values();
    final Elements elementUtils = processingEnv.getElementUtils();
    final Types typeUtils = processingEnv.getTypeUtils();
    final TypeElement componentType = elementUtils.getTypeElement(Constants.COMPONENT_CLASSNAME);
    final List<MethodDescriptor> overriddenLifecycleMethods = // Get all methods on type parent classes, and default methods from interfaces
    ProcessorUtil.getMethods(typeElement, processingEnv.getTypeUtils()).stream().filter(m -> lifecycleMethods.stream().anyMatch(l -> elementUtils.overrides(m, l, typeElement))).filter(m -> m.getEnclosingElement() != componentType).map(m -> new MethodDescriptor(m, (ExecutableType) typeUtils.asMemberOf(descriptor.getDeclaredType(), m))).collect(Collectors.toList());
    descriptor.setLifecycleMethods(overriddenLifecycleMethods);
}
Also used : Arrays(java.util.Arrays) PackageElement(javax.lang.model.element.PackageElement) AbstractProcessor(javax.annotation.processing.AbstractProcessor) Modifier(javax.lang.model.element.Modifier) VariableElement(javax.lang.model.element.VariableElement) HashMap(java.util.HashMap) TypeElement(javax.lang.model.element.TypeElement) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Elements(javax.lang.model.util.Elements) ArrayList(java.util.ArrayList) SupportedSourceVersion(javax.annotation.processing.SupportedSourceVersion) Kind(javax.tools.Diagnostic.Kind) Map(java.util.Map) DeclaredType(javax.lang.model.type.DeclaredType) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) PrintWriter(java.io.PrintWriter) ElementKind(javax.lang.model.element.ElementKind) ExecutableType(javax.lang.model.type.ExecutableType) StringWriter(java.io.StringWriter) Collection(java.util.Collection) ExecutableElement(javax.lang.model.element.ExecutableElement) Set(java.util.Set) IOException(java.io.IOException) Element(javax.lang.model.element.Element) TypeSpec(com.squareup.javapoet.TypeSpec) Processor(javax.annotation.processing.Processor) Types(javax.lang.model.util.Types) Collectors(java.util.stream.Collectors) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeKind(javax.lang.model.type.TypeKind) JavaFile(com.squareup.javapoet.JavaFile) SourceVersion(javax.lang.model.SourceVersion) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) RoundEnvironment(javax.annotation.processing.RoundEnvironment) AutoService(com.google.auto.service.AutoService) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Types(javax.lang.model.util.Types) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Elements(javax.lang.model.util.Elements)

Aggregations

ExecutableType (javax.lang.model.type.ExecutableType)68 ExecutableElement (javax.lang.model.element.ExecutableElement)53 DeclaredType (javax.lang.model.type.DeclaredType)41 TypeElement (javax.lang.model.element.TypeElement)39 TypeMirror (javax.lang.model.type.TypeMirror)39 Element (javax.lang.model.element.Element)29 VariableElement (javax.lang.model.element.VariableElement)27 TypeSpec (com.squareup.javapoet.TypeSpec)13 Nonnull (javax.annotation.Nonnull)13 PackageElement (javax.lang.model.element.PackageElement)13 HashMap (java.util.HashMap)12 Map (java.util.Map)12 MethodSpec (com.squareup.javapoet.MethodSpec)11 AnnotationMirror (javax.lang.model.element.AnnotationMirror)11 IOException (java.io.IOException)10 ArrayList (java.util.ArrayList)10 HashSet (java.util.HashSet)10 Nullable (javax.annotation.Nullable)10 JavaFile (com.squareup.javapoet.JavaFile)9 List (java.util.List)9