Exemplo n.º 1
0
  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));
                        }
                      }
                    }
                  });
            });
  }