Search in sources :

Example 1 with ModelType

use of org.gradle.model.internal.type.ModelType in project gradle by gradle.

the class DefaultVariantsMetaData method extractFrom.

public static VariantsMetaData extractFrom(BinarySpec binarySpec, ModelSchema<?> binarySpecSchema) {
    Map<String, Object> variants = Maps.newLinkedHashMap();
    ImmutableMap.Builder<String, ModelType<?>> dimensionTypesBuilder = ImmutableMap.builder();
    if (binarySpecSchema instanceof StructSchema) {
        VariantAspect variantAspect = ((StructSchema<?>) binarySpecSchema).getAspect(VariantAspect.class);
        if (variantAspect != null) {
            for (ModelProperty<?> property : variantAspect.getDimensions()) {
                // note: it's not the role of this class to validate that the annotation is properly used, that
                // is to say only on a getter returning String or a Named instance, so we trust the result of
                // the call
                Object value = property.getPropertyValue(binarySpec);
                variants.put(property.getName(), value);
                dimensionTypesBuilder.put(property.getName(), property.getType());
            }
        }
    }
    return new DefaultVariantsMetaData(Collections.unmodifiableMap(variants), dimensionTypesBuilder.build());
}
Also used : StructSchema(org.gradle.model.internal.manage.schema.StructSchema) ModelType(org.gradle.model.internal.type.ModelType) VariantAspect(org.gradle.platform.base.internal.VariantAspect) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 2 with ModelType

use of org.gradle.model.internal.type.ModelType in project gradle by gradle.

the class RuleSourceBackedRuleAction method create.

public static <R, T> RuleSourceBackedRuleAction<R, T> create(ModelType<T> subjectType, R ruleSourceInstance) {
    ModelType<R> ruleSourceType = ModelType.typeOf(ruleSourceInstance);
    List<Method> mutateMethods = JavaReflectionUtil.findAllMethods(ruleSourceType.getConcreteClass(), new Spec<Method>() {

        public boolean isSatisfiedBy(Method element) {
            return element.isAnnotationPresent(Mutate.class);
        }
    });
    FormattingValidationProblemCollector problemsFormatter = new FormattingValidationProblemCollector("rule source", ruleSourceType);
    RuleSourceValidationProblemCollector problems = new DefaultRuleSourceValidationProblemCollector(problemsFormatter);
    if (mutateMethods.size() == 0) {
        problems.add("Must have at exactly one method annotated with @" + Mutate.class.getName());
    } else {
        if (mutateMethods.size() > 1) {
            problems.add("More than one method is annotated with @" + Mutate.class.getName());
        }
        for (Method ruleMethod : mutateMethods) {
            if (ruleMethod.getReturnType() != Void.TYPE) {
                problems.add(ruleMethod, "A rule method must return void");
            }
            Type[] parameterTypes = ruleMethod.getGenericParameterTypes();
            if (parameterTypes.length == 0 || !subjectType.isAssignableFrom(ModelType.of(parameterTypes[0]))) {
                problems.add(ruleMethod, String.format("First parameter of a rule method must be of type %s", subjectType));
            }
        }
    }
    if (problemsFormatter.hasProblems()) {
        throw new RuleActionValidationException(problemsFormatter.format());
    }
    return new RuleSourceBackedRuleAction<R, T>(ruleSourceInstance, new JavaMethod<R, T>(subjectType.getConcreteClass(), mutateMethods.get(0)));
}
Also used : Mutate(org.gradle.model.Mutate) JavaMethod(org.gradle.internal.reflect.JavaMethod) Method(java.lang.reflect.Method) DefaultRuleSourceValidationProblemCollector(org.gradle.model.internal.inspect.DefaultRuleSourceValidationProblemCollector) RuleSourceValidationProblemCollector(org.gradle.model.internal.inspect.RuleSourceValidationProblemCollector) Type(java.lang.reflect.Type) ModelType(org.gradle.model.internal.type.ModelType) FormattingValidationProblemCollector(org.gradle.model.internal.inspect.FormattingValidationProblemCollector) DefaultRuleSourceValidationProblemCollector(org.gradle.model.internal.inspect.DefaultRuleSourceValidationProblemCollector)

