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}