001 /* Copyright 2000, 2001, Compaq Computer Corporation */ 002 003 package javafe; 004 005 006 import javafe.ast.*; 007 import javafe.tc.*; 008 009 import javafe.util.*; 010 011 012 /** 013 * <code>TestTool</code> is an test class for <code>SrcTool</code> and 014 * its superclasses. <p> 015 * 016 * It just loads in files unless <code>-superclasses</code> is 017 * supplied, in which case it chases down each classes' superclass 018 * chain.<p> 019 * 020 * Note: because this class is intended as a test class routine, the 021 * code for chasing superclass pointers is kludgey and does not always 022 * work correctly. 023 */ 024 025 public class TestTool extends SrcTool { 026 027 /*************************************************** 028 * * 029 * Generating a usage message: * 030 * * 031 **************************************************/ 032 033 /** 034 * Return the name of this tool. E.g., "ls" or "cp".<p> 035 * 036 * Used in usage and error messages.<p> 037 */ 038 public String name() { return "TestTool"; } 039 040 public javafe.Options makeOptions() { return new Options(); } 041 042 public final Options options() { return (Options)options; } 043 044 public class Options extends SrcToolOptions { 045 /** 046 * Print option information to <code>System.err</code>. Each 047 * printed line should be preceeded by two blank spaces. <p> 048 * 049 * Each overriding method should first call 050 * <code>super.showOptions()</code>.<p> 051 */ 052 public String showOptions(boolean all) { 053 return super.showOptions(all) + (" -superclasses") + eol; 054 } 055 056 057 /*************************************************** 058 * * 059 * Option processing: * 060 * * 061 **************************************************/ 062 063 /** 064 * Should we chase superclass pointers? Defaults to no, set by 065 * <code>-superclasses</code>. 066 */ 067 public boolean chaseSuperclasses = false; 068 069 070 /** 071 * Process next tool option. <p> 072 * 073 * See <code>Tool.processOption</code> for the complete 074 * specification of this routine.<p> 075 * 076 * This routine handles the <code>-superclasses</code> option.<p> 077 */ 078 public int processOption(String option, String[] args, int offset) 079 throws UsageError { 080 if (option.equals("-superclasses")) { 081 chaseSuperclasses = true; 082 return offset; 083 } 084 085 // Pass on unrecognized options: 086 return super.processOption(option, args, offset); 087 } 088 089 } 090 091 092 /*************************************************** 093 * * 094 * Main processing code: * 095 * * 096 **************************************************/ 097 098 /** 099 * Start up an instance of this tool using command-line arguments 100 * <code>args</code>. <p> 101 * 102 * <b>Note</b>: this code needs to be copied verbatim to each 103 * subclass of <code>Tool</code> except with the name of the actual 104 * subclass inserted after the new operator.<p> 105 * 106 * (This needs to be done because static methods cannot be 107 * inherited.)<p> 108 */ 109 //@ requires \nonnullelements(args); 110 public static void main(String[] args) { 111 Tool t = new TestTool(); 112 int result = t.run(args); 113 if (result != 0) System.exit(result); 114 } 115 116 117 /*************************************************** 118 * * 119 * SrcTool-instance specific processing: * 120 * * 121 **************************************************/ 122 123 /** 124 * This method is called on the TypeDecl of each 125 * outside type that SrcTool is to process. <p> 126 */ 127 public void handleTD(TypeDecl td) { 128 Info.out("[processing " 129 + TypeSig.getSig(td).getExternalName()); 130 131 if (!options().chaseSuperclasses) 132 return; 133 134 TypeSig current = TypeSig.getSig(td); 135 while (current != null) { 136 Info.out(" At " + current.getExternalName()); 137 138 current = getSuperClass(current.getTypeDecl()); 139 } 140 141 Info.out("]"); 142 } 143 144 145 /** 146 * Attempt to fetch the <code>TypeSig</code> for a given 147 * <code>TypeDecl</code>. <p> 148 * 149 * Returns null if none exists.<p> 150 */ 151 public TypeSig getSuperClass(TypeDecl td) { 152 // If td is not a class, then it has no superclass: 153 if (!(td instanceof ClassDecl)) 154 return null; 155 ClassDecl cd = (ClassDecl)td; 156 157 // Get td's superclass name: 158 TypeSig root = Types.javaLangObject(); 159 if (TypeSig.getSig(td) == root) 160 return null; 161 if (cd.superClass == null) { 162 Info.out(" extended by java.lang.Object"); 163 return root; 164 } 165 166 Name superClassName = cd.superClass.name; 167 Info.out(" extended by " + superClassName.printName()); 168 169 int sz = superClassName.size(); 170 String[] P = superClassName.toStrings(sz-1); 171 String T = superClassName.identifierAt(sz-1).toString(); 172 173 if (sz == 1) { 174 // Simple name -- assume for now in same package: 175 // This is a bit of a hack: 176 TypeSig sig = TypeSig.getSig(td); 177 P = sig.packageName; 178 } 179 180 TypeSig S = OutsideEnv.lookup(P, T); 181 if (S == null) 182 ErrorSet.error("unable to load type " 183 + superClassName.printName()); 184 return S; 185 } 186 }