Example 3 with ModelType

use of org.gradle.model.internal.type.ModelType in project gradle by gradle.

the class ManagedProxyClassGenerator method writeViewMethods.

private void writeViewMethods(ClassVisitor visitor, Type generatedType, Collection<ModelType<?>> viewTypes, StructBindings<?> bindings) {
    Type delegateType;
    StructSchema<?> delegateSchema = bindings.getDelegateSchema();
    if (delegateSchema != null) {
        Class<?> delegateClass = delegateSchema.getType().getRawClass();
        declareDelegateField(visitor, delegateClass);
        delegateType = Type.getType(delegateClass);
    } else {
        delegateType = null;
    }
    Multimap<String, ModelProperty<?>> viewPropertiesByNameBuilder = ArrayListMultimap.create();
    Set<Wrapper<Method>> viewMethods = Sets.newLinkedHashSet();
    for (StructSchema<?> viewSchema : bindings.getImplementedViewSchemas()) {
        for (ModelType<?> viewType : viewTypes) {
            if (viewType.equals(viewSchema.getType())) {
                for (ModelProperty<?> property : viewSchema.getProperties()) {
                    String propertyName = property.getName();
                    viewPropertiesByNameBuilder.put(propertyName, property);
                }
                for (WeaklyTypeReferencingMethod<?, ?> viewMethod : viewSchema.getAllMethods()) {
                    viewMethods.add(SIGNATURE_EQUIVALENCE.wrap(viewMethod.getMethod()));
                }
                break;
            }
        }
    }
    Class<?> viewClass = bindings.getPublicSchema().getType().getConcreteClass();
    for (Collection<ModelProperty<?>> viewProperties : viewPropertiesByNameBuilder.asMap().values()) {
        writeViewPropertyDslMethods(visitor, generatedType, viewProperties, viewClass);
    }
    for (StructMethodBinding methodBinding : bindings.getMethodBindings()) {
        WeaklyTypeReferencingMethod<?, ?> weakViewMethod = methodBinding.getViewMethod();
        Method viewMethod = weakViewMethod.getMethod();
        // Don't generate method if it's not part of the view schema
        Wrapper<Method> methodKey = SIGNATURE_EQUIVALENCE.wrap(viewMethod);
        if (!viewMethods.contains(methodKey)) {
            continue;
        }
        if (methodBinding instanceof DirectMethodBinding) {
            // TODO:LPTR What is with the "metaClass" property here?
            boolean isGetterMethod = methodBinding.getAccessorType() == GET_GETTER || methodBinding.getAccessorType() == IS_GETTER;
            if (isGetterMethod && !Modifier.isFinal(viewMethod.getModifiers()) && !viewMethod.getName().equals("getMetaClass")) {
                writeNonAbstractMethodWrapper(visitor, generatedType, viewClass, viewMethod);
            }
        } else if (methodBinding instanceof BridgeMethodBinding) {
            writeBridgeMethod(visitor, generatedType, viewMethod);
        } else if (methodBinding instanceof DelegateMethodBinding) {
            writeDelegatingMethod(visitor, generatedType, delegateType, viewMethod);
        } else if (methodBinding instanceof ManagedPropertyMethodBinding) {
            ManagedPropertyMethodBinding propertyBinding = (ManagedPropertyMethodBinding) methodBinding;
            ManagedProperty<?> managedProperty = bindings.getManagedProperty(propertyBinding.getPropertyName());
            String propertyName = managedProperty.getName();
            Class<?> propertyClass = managedProperty.getType().getRawClass();
            WeaklyTypeReferencingMethod<?, ?> propertyAccessor = propertyBinding.getViewMethod();
            switch(propertyBinding.getAccessorType()) {
                case GET_GETTER:
                case IS_GETTER:
                    writeGetter(visitor, generatedType, propertyName, propertyClass, propertyAccessor);
                    break;
                case SETTER:
                    writeSetter(visitor, generatedType, propertyName, propertyClass, propertyAccessor);
                    break;
                default:
                    throw new AssertionError();
            }
        } else {
            throw new AssertionError();
        }
    }
}
Also used : Wrapper(com.google.common.base.Equivalence.Wrapper) DirectMethodBinding(org.gradle.model.internal.manage.binding.DirectMethodBinding) Method(java.lang.reflect.Method) WeaklyTypeReferencingMethod(org.gradle.model.internal.method.WeaklyTypeReferencingMethod) BridgeMethodBinding(org.gradle.model.internal.manage.binding.BridgeMethodBinding) ManagedPropertyMethodBinding(org.gradle.model.internal.manage.binding.ManagedPropertyMethodBinding) DelegateMethodBinding(org.gradle.model.internal.manage.binding.DelegateMethodBinding) WeaklyTypeReferencingMethod(org.gradle.model.internal.method.WeaklyTypeReferencingMethod) ManagedProperty(org.gradle.model.internal.manage.binding.ManagedProperty) Type(org.objectweb.asm.Type) PropertyAccessorType(org.gradle.internal.reflect.PropertyAccessorType) ModelType(org.gradle.model.internal.type.ModelType) StructMethodBinding(org.gradle.model.internal.manage.binding.StructMethodBinding) ModelProperty(org.gradle.model.internal.manage.schema.ModelProperty)

