001package daikon.chicory;
002
003import java.lang.reflect.Constructor;
004import java.lang.reflect.Method;
005import java.lang.reflect.Modifier;
006import java.util.Arrays;
007
008/**
009 * This is a subtype of DaikonVariableInfo and is used as a "placeholder" for the root of the tree.
010 * It contains no variable information other than what is stored in its children.
011 */
012@SuppressWarnings("nullness") // to do
013public class RootInfo extends DaikonVariableInfo {
014  private RootInfo() {
015    // the root needs no name, etc. but set them to preserve nullness property
016    super(" RootInfo Object ", " RootInfo Object type ", " RootInfo Object reptype ");
017  }
018
019  @Override
020  public Object getMyValFromParentVal(Object value) {
021    throw new RuntimeException("No val for RootInfo");
022  }
023
024  /** Creates a RootInfo object for a method entry program point. */
025  public static RootInfo enter_process(MethodInfo mi, int depth) {
026    // debug_vars.clear("Building enter tree for %s:%s%n", mi.method_name, mi);
027
028    RootInfo root = new RootInfo();
029
030    // Don't build a tree for class initializers.
031    if (mi.is_class_initializer()) {
032      return root;
033    }
034
035    // Clear the set of static variables
036    ppt_statics.clear();
037
038    // Print class variables.   Print class variables first because
039    // the depth goes deeper there ('this' is not counted).  This
040    // guarantees that any static variables in the class are found here
041    // and not below.
042    if (!(mi.member instanceof Constructor<?>)) {
043      root.addClassVars(
044          mi.class_info,
045          Modifier.isStatic(mi.member.getModifiers()),
046          mi.member.getDeclaringClass(),
047          /* offset= */ "",
048          depth);
049    }
050
051    // Print each parameter
052    root.addParameters(mi.class_info, mi.member, Arrays.<String>asList(mi.arg_names), depth);
053
054    // debug_vars.log("exit enter_process%n");
055
056    return root;
057  }
058
059  /** Creates a RootInfo object for a method exit program point. */
060  public static RootInfo exit_process(MethodInfo mi, int depth) {
061    // debug_vars.clear("Building exit tree for %s%n", mi);
062
063    RootInfo root = new RootInfo();
064
065    // Don't build a tree for class initializers.
066    if (mi.is_class_initializer()) {
067      return root;
068    }
069
070    // Clear the set of static variables
071    ppt_statics.clear();
072
073    // Print class variables.   Print class variables first because
074    // the depth goes deeper there ('this' is not counted).  This
075    // guarantees that any static variables in the class are found here
076    // and not below.
077    root.addClassVars(
078        mi.class_info,
079        Modifier.isStatic(mi.member.getModifiers()),
080        mi.member.getDeclaringClass(),
081        "",
082        depth);
083
084    // Print arguments
085    root.addParameters(mi.class_info, mi.member, Arrays.<String>asList(mi.arg_names), depth);
086
087    // Print return type information for methods only and not constructors
088    if (mi.member instanceof Method) {
089      Class<?> returnType = ((Method) mi.member).getReturnType();
090      if (!returnType.equals(Void.TYPE)) {
091        // add a new ReturnInfo object to the traversal tree
092        DaikonVariableInfo retInfo = new ReturnInfo(returnType);
093
094        root.addChild(retInfo);
095
096        retInfo.checkForDerivedVariables(returnType, "return", "");
097
098        retInfo.addChildNodes(mi.class_info, returnType, "return", "", depth);
099      }
100    }
101
102    // debug_vars.log("exit exit_process%n");
103
104    return root;
105  }
106
107  /**
108   * Creates a new RootInfo object for an object program point. This will include the class' fields
109   * and the "this" object.
110   *
111   * @param cinfo information about the class
112   * @param depth the depth to which to nest variables, as in "a.b.field"
113   * @return a a new RootInfo object for an object program point
114   */
115  public static RootInfo getObjectPpt(ClassInfo cinfo, int depth) {
116    // debug_vars.clear("enter getObjectPpt: %s%n", cinfo);
117
118    RootInfo root = new RootInfo();
119
120    // Clear the set of static variables
121    ppt_statics.clear();
122
123    root.addClassVars(
124        cinfo, /* dontPrintInstanceVars= */ false, cinfo.clazz, /* offset= */ "", depth);
125
126    // debug_vars.log("exit getObjectPpt%n");
127
128    return root;
129  }
130
131  /**
132   * Creates a new RootInfo object for a class program point. This will just include static fields.
133   *
134   * @param cinfo information about the class
135   * @param depth the depth to which to nest variables, as in "a.b.field"
136   * @return a new RootInfo object for a class program point
137   */
138  public static RootInfo getClassPpt(ClassInfo cinfo, int depth) {
139    // debug_vars.clear("enter getClassPpt: %s%n", cinfo);
140
141    RootInfo root = new RootInfo();
142
143    // Clear the set of static variables
144    ppt_statics.clear();
145
146    root.addClassVars(
147        cinfo, /* dontPrintInstanceVars= */ true, cinfo.clazz, /* offset= */ "", depth);
148
149    // debug_vars.log("exit getClassPpt%n");
150
151    return root;
152  }
153
154  @Override
155  public VarKind get_var_kind() {
156    throw new RuntimeException("No var-kind for RootInfo");
157  }
158}