use of org.gradle.model.internal.method.WeaklyTypeReferencingMethod in project gradle by gradle.
the class DefaultStructBindingsStore method collectMethodBindings.
private static <T> Set<StructMethodBinding> collectMethodBindings(StructBindingExtractionContext<T> extractionContext, Map<String, Multimap<PropertyAccessorType, StructMethodBinding>> propertyBindings) {
Collection<WeaklyTypeReferencingMethod<?, ?>> implementedMethods = collectImplementedMethods(extractionContext.getImplementedSchemas());
Map<Wrapper<Method>, WeaklyTypeReferencingMethod<?, ?>> publicViewImplMethods = collectPublicViewImplMethods(extractionContext.getPublicSchema());
Map<Wrapper<Method>, WeaklyTypeReferencingMethod<?, ?>> delegateMethods = collectDelegateMethods(extractionContext.getDelegateSchema());
ImmutableSet.Builder<StructMethodBinding> methodBindingsBuilder = ImmutableSet.builder();
for (WeaklyTypeReferencingMethod<?, ?> weakImplementedMethod : implementedMethods) {
Method implementedMethod = weakImplementedMethod.getMethod();
PropertyAccessorType accessorType = PropertyAccessorType.of(implementedMethod);
Wrapper<Method> methodKey = SIGNATURE_EQUIVALENCE.wrap(implementedMethod);
WeaklyTypeReferencingMethod<?, ?> weakDelegateImplMethod = delegateMethods.get(methodKey);
WeaklyTypeReferencingMethod<?, ?> weakPublicImplMethod = publicViewImplMethods.get(methodKey);
if (weakDelegateImplMethod != null && weakPublicImplMethod != null) {
extractionContext.add(weakImplementedMethod, String.format("it is both implemented by the view '%s' and the delegate type '%s'", extractionContext.getPublicSchema().getType().getDisplayName(), extractionContext.getDelegateSchema().getType().getDisplayName()));
}
String propertyName = accessorType == null ? null : accessorType.propertyNameFor(implementedMethod);
StructMethodBinding binding;
if (!Modifier.isAbstract(implementedMethod.getModifiers())) {
binding = new DirectMethodBinding(weakImplementedMethod, accessorType);
} else if (weakPublicImplMethod != null) {
binding = new BridgeMethodBinding(weakImplementedMethod, weakPublicImplMethod, accessorType);
} else if (weakDelegateImplMethod != null) {
binding = new DelegateMethodBinding(weakImplementedMethod, weakDelegateImplMethod, accessorType);
} else if (propertyName != null) {
binding = new ManagedPropertyMethodBinding(weakImplementedMethod, propertyName, accessorType);
} else {
handleNoMethodImplementation(extractionContext, weakImplementedMethod);
continue;
}
methodBindingsBuilder.add(binding);
if (accessorType != null) {
Multimap<PropertyAccessorType, StructMethodBinding> accessorBindings = propertyBindings.get(propertyName);
if (accessorBindings == null) {
accessorBindings = ArrayListMultimap.create();
propertyBindings.put(propertyName, accessorBindings);
}
accessorBindings.put(accessorType, binding);
}
}
return methodBindingsBuilder.build();
}
use of org.gradle.model.internal.method.WeaklyTypeReferencingMethod in project gradle by gradle.
the class ManagedProxyClassGenerator method writeGetter.
private void writeGetter(ClassVisitor visitor, Type generatedType, String propertyName, Class<?> propertyClass, WeaklyTypeReferencingMethod<?, ?> weakGetter) {
Method getter = weakGetter.getMethod();
Type propertyType = Type.getType(propertyClass);
MethodVisitor methodVisitor = declareMethod(visitor, getter.getName(), Type.getMethodDescriptor(propertyType), AsmClassGeneratorUtils.signature(getter));
putStateFieldValueOnStack(methodVisitor, generatedType);
putConstantOnStack(methodVisitor, propertyName);
invokeStateGetMethod(methodVisitor);
castFirstStackElement(methodVisitor, propertyClass);
finishVisitingMethod(methodVisitor, returnCode(propertyType));
}
use of org.gradle.model.internal.method.WeaklyTypeReferencingMethod in project gradle by gradle.
the class ManagedProxyClassGenerator method writeSetter.
private void writeSetter(ClassVisitor visitor, Type generatedType, String propertyName, Class<?> propertyClass, WeaklyTypeReferencingMethod<?, ?> weakSetter) {
Type propertyType = Type.getType(propertyClass);
Label calledOutsideOfConstructor = new Label();
Method setter = weakSetter.getMethod();
// the regular typed setter
String methodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, propertyType);
MethodVisitor methodVisitor = declareMethod(visitor, setter.getName(), methodDescriptor, AsmClassGeneratorUtils.signature(setter));
putCanCallSettersFieldValueOnStack(methodVisitor, generatedType);
jumpToLabelIfStackEvaluatesToTrue(methodVisitor, calledOutsideOfConstructor);
throwExceptionBecauseCalledOnItself(methodVisitor);
methodVisitor.visitLabel(calledOutsideOfConstructor);
putStateFieldValueOnStack(methodVisitor, generatedType);
putConstantOnStack(methodVisitor, propertyName);
putFirstMethodArgumentOnStack(methodVisitor, propertyType);
if (propertyClass.isPrimitive()) {
boxType(methodVisitor, propertyClass);
}
invokeStateSetMethod(methodVisitor);
finishVisitingMethod(methodVisitor);
}
use of org.gradle.model.internal.method.WeaklyTypeReferencingMethod 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();
}
}
}
use of org.gradle.model.internal.method.WeaklyTypeReferencingMethod 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);
}
Aggregations