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;
   }
 }
Beispiel #2
0
 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));
                        }
                      }
                    }
                  });
            });
  }
Beispiel #4
0
  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());
  }
Beispiel #5
0
 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();
   }
 }
Beispiel #6
0
  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;
  }