Example 4 with ModelType

use of org.gradle.model.internal.type.ModelType in project gradle by gradle.

the class TypeOf method captureTypeArgument.

private ModelType<T> captureTypeArgument() {
    Type genericSuperclass = getClass().getGenericSuperclass();
    Type type = genericSuperclass instanceof ParameterizedType ? ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0] : Object.class;
    return Cast.uncheckedCast(ModelType.of(type));
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) ModelType(org.gradle.model.internal.type.ModelType)

Example 5 with ModelType

use of org.gradle.model.internal.type.ModelType in project gradle by gradle.

the class ManagedProxyClassGenerator method generate.

/**
     * Generates an implementation of the given managed type.
     * <p>
     * The generated class will implement/extend the managed type and will:
     * <ul>
     *     <li>provide implementations for abstract getters and setters that delegate to the backing state</li>
     *     <li>provide a `toString()` implementation</li>
     *     <li>mix-in implementation of {@link ManagedInstance}</li>
     *     <li>provide a constructor that accepts a {@link ModelElementState}, which will be used to implement the above.</li>
     * </ul>
     *
     * In case a delegate schema is supplied, the generated class will also have:
     * <ul>
     *     <li>a constructor that also takes a delegate instance</li>
     *     <li>methods that call through to the delegate instance</li>
     * </ul>
     */
