public static ClassNode configureTypeVariableReference(String name) { ClassNode cn = ClassHelper.makeWithoutCaching(name); cn.setGenericsPlaceHolder(true); ClassNode cn2 = ClassHelper.makeWithoutCaching(name); cn2.setGenericsPlaceHolder(true); GenericsType[] gts = new GenericsType[] {new GenericsType(cn2)}; cn.setGenericsTypes(gts); cn.setRedirect(ClassHelper.OBJECT_TYPE); return cn; }
private ClassNode configureTypeVariableReference(TypeVariable tv) { ClassNode cn = ClassHelper.makeWithoutCaching(tv.getName()); cn.setGenericsPlaceHolder(true); ClassNode cn2 = ClassHelper.makeWithoutCaching(tv.getName()); cn2.setGenericsPlaceHolder(true); GenericsType[] gts = new GenericsType[] {new GenericsType(cn2)}; cn.setGenericsTypes(gts); cn.setRedirect(ClassHelper.OBJECT_TYPE); return cn; }
private ClassNode createInnerHelperClass( ClassNode buildee, String builderClassName, int fieldsSize) { final String fullName = buildee.getName() + "$" + builderClassName; ClassNode builder = new InnerClassNode(buildee, fullName, PUBLIC_STATIC, OBJECT_TYPE); GenericsType[] gtypes = new GenericsType[fieldsSize]; for (int i = 0; i < gtypes.length; i++) { gtypes[i] = makePlaceholder(i); } builder.setGenericsTypes(gtypes); return builder; }
/** * Interface class nodes retrieved from {@link org.codehaus.groovy.ast.ClassNode#getInterfaces()} * or {@link org.codehaus.groovy.ast.ClassNode#getAllInterfaces()} are returned with generic type * arguments. This method allows returning a parameterized interface given the parameterized class * node which implements this interface. * * @param hint the class node where generics types are parameterized * @param target the interface we want to parameterize generics types * @return a parameterized interface class node */ public static ClassNode parameterizeType(final ClassNode hint, final ClassNode target) { ClassNode interfaceFromClassNode = null; if (hint.equals(target)) interfaceFromClassNode = hint; if (ClassHelper.OBJECT_TYPE.equals(target) && target.isUsingGenerics() && target.getGenericsTypes() != null && target.getGenericsTypes()[0].isPlaceholder()) { // Object<T> return ClassHelper.getWrapper(hint); } if (interfaceFromClassNode == null) { ClassNode[] interfaces = hint.getInterfaces(); for (ClassNode node : interfaces) { if (node.equals(target)) { interfaceFromClassNode = node; break; } else if (node.implementsInterface(target)) { // ex: classNode = LinkedList<A> , node=List<E> , anInterface = Iterable<T> return parameterizeType(parameterizeType(hint, node), target); } } } if (interfaceFromClassNode == null && hint.getUnresolvedSuperClass() != null) { return parameterizeType(hint.getUnresolvedSuperClass(), target); } if (interfaceFromClassNode == null) { // return target; interfaceFromClassNode = hint; } Map<String, GenericsType> parameters = new HashMap<String, GenericsType>(); extractPlaceholders(hint, parameters); ClassNode node = target.getPlainNodeReference(); GenericsType[] interfaceGTs = interfaceFromClassNode.getGenericsTypes(); if (interfaceGTs == null) return target; GenericsType[] types = new GenericsType[interfaceGTs.length]; for (int i = 0; i < interfaceGTs.length; i++) { GenericsType interfaceGT = interfaceGTs[i]; types[i] = interfaceGT; if (interfaceGT.isPlaceholder()) { String name = interfaceGT.getName(); if (parameters.containsKey(name)) { types[i] = parameters.get(name); } } } node.setGenericsTypes(types); return node; }
public static ClassNode nonGeneric(ClassNode type) { if (type.isUsingGenerics()) { final ClassNode nonGen = ClassHelper.makeWithoutCaching(type.getName()); nonGen.setRedirect(type); nonGen.setGenericsTypes(null); nonGen.setUsingGenerics(false); return nonGen; } if (type.isArray()) { final ClassNode nonGen = ClassHelper.makeWithoutCaching(Object.class); nonGen.setUsingGenerics(false); return nonGen.makeArray(); } return type.getPlainNodeReference(); }
private ClassNode configureWildcardType(WildcardType wildcardType) { ClassNode base = ClassHelper.makeWithoutCaching("?"); base.setRedirect(ClassHelper.OBJECT_TYPE); // TODO: more than one lower bound for wildcards? ClassNode[] lowers = configureTypes(wildcardType.getLowerBounds()); ClassNode lower = null; // TODO: is it safe to remove this? What was the original intention? if (lower != null) lower = lowers[0]; ClassNode[] upper = configureTypes(wildcardType.getUpperBounds()); GenericsType t = new GenericsType(base, upper, lower); t.setWildcard(true); ClassNode ref = ClassHelper.makeWithoutCaching(Object.class, false); ref.setGenericsTypes(new GenericsType[] {t}); return ref; }
public ClassNode parameterizedType(ClassNode baseType, ClassNode... genericsTypeArguments) { ClassNode result = baseType.getPlainNodeReference(); if (result.isUsingGenerics()) { GenericsType[] gts = new GenericsType[genericsTypeArguments.length]; int expectedLength = result.getGenericsTypes().length; if (expectedLength != genericsTypeArguments.length) { throw new GroovyBugError( "Expected number of generic type arguments for " + baseType.toString(false) + " is " + expectedLength + " but you gave " + genericsTypeArguments.length); } for (int i = 0; i < gts.length; i++) { gts[i] = new GenericsType(genericsTypeArguments[i]); } result.setGenericsTypes(gts); } return result; }
private void setGenericsTypes(ClassNode cn) { TypeVariable[] tvs = cn.getTypeClass().getTypeParameters(); GenericsType[] gts = configureTypeVariable(tvs); cn.setGenericsTypes(gts); }
private ClassNode configureParameterizedType(ParameterizedType parameterizedType) { ClassNode base = configureType(parameterizedType.getRawType()); GenericsType[] gts = configureTypeArguments(parameterizedType.getActualTypeArguments()); base.setGenericsTypes(gts); return base; }
public static void apply(ClassNode declaringClass) { injectInterface(declaringClass, MYBATIS_CONTRIBUTION_HANDLER_CNODE); // add field: // protected MybatisProvider this$MybatisProvider = DefaultMybatisProvider.instance FieldNode providerField = declaringClass.addField( MYBATIS_PROVIDER_FIELD_NAME, ACC_PRIVATE | ACC_SYNTHETIC, MYBATIS_PROVIDER_CNODE, defaultMybatisProviderInstance()); // add method: // MybatisProvider getMybatisProvider() { // return this$MybatisProvider // } injectMethod( declaringClass, new MethodNode( METHOD_GET_MYBATIS_PROVIDER, ACC_PUBLIC, MYBATIS_PROVIDER_CNODE, Parameter.EMPTY_ARRAY, NO_EXCEPTIONS, returns(field(providerField)))); // add method: // void setMybatisProvider(MybatisProvider provider) { // this$MybatisProvider = provider ?: DefaultMybatisProvider.instance // } injectMethod( declaringClass, new MethodNode( METHOD_SET_MYBATIS_PROVIDER, ACC_PUBLIC, ClassHelper.VOID_TYPE, params(param(MYBATIS_PROVIDER_CNODE, PROVIDER)), NO_EXCEPTIONS, block( ifs_no_return( cmp(var(PROVIDER), ConstantExpression.NULL), assigns(field(providerField), defaultMybatisProviderInstance()), assigns(field(providerField), var(PROVIDER)))))); for (MethodNode method : MYBATIS_CONTRIBUTION_HANDLER_CNODE.getMethods()) { if (Arrays.binarySearch(DELEGATING_METHODS, method.getName()) < 0) continue; List<Expression> variables = new ArrayList<Expression>(); Parameter[] parameters = new Parameter[method.getParameters().length]; for (int i = 0; i < method.getParameters().length; i++) { Parameter p = method.getParameters()[i]; parameters[i] = new Parameter(makeClassSafe(p.getType()), p.getName()); parameters[i].getType().setGenericsTypes(p.getType().getGenericsTypes()); variables.add(var(p.getName())); } ClassNode returnType = makeClassSafe(method.getReturnType()); returnType.setGenericsTypes(method.getReturnType().getGenericsTypes()); returnType.setGenericsPlaceHolder(method.getReturnType().isGenericsPlaceHolder()); MethodNode newMethod = new MethodNode( method.getName(), ACC_PUBLIC, returnType, parameters, NO_EXCEPTIONS, returns(call(field(providerField), method.getName(), args(variables)))); newMethod.setGenericsTypes(method.getGenericsTypes()); injectMethod(declaringClass, newMethod); } }