private static <T> void mergeStagedChainInner(List<CtClass<T>> chain) { if (chain.size() == 1) return; reverse(chain); CtClass<T> toMerge = chain.get(0); for (int i = 1; i < chain.size(); i++) { CtClass<T> mergeInto = chain.get(i); replaceInstantiatedTypeParams(toMerge, mergeInto); toMerge .getAnnotations() .stream() .forEach( (CtAnnotation<? extends Annotation> a) -> { if (mergeInto.getAnnotation(a.getActualAnnotation().getClass()) == null) add(mergeInto, a, mergeInto::addAnnotation); }); toMerge.getSuperInterfaces().forEach(mergeInto::addSuperInterface); toMerge .getAnonymousExecutables() .forEach(b -> add(mergeInto, b, mergeInto::addAnonymousExecutable)); toMerge.getNestedTypes().forEach(nt -> add(mergeInto, nt, mergeInto::addNestedType)); toMerge.getFields().forEach(f -> add(mergeInto, f, mergeInto::addField)); for (CtMethod<?> methodToMerge : toMerge.getMethods()) { processMethod(mergeInto, toMerge, methodToMerge); } final CtClass<T> finalToMerge = toMerge; mergeInto.getConstructors().forEach(c -> processConstructor(c, finalToMerge)); mergeInto.setSuperclass(toMerge.getSuperclass()); toMerge = mergeInto; } }
public static CtClass getSuperclass(CtClass c) throws CompileError { try { CtClass sc = c.getSuperclass(); if (sc != null) return sc; } catch (NotFoundException e) { } throw new CompileError("cannot find the super class of " + c.getName()); }
private static <T> void replaceInstantiatedTypeParams(CtClass<T> toMerge, CtClass<T> mergeInto) { List<CtTypeReference<?>> typeArgs = mergeInto.getSuperclass().getActualTypeArguments(); typeArgs .stream() .filter(ta -> !(ta instanceof CtTypeParameterReference)) .forEach( ta -> { int instantiatedParamIndex = typeArgs.indexOf(ta); CtTypeReference<?> instantiatedTypeParam = toMerge.getFormalTypeParameters().get(instantiatedParamIndex); toMerge.accept( new CtScanner() { @Override public void scan(CtReference ref) { if (ref instanceof CtGenericElementReference) { CtGenericElementReference gRef = (CtGenericElementReference) ref; replaceInList(ref.getFactory(), gRef.getActualTypeArguments()); } if (ref instanceof CtTypeParameterReference) { replaceInList( ref.getFactory(), ((CtTypeParameterReference) ref).getBounds()); } super.scan(ref); } @Override public void scan(CtElement element) { if (element instanceof CtTypedElement) { CtTypedElement typed = (CtTypedElement) element; CtTypeReference type = typed.getType(); if (type != null && instantiatedTypeParam.getSimpleName().equals(type.getSimpleName())) { typed.setType(element.getFactory().Core().clone(ta)); } } if (element instanceof CtExpression) { replaceInList( element.getFactory(), ((CtExpression) element).getTypeCasts()); } super.scan(element); } private void replaceInList(Factory f, List<CtTypeReference<?>> types) { for (int i = 0; i < types.size(); i++) { CtTypeReference<?> arg = types.get(i); if (instantiatedTypeParam.getSimpleName().equals(arg.getSimpleName())) { types.set(i, f.Core().clone(ta)); } } } }); }); }
public void testSetSuper() throws Exception { CtClass cc = sloader.makeClass("test2.SetSuper"); CtClass cc2 = sloader.makeClass("test2.SetSuperParent"); CtClass intf = sloader.makeInterface("test2.SetSuperIntf"); CtClass remote = sloader.get("java.rmi.Remote"); cc.setSuperclass(cc2); cc.setInterfaces(new CtClass[] {intf}); intf.setSuperclass(remote); intf.writeFile(); cc2.writeFile(); cc.writeFile(); assertEquals(cc2, cc.getSuperclass()); assertEquals(intf, cc.getInterfaces()[0]); assertEquals(sloader.get("java.lang.Object"), intf.getSuperclass()); assertEquals(remote, intf.getInterfaces()[0]); make(cc.getName()); }
public void onWrite(ClassPool pool, String className) throws NotFoundException, CannotCompileException { CtClass cc = pool.get(className); try { if (isPersistent(className)) { CtClass base = cc.getSuperclass(); CtConstructor cons = new CtConstructor(constructorParams, cc); if (base.subclassOf(persistent) || base == object) { cons.setBody(null); cc.addConstructor(cons); if (base == object) { cc.setSuperclass(persistent); } } else { if (!isPersistent(base.getName())) { throw new NotFoundException( "Base class " + base.getName() + " was not declared as persistent"); } cons.setBody("super($0);"); cc.addConstructor(cons); } preprocessMethods(cc, true, true); if (base == persistent || base == object) { CtMethod m = new CtMethod(isRecursive, cc, null); m.setBody("return false;"); cc.addMethod(m); addSerializeMethods(cc, false); } else if (base.subtypeOf(serializable)) { addSerializeMethods(cc, true); } if ((cc.getModifiers() & Modifier.PRIVATE) == 0) { CtClass f = pool.makeClass(className + "LoadFactory"); f.addInterface(factory); CtMethod c = new CtMethod(create, f, null); c.setBody("return new " + className + "($1);"); f.addMethod(c); CtNewConstructor.defaultConstructor(f); } } else { preprocessMethods( cc, cc.subtypeOf(persistent) && cc != persistent, !className.startsWith("org.nachodb")); } } catch (Exception x) { x.printStackTrace(); } }
private Method lookupMethod( CtClass clazz, String methodName, int[] argTypes, int[] argDims, String[] argClassNames, boolean onlyExact) throws CompileError { Method maybe = null; ClassFile cf = clazz.getClassFile2(); // If the class is an array type, the class file is null. // If so, search the super class java.lang.Object for clone() etc. if (cf != null) { List list = cf.getMethods(); int n = list.size(); for (int i = 0; i < n; ++i) { MethodInfo minfo = (MethodInfo) list.get(i); if (minfo.getName().equals(methodName)) { int res = compareSignature(minfo.getDescriptor(), argTypes, argDims, argClassNames); if (res != NO) { Method r = new Method(clazz, minfo, res); if (res == YES) return r; else if (maybe == null || maybe.notmatch > res) maybe = r; } } } } if (onlyExact) maybe = null; else onlyExact = maybe != null; int mod = clazz.getModifiers(); boolean isIntf = Modifier.isInterface(mod); try { // skip searching java.lang.Object if clazz is an interface type. if (!isIntf) { CtClass pclazz = clazz.getSuperclass(); if (pclazz != null) { Method r = lookupMethod(pclazz, methodName, argTypes, argDims, argClassNames, onlyExact); if (r != null) return r; } } } catch (NotFoundException e) { } if (isIntf || Modifier.isAbstract(mod)) try { CtClass[] ifs = clazz.getInterfaces(); int size = ifs.length; for (int i = 0; i < size; ++i) { Method r = lookupMethod(ifs[i], methodName, argTypes, argDims, argClassNames, onlyExact); if (r != null) return r; } if (isIntf) { // finally search java.lang.Object. CtClass pclazz = clazz.getSuperclass(); if (pclazz != null) { Method r = lookupMethod(pclazz, methodName, argTypes, argDims, argClassNames, onlyExact); if (r != null) return r; } } } catch (NotFoundException e) { } return maybe; }