public <T, M extends T, D extends T> Class<? extends M> generate(Class<? extends GeneratedViewState> backingStateType, StructSchema<M> viewSchema, StructBindings<?> structBindings) {
    if (!structBindings.getImplementedViewSchemas().contains(viewSchema)) {
        throw new IllegalArgumentException(String.format("View '%s' is not supported by struct '%s'", viewSchema.getType(), structBindings.getPublicSchema().getType()));
    }
    ClassWriter visitor = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    ModelType<M> viewType = viewSchema.getType();
    StringBuilder generatedTypeNameBuilder = new StringBuilder(viewType.getRawClass().getName());
    if (backingStateType == GeneratedViewState.class) {
        generatedTypeNameBuilder.append("$View");
    } else {
        generatedTypeNameBuilder.append("$NodeView");
    }
    StructSchema<D> delegateSchema = Cast.uncheckedCast(structBindings.getDelegateSchema());
    if (delegateSchema != null) {
        generatedTypeNameBuilder.append("$").append(delegateSchema.getType().getName().replaceAll("\\.", "_"));
    }
    String generatedTypeName = generatedTypeNameBuilder.toString();
    Type generatedType = Type.getType("L" + generatedTypeName.replaceAll("\\.", "/") + ";");
    Class<?> superclass;
    final ImmutableSet.Builder<String> interfacesToImplement = ImmutableSet.builder();
    final ImmutableSet.Builder<ModelType<?>> typesToDelegate = ImmutableSet.builder();
    typesToDelegate.add(viewType);
    interfacesToImplement.add(GENERATED_VIEW_TYPE.getInternalName());
    if (backingStateType == ModelElementState.class) {
        interfacesToImplement.add(MANAGED_INSTANCE_TYPE);
    }
    Class<M> viewClass = viewType.getConcreteClass();
    if (viewClass.isInterface()) {
        superclass = Object.class;
        interfacesToImplement.add(Type.getInternalName(viewClass));
    } else {
        superclass = viewClass;
    }
    // BinaryContainer won't recognize managed binaries as BinarySpecInternal
    if (delegateSchema != null) {
        walkTypeHierarchy(delegateSchema.getType().getConcreteClass(), IGNORED_OBJECT_TYPES, new TypeVisitor<D>() {

            @Override
            public void visitType(Class<? super D> type) {
                if (type.isInterface()) {
                    typesToDelegate.add(ModelType.of(type));
                    interfacesToImplement.add(Type.getInternalName(type));
                }
            }
        });
    }
    generateProxyClass(visitor, viewSchema, structBindings, interfacesToImplement.build(), typesToDelegate.build(), generatedType, Type.getType(superclass), backingStateType);
    ClassLoader targetClassLoader = viewClass.getClassLoader();
    if (delegateSchema != null) {
        // TODO - remove this once the above is removed
        try {
            viewClass.getClassLoader().loadClass(delegateSchema.getType().getConcreteClass().getName());
        } catch (ClassNotFoundException e) {
            // Delegate class is not visible to managed view type -> view type is more general than delegate type, so use the delegate classloader instead
            targetClassLoader = delegateSchema.getType().getConcreteClass().getClassLoader();
        }
    }
    return defineClass(visitor, targetClassLoader, generatedTypeName);
}
Also used : ClassWriter(org.objectweb.asm.ClassWriter) Type(org.objectweb.asm.Type) PropertyAccessorType(org.gradle.internal.reflect.PropertyAccessorType) ModelType(org.gradle.model.internal.type.ModelType) ImmutableSet(com.google.common.collect.ImmutableSet) ModelType(org.gradle.model.internal.type.ModelType)

Aggregations

ModelType (org.gradle.model.internal.type.ModelType)6 Type (java.lang.reflect.Type)3 Method (java.lang.reflect.Method)2 ParameterizedType (java.lang.reflect.ParameterizedType)2 PropertyAccessorType (org.gradle.internal.reflect.PropertyAccessorType)2 Type (org.objectweb.asm.Type)2 Wrapper (com.google.common.base.Equivalence.Wrapper)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 ExecutionException (java.util.concurrent.ExecutionException)1 JavaMethod (org.gradle.internal.reflect.JavaMethod)1 ModelMap (org.gradle.model.ModelMap)1 Mutate (org.gradle.model.Mutate)1 NodeBackedModelMap (org.gradle.model.internal.core.NodeBackedModelMap)1 DefaultRuleSourceValidationProblemCollector (org.gradle.model.internal.inspect.DefaultRuleSourceValidationProblemCollector)1 FormattingValidationProblemCollector (org.gradle.model.internal.inspect.FormattingValidationProblemCollector)1 RuleSourceValidationProblemCollector (org.gradle.model.internal.inspect.RuleSourceValidationProblemCollector)1 BridgeMethodBinding (org.gradle.model.internal.manage.binding.BridgeMethodBinding)1 DelegateMethodBinding (org.gradle.model.internal.manage.binding.DelegateMethodBinding)1 DirectMethodBinding (org.gradle.model.internal.manage.binding.DirectMethodBinding)1