@Override public Collection<MetaClass> provideTypesToExpose() { final Set<MetaClass> types = new HashSet<MetaClass>(); for (final MetaClass metaClass : ClassScanner.getTypesAnnotatedWith(Remote.class)) { for (final MetaMethod method : metaClass.getDeclaredMethods()) { if (!method.getReturnType().isVoid()) { types.add(method.getReturnType().getErased()); } for (final MetaParameter parameter : method.getParameters()) { final MetaClass type = parameter.getType(); types.add(type.getErased()); final MetaParameterizedType parameterizedType = type.getParameterizedType(); if (parameterizedType != null) { for (final MetaType tp : parameterizedType.getTypeParameters()) { if (tp instanceof MetaClass) { types.add(((MetaClass) tp).getErased()); } } } } } } return types; } }
private MetaClass getConstraintType(final MetaClass validator, final MetaClass constraintValidatorIface) { final MetaType annoTypeVariable = constraintValidatorIface.getParameterizedType().getTypeParameters()[0]; if (!(annoTypeVariable instanceof MetaClass)) { throw new RuntimeException("Cannot determine constraint type for " + validator.getFullyQualifiedName()); } final MetaClass annoType = (MetaClass) annoTypeVariable; return annoType; }
private MetaClass getValueType(final MetaClass validator, final MetaClass constraintValidatorIface) { final MetaType valueTypeVariable = constraintValidatorIface.getParameterizedType().getTypeParameters()[1]; if (!(valueTypeVariable instanceof MetaClass)) { throw new RuntimeException("Cannot determine validated type of " + validator.getFullyQualifiedName()); } final MetaClass valueType = (MetaClass) valueTypeVariable; return valueType; }
private static MetaType[] getTypeArgumentsForInterface(final Map<String, MetaType> typeArgsByTypeParam, final MetaClass iface) { return Arrays .stream(Optional.ofNullable(iface.getParameterizedType()) .map(i -> i.getTypeParameters()) .orElseGet(() -> iface.getTypeParameters())) .map(mt -> { if (typeArgsByTypeParam.containsKey(mt.getName())) { return typeArgsByTypeParam.get(mt.getName()); } else { return mt; } }).toArray(size -> new MetaType[size]); }
private static MetaType[] getTypeArgumentsForInterface(final Map<String, MetaType> typeArgsByTypeParam, final MetaClass iface) { return Arrays .stream(Optional.ofNullable(iface.getParameterizedType()) .map(i -> i.getTypeParameters()) .orElseGet(() -> iface.getTypeParameters())) .map(mt -> { if (typeArgsByTypeParam.containsKey(mt.getName())) { return typeArgsByTypeParam.get(mt.getName()); } else { return mt; } }).toArray(size -> new MetaType[size]); }
protected MetaClass[] getTypeArguments(final MetaClass type) { final MetaParameterizedType pType = type.getParameterizedType(); final MetaType[] typeArgs = (pType != null ? pType.getTypeParameters() : new MetaType[0]); final MetaClass[] typeArgsClasses = new MetaClass[typeArgs.length]; for (int i = 0; i < typeArgs.length; i++) { final MetaType argType = typeArgs[i]; if (argType instanceof MetaClass) { typeArgsClasses[i] = (MetaClass) argType; } else if (argType instanceof MetaParameterizedType) { typeArgsClasses[i] = (MetaClass) ((MetaParameterizedType) argType).getRawType(); } } return typeArgsClasses; }
private static Optional<MetaClass> getMetaClassFromGeneric(final MetaType genericType) { if (genericType instanceof MetaClass) { return Optional.of((MetaClass) genericType); } else if (genericType instanceof MetaParameterizedType && ((MetaParameterizedType) genericType).getRawType() instanceof MetaClass) { final MetaParameterizedType mpt = (MetaParameterizedType) genericType; @SuppressWarnings({ "unchecked", "rawtypes" }) final MetaType[] typeArgs = Arrays .stream(mpt.getTypeParameters()) .map(arg -> ((Optional<MetaType>) (Optional) getMetaClassFromGeneric(arg)).orElse(arg)) .toArray(MetaType[]::new); return Optional.of(parameterizedAs((MetaClass) mpt.getRawType(), typeParametersOf(typeArgs))); } else { return Optional.empty(); } }
private static void addInterfaces(final MetaClass clazz, final BuildMetaClass buildMetaClass, final MetaParameterizedType parameterizedType) { final MetaType[] typeParams = (clazz.getParameterizedType() != null ? clazz.getParameterizedType().getTypeParameters() : clazz.getTypeParameters()); final MetaType[] typeArgs = parameterizedType.getTypeParameters(); validateTypeArgumentsAgainstParameters(clazz, typeParams, typeArgs); final Map<String, MetaType> typeArgsByTypeParam = mapTypeArgsByTypeParamName(typeParams, typeArgs); final List<MetaClass> ifaces = Arrays .stream(clazz.getInterfaces()) .map(iface -> getParameterizedInterface(typeArgsByTypeParam, iface)) .collect(Collectors.toList()); buildMetaClass.setInterfaces(ifaces); }
private static void addInterfaces(final MetaClass clazz, final BuildMetaClass buildMetaClass, final MetaParameterizedType parameterizedType) { final MetaType[] typeParams = (clazz.getParameterizedType() != null ? clazz.getParameterizedType().getTypeParameters() : clazz.getTypeParameters()); final MetaType[] typeArgs = parameterizedType.getTypeParameters(); validateTypeArgumentsAgainstParameters(clazz, typeParams, typeArgs); final Map<String, MetaType> typeArgsByTypeParam = mapTypeArgsByTypeParamName(typeParams, typeArgs); final List<MetaClass> ifaces = Arrays .stream(clazz.getInterfaces()) .map(iface -> getParameterizedInterface(typeArgsByTypeParam, iface)) .collect(Collectors.toList()); buildMetaClass.setInterfaces(ifaces); }
private static MetaClass getConcreteTypeParameter(final MetaClass toType, final int typeParamIndex, final int typeParamsSize) { if (toType.getParameterizedType() != null) { final MetaType[] typeParms = toType.getParameterizedType().getTypeParameters(); if (typeParms != null && typeParms.length == typeParamsSize) { MetaClass typeParameter = null; if (typeParms[typeParamIndex] instanceof MetaParameterizedType) { final MetaParameterizedType parameterizedTypeParemeter = (MetaParameterizedType) typeParms[typeParamIndex]; typeParameter = (MetaClass) parameterizedTypeParemeter.getRawType(); } else if (typeParms[typeParamIndex] instanceof MetaClass) { typeParameter = (MetaClass) typeParms[typeParamIndex]; } return typeParameter; } } return null; }
private static MetaClass getTypeVariableValue(final MetaTypeVariable typeVariable, final MetaClass clazz) { int idx = -1; final MetaTypeVariable[] typeVariables = clazz.getTypeParameters(); for (int i = 0; i < typeVariables.length; i++) { if (typeVariables[i].getName().equals(typeVariable.getName())) { idx = i; break; } } if (idx != -1) { final MetaType type = clazz.getParameterizedType().getTypeParameters()[idx]; if (type instanceof MetaClass) { return (MetaClass) type; } } return null; }
private static MetaClass getConcreteTypeParameter(final MetaClass toType, final int typeParamIndex, final int typeParamsSize) { if (toType.getParameterizedType() != null) { final MetaType[] typeParms = toType.getParameterizedType().getTypeParameters(); if (typeParms != null && typeParms.length == typeParamsSize) { MetaClass typeParameter = null; if (typeParms[typeParamIndex] instanceof MetaParameterizedType) { final MetaParameterizedType parameterizedTypeParemeter = (MetaParameterizedType) typeParms[typeParamIndex]; typeParameter = (MetaClass) parameterizedTypeParemeter.getRawType(); } else if (typeParms[typeParamIndex] instanceof MetaClass) { typeParameter = (MetaClass) typeParms[typeParamIndex]; } return typeParameter; } } return null; }
private static MetaClass getTypeVariableValue(final MetaTypeVariable typeVariable, final MetaClass clazz) { int idx = -1; final MetaTypeVariable[] typeVariables = clazz.getTypeParameters(); for (int i = 0; i < typeVariables.length; i++) { if (typeVariables[i].getName().equals(typeVariable.getName())) { idx = i; break; } } if (idx != -1) { final MetaType type = clazz.getParameterizedType().getTypeParameters()[idx]; if (type instanceof MetaClass) { return (MetaClass) type; } } return null; }
@Override public MetaClass getSuperClass() { if (_superClass != null) return _superClass; if (getGenericSuperClass() != null) { _superClass = parameterizedAs(getEnclosedMetaObject().getSuperclass(), typeParametersOf(getGenericSuperClass() .getTypeParameters())); } else { _superClass = newInstance(getEnclosedMetaObject().getSuperclass()); } return _superClass; }
private Variable createForEachLoopVar(Statement collection, String loopVarName, MetaClass providedLoopVarType, Context context) { // infer the loop variable type MetaClass loopVarType = MetaClassFactory.get(Object.class); final MetaParameterizedType parameterizedType = collection.getType().getParameterizedType(); if (parameterizedType != null && parameterizedType.getTypeParameters().length != 0 && parameterizedType.getTypeParameters()[0] instanceof MetaClass) { loopVarType = (MetaClass) parameterizedType.getTypeParameters()[0]; } else if (collection.getType().getComponentType() != null) { loopVarType = collection.getType().getComponentType(); } // try to use the provided loop variable type if possible (assignable from the inferred type) if (providedLoopVarType != null) { GenUtil.assertAssignableTypes(context, loopVarType, providedLoopVarType); loopVarType = providedLoopVarType; } final Variable loopVar = Variable.create(loopVarName, loopVarType); context.addVariable(loopVar); return loopVar; }
@Override public MetaClass getSuperClass() { if (_superClass != null) return _superClass; if (getGenericSuperClass() != null) { _superClass = parameterizedAs(getEnclosedMetaObject().getSuperclass(), typeParametersOf(getGenericSuperClass() .getTypeParameters())); } else { _superClass = newInstance(getEnclosedMetaObject().getSuperclass()); } return _superClass; }
private void validateExistingRolesPresent(final Collection<MetaClass> pages, final Multimap<Class<?>, MetaClass> pageRoles) { for (final MetaClass page : pages) { for (final MetaField field : getAllFields(page)) { if (field.getType().getErased().equals(MetaClassFactory.get(TransitionToRole.class))) { final MetaType uniquePageRole = field.getType().getParameterizedType().getTypeParameters()[0]; try { getPageWithRole(uniquePageRole, pageRoles); } catch (IllegalStateException e) { // give a more descriptive error message. throw new GenerationException("No @Page with the UniquePageRole " + uniquePageRole.getName() + " exists to satisfy TransitionToRole<" + uniquePageRole.getName() + "> in " + page.getFullyQualifiedName() + "." + "\nThere must be exactly 1 @Page with this role.", e); } } } } }
@Test public void testMethodReturnTypeWithUpperBoundedWildcardParameter() { final MetaClass c = getMetaClass(ClassWithGenericMethods.class); final MetaMethod method = c.getMethod("methodReturningUpperBoundedWildcardCollection", new Class[] {}); // TODO (ERRAI-459) decide whether it's correct to have the type param present or not // then adjust this assertion to strict equality rather than startsWith() assertTrue(method.getReturnType().getFullyQualifiedNameWithTypeParms().startsWith("java.util.Collection")); final MetaType genericReturnType = method.getGenericReturnType(); assertNotNull(genericReturnType); assertTrue("Got unexpected return type type " + genericReturnType.getClass(), genericReturnType instanceof MetaParameterizedType); final MetaParameterizedType mpReturnType = (MetaParameterizedType) genericReturnType; assertEquals(1, mpReturnType.getTypeParameters().length); // Sole type parameter should be <? extends String> assertTrue(mpReturnType.getTypeParameters()[0] instanceof MetaWildcardType); final MetaWildcardType typeParam = (MetaWildcardType) mpReturnType.getTypeParameters()[0]; assertArrayEquals(new MetaType[] {}, typeParam.getLowerBounds()); assertArrayEquals(new MetaType[] { getMetaClass(String.class) }, typeParam.getUpperBounds()); }
@Test public void testFieldWithStringTypeParam() throws Exception { final MetaClass metaClass = getMetaClass(ClassWithGenericCollections.class); final MetaField field = metaClass.getDeclaredField("hasStringParam"); assertNotNull(field); assertEquals("Collection", field.getType().getName()); assertEquals("java.util.Collection", field.getType().getFullyQualifiedName()); assertEquals("<java.lang.String>", field.getType().getParameterizedType().toString()); assertEquals("java.util.Collection<java.lang.String>", field.getType().getFullyQualifiedNameWithTypeParms()); assertEquals("java.util.Collection", field.getType().getErased().getFullyQualifiedNameWithTypeParms()); assertEquals( Arrays.asList(getMetaClass(String.class)), Arrays.asList(field.getType().getParameterizedType().getTypeParameters())); }
@Test public void testFieldWithUnboundedTypeVarParam() throws Exception { final MetaClass metaClass = getMetaClass(ClassWithGenericCollections.class); final MetaField field = metaClass.getDeclaredField("hasUnboundedTypeVarFromClass"); assertNotNull(field); assertEquals("Collection", field.getType().getName()); assertEquals("java.util.Collection", field.getType().getFullyQualifiedName()); assertEquals("java.util.Collection<T>", field.getType().getParameterizedType().getName()); assertEquals("java.util.Collection<T>", field.getType().getFullyQualifiedNameWithTypeParms()); assertEquals("java.util.Collection", field.getType().getErased().getFullyQualifiedNameWithTypeParms()); assertEquals(1, field.getType().getParameterizedType().getTypeParameters().length); final MetaTypeVariable typeVar = (MetaTypeVariable) field.getType().getParameterizedType().getTypeParameters()[0]; assertEquals("T", typeVar.getName()); assertEquals("Should have no upper bound", Arrays.asList(getMetaClass(Object.class)), Arrays.asList(typeVar.getBounds())); }