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