Search in sources :

Example 1 with ScalarValueSchema

use of org.gradle.model.internal.manage.schema.ScalarValueSchema in project gradle by gradle.

the class ManagedProxyClassGenerator method writeSetMethod.

private void writeSetMethod(ClassVisitor visitor, Type generatedType, ModelProperty<?> property) {
    WeaklyTypeReferencingMethod<?, ?> setter = property.getAccessor(SETTER);
    if (setter != null && property.getSchema() instanceof ScalarValueSchema) {
        // TODO - should we support this?
        // Adds a void $propName(Object value) method that simply delegates to the converting setter method
        MethodVisitor methodVisitor = declareMethod(visitor, property.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE), null);
        putThisOnStack(methodVisitor);
        putFirstMethodArgumentOnStack(methodVisitor);
        methodVisitor.visitMethodInsn(INVOKEVIRTUAL, generatedType.getInternalName(), setter.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE), false);
        finishVisitingMethod(methodVisitor);
    }
}
Also used : ScalarValueSchema(org.gradle.model.internal.manage.schema.ScalarValueSchema) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 2 with ScalarValueSchema

use of org.gradle.model.internal.manage.schema.ScalarValueSchema in project gradle by gradle.

the class ScalarCollectionNodeInitializerExtractionStrategy method extractNodeInitializer.

@Override
protected <T, E> NodeInitializer extractNodeInitializer(CollectionSchema<T, E> schema, NodeInitializerContext<T> context) {
    ModelType<T> type = schema.getType();
    Class<? super T> rawClass = type.getRawClass();
    ModelType<? super T> rawCollectionType = ModelType.of(rawClass);
    if (TYPES.contains(rawCollectionType) && (schema.getElementTypeSchema() instanceof ScalarValueSchema)) {
        Optional<NodeInitializerContext.PropertyContext> propertyContext = context.getPropertyContextOptional();
        boolean writable = !propertyContext.isPresent() || propertyContext.get().isWritable();
        if (schema.getType().getRawClass() == List.class) {
            return new ProjectionOnlyNodeInitializer(ScalarCollectionModelProjection.forList(schema.getElementType(), !writable), new ModelElementProjection(schema.getType()));
        } else {
            return new ProjectionOnlyNodeInitializer(ScalarCollectionModelProjection.forSet(schema.getElementType(), !writable), new ModelElementProjection(schema.getType()));
        }
    }
    return null;
}
Also used : ProjectionOnlyNodeInitializer(org.gradle.model.internal.inspect.ProjectionOnlyNodeInitializer) ModelElementProjection(org.gradle.model.internal.inspect.ModelElementProjection) ScalarValueSchema(org.gradle.model.internal.manage.schema.ScalarValueSchema)

Example 3 with ScalarValueSchema

use of org.gradle.model.internal.manage.schema.ScalarValueSchema in project gradle by gradle.

the class ManagedProxyClassGenerator method writeTypeConvertingSetter.

// the overload of type Object for Groovy coercions:  public void setFoo(Object foo)
private void writeTypeConvertingSetter(ClassVisitor visitor, Type generatedType, Class<?> viewClass, ModelProperty<?> property) {
    WeaklyTypeReferencingMethod<?, ?> weakSetter = property.getAccessor(SETTER);
    // There is no setter for this property
    if (weakSetter == null) {
        return;
    }
    if (!(property.getSchema() instanceof ScalarValueSchema)) {
        return;
    }
    Class<?> propertyClass = property.getType().getConcreteClass();
    Type propertyType = Type.getType(propertyClass);
    Class<?> boxedClass = propertyClass.isPrimitive() ? BOXED_TYPES.get(propertyClass) : propertyClass;
    Type boxedType = Type.getType(boxedClass);
    Method setter = weakSetter.getMethod();
    MethodVisitor methodVisitor = declareMethod(visitor, setter.getName(), SET_OBJECT_PROPERTY_DESCRIPTOR, SET_OBJECT_PROPERTY_DESCRIPTOR);
    putThisOnStack(methodVisitor);
    putTypeConverterFieldValueOnStack(methodVisitor, generatedType);
    // Object converted = $typeConverter.convert(foo, Float.class, false);
    // put var #1 ('foo') on the stack
    methodVisitor.visitVarInsn(ALOAD, 1);
    // push the constant Class onto the stack
    methodVisitor.visitLdcInsn(boxedType);
    // push int 1 or 0 (interpreted as true or false) onto the stack
    methodVisitor.visitInsn(propertyClass.isPrimitive() ? ICONST_1 : ICONST_0);
    Label startTry = new Label();
    methodVisitor.visitLabel(startTry);
    methodVisitor.visitMethodInsn(INVOKEINTERFACE, TYPE_CONVERTER_TYPE.getInternalName(), "convert", COERCE_TO_SCALAR_DESCRIPTOR, true);
    Label endTry = new Label();
    methodVisitor.visitLabel(endTry);
    methodVisitor.visitTypeInsn(CHECKCAST, boxedType.getInternalName());
    if (propertyClass.isPrimitive()) {
        unboxType(methodVisitor, propertyClass);
    }
    // invoke the typed setter
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, generatedType.getInternalName(), setter.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, propertyType), false);
    methodVisitor.visitInsn(RETURN);
    // catch(TypeConversionException e) { throw ... }
    Label startCatch = new Label();
    methodVisitor.visitLabel(startCatch);
    methodVisitor.visitTryCatchBlock(startTry, endTry, startCatch, TYPE_CONVERSION_EXCEPTION_TYPE.getInternalName());
    // store thrown exception
    methodVisitor.visitVarInsn(ASTORE, 2);
    putClassOnStack(methodVisitor, viewClass);
    methodVisitor.visitLdcInsn(property.getName());
    putFirstMethodArgumentOnStack(methodVisitor);
    methodVisitor.visitVarInsn(ALOAD, 2);
    methodVisitor.visitMethodInsn(INVOKESTATIC, Type.getInternalName(ManagedProxyClassGenerator.class), "propertyValueConvertFailure", Type.getMethodDescriptor(Type.VOID_TYPE, CLASS_TYPE, STRING_TYPE, OBJECT_TYPE, TYPE_CONVERSION_EXCEPTION_TYPE), false);
    finishVisitingMethod(methodVisitor);
}
Also used : Type(org.objectweb.asm.Type) ModelType(org.gradle.model.internal.type.ModelType) Label(org.objectweb.asm.Label) ScalarValueSchema(org.gradle.model.internal.manage.schema.ScalarValueSchema) Method(java.lang.reflect.Method) WeaklyTypeReferencingMethod(org.gradle.model.internal.method.WeaklyTypeReferencingMethod) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 4 with ScalarValueSchema

