001/* 002 * Created on May 3, 2005 003 * 004 */ 005package daikon.chicory; 006 007import java.lang.reflect.InvocationTargetException; 008import java.lang.reflect.Method; 009import java.util.List; 010 011/** 012 * The ListInfo class is a subtype of DaikonVariableInfo used for variable types that implement 013 * {@code java.util.List}. 014 */ 015public class ListInfo extends DaikonVariableInfo { 016 017 private Class<? extends List<?>> listType; 018 019 public ListInfo(String theName, Class<? extends List<?>> theType) { 020 super(theName, theType.getName(), "hashcode[]", true); 021 listType = theType; 022 } 023 024 // use the "toArray" method to get an array 025 // convert the array to a List 026 @Override 027 public Object getMyValFromParentVal(Object value) { 028 029 Method arrayMethod; 030 try { 031 arrayMethod = listType.getMethod("toArray", new Class<?>[0]); 032 } catch (NoSuchMethodException e) { 033 throw new Error( 034 listType.getName() 035 + " seems to implement java.util.List, but method toArray() not found"); 036 } 037 038 Object arrayVal; 039 040 if (value != null && !(value instanceof NonsensicalObject)) { 041 042 // TODO why can't we just cast to List and call toArray directly? 043 044 try { 045 arrayVal = arrayMethod.invoke(value, new Object[0]); 046 } catch (IllegalArgumentException e1) { 047 throw new Error(e1); 048 } catch (IllegalAccessException e1) { 049 throw new Error(e1); 050 } catch (InvocationTargetException e1) { 051 // We used to check for java.util.ConcurrentModificationException, but 052 // now beleive than any InvocationTargetException should not fail and 053 // thus should return Nonsensical. 054 // Possibly, this should be extended to all exceptions. 055 System.err.println( 056 "Detected a InvocationTargetException in: " + listType.getName() + " " + getName()); 057 arrayVal = NonsensicalObject.getInstance(); 058 } 059 } else { 060 arrayVal = NonsensicalObject.getInstance(); 061 } 062 063 @SuppressWarnings("nullness") // We just verified (or set) arrayVal in code above. 064 Object tmp = DTraceWriter.getListFromArray(arrayVal); 065 return tmp; 066 } 067 068 /** Lists are arrays from Daikon's point of view. */ 069 @Override 070 public VarKind get_var_kind() { 071 return VarKind.ARRAY; 072 } 073}