1 package polyglot.types; 2 3 import java.io.InvalidClassException ; 4 import java.util.Collection ; 5 import java.util.HashSet ; 6 import java.util.Set ; 7 import java.util.StringTokenizer ; 8 9 import polyglot.main.Report; 10 import polyglot.main.Version; 11 import polyglot.types.reflect.ClassFile; 12 import polyglot.types.reflect.ClassFileLoader; 13 import polyglot.types.reflect.ClassPathLoader; 14 import polyglot.util.CollectionUtil; 15 import polyglot.util.TypeEncoder; 16 17 21 public class LoadedClassResolver extends ClassResolver implements TopLevelResolver 22 { 23 protected final static int NOT_COMPATIBLE = -1; 24 protected final static int MINOR_NOT_COMPATIBLE = 1; 25 protected final static int COMPATIBLE = 0; 26 27 TypeSystem ts; 28 TypeEncoder te; 29 ClassPathLoader loader; 30 Version version; 31 Set nocache; 32 boolean allowRawClasses; 33 34 final static Collection report_topics = CollectionUtil.list( 35 Report.types, Report.resolver, Report.loader); 36 37 45 public LoadedClassResolver(TypeSystem ts, String classpath, 46 ClassFileLoader loader, Version version, 47 boolean allowRawClasses) 48 { 49 this.ts = ts; 50 this.te = new TypeEncoder(ts); 51 this.loader = new ClassPathLoader(classpath, loader); 52 this.version = version; 53 this.nocache = new HashSet (); 54 this.allowRawClasses = allowRawClasses; 55 } 56 57 public boolean packageExists(String name) { 58 return loader.packageExists(name); 59 } 60 61 64 protected ClassFile loadFile(String name) { 65 if (nocache.contains(name)) { 66 return null; 67 } 68 69 try { 70 ClassFile clazz = loader.loadClass(name); 71 72 if (clazz == null) { 73 if (Report.should_report(report_topics, 4)) { 74 Report.report(4, "Class " + name + " not found in classpath " 75 + loader.classpath()); 76 } 77 } 78 else { 79 if (Report.should_report(report_topics, 4)) { 80 Report.report(4, "Class " + name + " found in classpath " 81 + loader.classpath()); 82 } 83 return clazz; 84 } 85 } 86 catch (ClassFormatError e) { 87 if (Report.should_report(report_topics, 4)) 88 Report.report(4, "Class " + name + " format error"); 89 } 90 91 nocache.add(name); 92 93 return null; 94 } 95 96 99 public Named find(String name) throws SemanticException { 100 if (Report.should_report(report_topics, 3)) 101 Report.report(3, "LoadedCR.find(" + name + ")"); 102 103 ClassFile clazz = loadFile(name); 105 if (clazz == null) { 106 throw new NoClassException(name); 107 } 108 109 if (clazz.encodedClassType(version.name()) != null) { 111 if (Report.should_report(report_topics, 4)) 112 Report.report(4, "Using encoded class type for " + name); 113 return getEncodedType(clazz, name); 114 } 115 116 if (allowRawClasses) { 117 if (Report.should_report(report_topics, 4)) 118 Report.report(4, "Using raw class file for " + name); 119 return clazz.type(ts); 120 } 121 122 throw new SemanticException("Unable to find a suitable definition of \"" 125 + name +"\". A class file was found," 126 + " but it did not contain appropriate information for this" 127 + " language extension. If the source for this file is written" 128 + " in the language extension, try recompiling the source code."); 129 130 } 131 132 135 protected ClassType getEncodedType(ClassFile clazz, String name) 136 throws SemanticException 137 { 138 141 FieldInstance field; 144 145 int comp = checkCompilerVersion(clazz.compilerVersion(version.name())); 146 147 if (comp == NOT_COMPATIBLE) { 148 throw new SemanticException("Unable to find a suitable definition of " 149 + clazz.name() 150 + ". Try recompiling or obtaining " 151 + " a newer version of the class file."); 152 } 153 154 ClassType dt; 156 157 try { 158 dt = (ClassType) te.decode(clazz.encodedClassType(version.name())); 159 } 160 catch (InvalidClassException e) { 161 throw new BadSerializationException(clazz.name()); 162 } 163 164 ((CachingResolver) ts.systemResolver()).addNamed(name, dt); 166 167 if (Report.should_report(report_topics, 2)) 168 Report.report(2, "Returning serialized ClassType for " + 169 clazz.name() + "."); 170 171 return (ClassType) dt; 172 } 173 174 177 protected int checkCompilerVersion(String clazzVersion) { 178 if (clazzVersion == null) { 179 return NOT_COMPATIBLE; 180 } 181 182 StringTokenizer st = new StringTokenizer (clazzVersion, "."); 183 184 try { 185 int v; 186 v = Integer.parseInt(st.nextToken()); 187 Version version = this.version; 188 189 if (v != version.major()) { 190 return NOT_COMPATIBLE; 192 } 193 194 v = Integer.parseInt(st.nextToken()); 195 196 if (v != version.minor()) { 197 return MINOR_NOT_COMPATIBLE; 199 } 200 } 201 catch (NumberFormatException e) { 202 return NOT_COMPATIBLE; 203 } 204 205 return COMPATIBLE; 207 } 208 } 209 | Popular Tags |