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);
}
}
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;
}
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);
}
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);
}
}
Aggregations