use of org.gradle.model.internal.manage.schema.ScalarValueSchema in project gradle by gradle.

the class ModelRuleExtractor method doExtract.

private <T> CachedRuleSource doExtract(final Class<T> source) {
    final ModelType<T> type = ModelType.of(source);
    FormattingValidationProblemCollector problems = new FormattingValidationProblemCollector("rule source", type);
    DefaultMethodModelRuleExtractionContext context = new DefaultMethodModelRuleExtractionContext(this, problems);
    // TODO - exceptions thrown here should point to some extensive documentation on the concept of class rule sources
    StructSchema<T> schema = getSchema(source, context);
    if (schema == null) {
        throw new InvalidModelRuleDeclarationException(problems.format());
    }
    // sort for determinism
    Set<Method> methods = new TreeSet<Method>(Ordering.usingToString());
    methods.addAll(Arrays.asList(source.getDeclaredMethods()));
    ImmutableList.Builder<ModelProperty<?>> implicitInputs = ImmutableList.builder();
    ModelProperty<?> target = null;
    for (ModelProperty<?> property : schema.getProperties()) {
        if (property.isAnnotationPresent(RuleTarget.class)) {
            target = property;
        } else if (property.isAnnotationPresent(RuleInput.class) && !(property.getSchema() instanceof ScalarValueSchema)) {
            implicitInputs.add(property);
        }
        for (WeaklyTypeReferencingMethod<?, ?> method : property.getAccessors()) {
            methods.remove(method.getMethod());
        }
    }
    ImmutableList.Builder<ExtractedRuleDetails> rules = ImmutableList.builder();
    for (Method method : methods) {
        MethodRuleDefinition<?, ?> ruleDefinition = DefaultMethodRuleDefinition.create(source, method);
        ExtractedModelRule rule = getMethodHandler(ruleDefinition, method, context);
        if (rule != null) {
            rules.add(new ExtractedRuleDetails(ruleDefinition, rule));
        }
    }
    if (context.hasProblems()) {
        throw new InvalidModelRuleDeclarationException(problems.format());
    }
    StructBindings<T> bindings = structBindingsStore.getBindings(schema.getType());
    if (schema.getProperties().isEmpty()) {
        return new StatelessRuleSource(rules.build(), Modifier.isAbstract(source.getModifiers()) ? new AbstractRuleSourceFactory<T>(schema, bindings, proxyFactory) : new ConcreteRuleSourceFactory<T>(type));
    } else {
        return new ParameterizedRuleSource(rules.build(), target, implicitInputs.build(), schema, bindings, proxyFactory);
    }
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) Method(java.lang.reflect.Method) WeaklyTypeReferencingMethod(org.gradle.model.internal.method.WeaklyTypeReferencingMethod) TreeSet(java.util.TreeSet) ModelProperty(org.gradle.model.internal.manage.schema.ModelProperty) ScalarValueSchema(org.gradle.model.internal.manage.schema.ScalarValueSchema) InvalidModelRuleDeclarationException(org.gradle.model.InvalidModelRuleDeclarationException)

Aggregations

ScalarValueSchema (org.gradle.model.internal.manage.schema.ScalarValueSchema)4 Method (java.lang.reflect.Method)2 WeaklyTypeReferencingMethod (org.gradle.model.internal.method.WeaklyTypeReferencingMethod)2 MethodVisitor (org.objectweb.asm.MethodVisitor)2 ImmutableList (com.google.common.collect.ImmutableList)1 TreeSet (java.util.TreeSet)1 InvalidModelRuleDeclarationException (org.gradle.model.InvalidModelRuleDeclarationException)1 ModelElementProjection (org.gradle.model.internal.inspect.ModelElementProjection)1 ProjectionOnlyNodeInitializer (org.gradle.model.internal.inspect.ProjectionOnlyNodeInitializer)1 ModelProperty (org.gradle.model.internal.manage.schema.ModelProperty)1 ModelType (org.gradle.model.internal.type.ModelType)1 Label (org.objectweb.asm.Label)1 Type (org.objectweb.asm.Type)1