Package se.arnetheduck.j2c.transform

Source Code of se.arnetheduck.j2c.transform.TypeUtil

package se.arnetheduck.j2c.transform;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;

/** Utilities for traversing the type hierarchy */
public class TypeUtil {
  public static Predicate<Object> named(final String name) {
    return new Predicate<Object>() {
      @Override
      public boolean apply(Object t) {
        if (t instanceof ITypeBinding) {
          ITypeBinding tb = (ITypeBinding) t;
          return tb.getName().equals(name);
        }

        if (t instanceof IMethodBinding) {
          IMethodBinding mb = (IMethodBinding) t;
          return mb.getName().equals(name);
        }

        if (t instanceof IVariableBinding) {
          IVariableBinding vb = (IVariableBinding) t;
          return vb.getName().equals(name);
        }

        return false;
      }
    };
  }

  /** Predicate that returns true for any method that mb overrides */
  public static Predicate<IMethodBinding> overrides(final IMethodBinding mb) {
    return new Predicate<IMethodBinding>() {
      @Override
      public boolean apply(IMethodBinding t) {
        return !mb.isConstructor()
            && mb.getMethodDeclaration().overrides(
                t.getMethodDeclaration());
      }
    };
  }

  /** tb and all bases */
  public static List<ITypeBinding> types(ITypeBinding tb, ITypeBinding object) {
    List<ITypeBinding> ret = new ArrayList<ITypeBinding>();
    ret.add(tb);
    ret.addAll(allBases(tb, object));
    return ret;
  }

  /** Superclasses of tb, including java.lang.Object but not tb itself */
  public static List<ITypeBinding> superClasses(ITypeBinding tb) {
    List<ITypeBinding> ret = new ArrayList<ITypeBinding>();
    superClasses(tb, ret);
    return ret;
  }

  public static void superClasses(ITypeBinding tb, Collection<ITypeBinding> c) {
    ITypeBinding superclass = tb.getSuperclass();
    if (superclass == null) {
      return;
    }

    c.add(superclass);
    superClasses(superclass, c);
  }

  /**
   * The interfaces a particular type implements including recursive
   * superinterfaces (but not the interfaces of any super class)
   */
  public static List<ITypeBinding> interfaces(ITypeBinding tb) {
    List<ITypeBinding> ret = new ArrayList<ITypeBinding>();
    interfaces(tb, ret);
    return ret;
  }

  public static void interfaces(ITypeBinding tb, Collection<ITypeBinding> c) {
    for (ITypeBinding ib : tb.getInterfaces()) {
      c.add(ib);
      interfaces(ib, c);
    }
  }

  /** Union of all methods defined by the supplied types */
  public static List<IMethodBinding> methods(Collection<ITypeBinding> types) {
    return methods(types, null);
  }

  /** Union of all methods defined by the supplied types matching p */
  public static List<IMethodBinding> methods(Collection<ITypeBinding> types,
      Predicate<? super IMethodBinding> predicate) {

    List<IMethodBinding> ret = new ArrayList<IMethodBinding>();
    for (ITypeBinding tb : types) {
      for (IMethodBinding mb : tb.getDeclaredMethods()) {
        if (predicate == null || predicate.apply(mb)) {
          ret.add(mb);
        }
      }
    }

    return ret;
  }

  /** Direct bases (superclass and interfaces) of a type */
  public static List<ITypeBinding> bases(ITypeBinding tb, ITypeBinding object) {
    List<ITypeBinding> ret = new ArrayList<ITypeBinding>();

    if (tb.getSuperclass() != null) {
      ret.add(tb.getSuperclass());
    }

    for (ITypeBinding ib : tb.getInterfaces()) {
      ret.add(ib);
    }

    if (object != null && ret.isEmpty()
        && !TransformUtil.same(tb, Object.class)) {
      ret.add(object);
    }

    return ret;
  }

  public static ITypeBinding commonBase(ITypeBinding tb0, ITypeBinding tb1,
      ITypeBinding object) {
    if (tb0.isEqualTo(tb1)) {
      return tb0;
    }

    if (tb0.isNullType()) {
      return tb1;
    }

    if (tb1.isNullType()) {
      return tb0;
    }

    List<ITypeBinding> b0 = types(tb0, object);
    List<ITypeBinding> b1 = types(tb1, object);
    for (ITypeBinding x0 : b0) {
      for (ITypeBinding x1 : b1) {
        if (x0.isEqualTo(x1)) {
          return x0;
        }
      }
    }

    throw new Error("Huh? Where's Object?");
  }

  /** Recursive bases (superclasses and interfaces) of a type */
  public static List<ITypeBinding> allBases(ITypeBinding tb,
      ITypeBinding object) {
    List<ITypeBinding> ret = new ArrayList<ITypeBinding>();

    List<ITypeBinding> supers = superClasses(tb);
    ret.addAll(supers);
    interfaces(tb, ret);

    for (ITypeBinding b : supers) {
      interfaces(b, ret);
    }

    if (object != null && !TransformUtil.same(tb, Object.class)
        && !ret.contains(object)) {
      ret.add(object);
    }

    return ret;
  }

  public static boolean isClassLike(ITypeBinding type) {
    return type.isClass() || type.isEnum();
  }

  public static int countBases(ITypeBinding type, ITypeBinding base) {
    int ret = 0;

    base = base.getErasure();
    ITypeBinding superclass = type.getSuperclass();
    if (superclass != null) {
      superclass = superclass.getErasure();
      if (superclass.isEqualTo(base)) {
        return 1; // Base is a class, can only appear once
      }

      ret += countBases(superclass, base);
    }

    for (ITypeBinding ib : type.getInterfaces()) {
      ib = ib.getErasure();
      if (ib.isEqualTo(base)) {
        ret += 1;
      }

      ret += countBases(ib, base);
    }

    return ret;
  }

  public static boolean isOverloaded(IMethodBinding b, ITypeBinding object) {
    Collection<IMethodBinding> methods = methods(
        types(b.getDeclaringClass(), object), named(b.getName()));
    if (methods.size() < 2) {
      return false;
    }

    for (IMethodBinding mb : methods) {
      if (!mb.isEqualTo(b)
          && mb.getParameterTypes().length == b.getParameterTypes().length) {
        return true;
      }
    }

    return false;
  }
}
TOP

Related Classes of se.arnetheduck.j2c.transform.TypeUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.