1 package polyglot.types; 2 3 import polyglot.util.*; 4 import polyglot.frontend.ExtensionInfo; 5 import polyglot.main.Report; 6 import polyglot.types.Package; 7 import java.util.*; 8 9 12 public class CachingResolver implements TopLevelResolver { 13 TopLevelResolver inner; 14 Map cache; 15 Map packageCache; 16 ExtensionInfo extInfo; 17 18 static Object NOT_FOUND = new Object (); 19 20 24 public CachingResolver(TopLevelResolver inner, ExtensionInfo extInfo) { 25 this.inner = inner; 26 this.cache = new HashMap(); 27 this.packageCache = new HashMap(); 28 this.extInfo = extInfo; 29 } 30 31 34 public TopLevelResolver inner() { 35 return this.inner; 36 } 37 38 public String toString() { 39 return "(cache " + inner.toString() + ")"; 40 } 41 42 45 public boolean packageExists(String name) { 46 Boolean b = (Boolean ) packageCache.get(name); 47 if (b != null) { 48 return b.booleanValue(); 49 } 50 else { 51 String prefix = StringUtil.getPackageComponent(name); 52 53 if (packageCache.get(prefix) == Boolean.FALSE) { 54 packageCache.put(name, Boolean.FALSE); 55 return false; 56 } 57 58 boolean exists = inner.packageExists(name); 59 60 if (exists) { 61 packageCache.put(name, Boolean.TRUE); 62 63 do { 64 packageCache.put(prefix, Boolean.TRUE); 65 prefix = StringUtil.getPackageComponent(prefix); 66 } while (! prefix.equals("")); 67 } 68 else { 69 packageCache.put(name, Boolean.FALSE); 70 } 71 72 return exists; 73 } 74 } 75 76 protected void cachePackage(Package p) { 77 if (p != null) { 78 packageCache.put(p.fullName(), Boolean.TRUE); 79 cachePackage(p.prefix()); 80 } 81 } 82 83 87 public Named find(String name) throws SemanticException { 88 if (Report.should_report(TOPICS, 2)) 89 Report.report(2, "CachingResolver: find: " + name); 90 91 Object o = cache.get(name); 92 93 if (o == NOT_FOUND) { 94 throw new NoClassException(name); 95 } 96 97 Named q = (Named) o; 98 99 if (q == null) { 100 if (Report.should_report(TOPICS, 3)) 101 Report.report(3, "CachingResolver: not cached: " + name); 102 103 try { 104 q = inner.find(name); 105 } 106 catch (NoClassException e) { 107 cache.put(name, NOT_FOUND); 108 throw e; 109 } 110 111 if (q instanceof ClassType) { 112 Package p = ((ClassType) q).package_(); 113 cachePackage(p); 114 } 115 116 addNamed(name, q); 117 118 if (Report.should_report(TOPICS, 3)) 119 Report.report(3, "CachingResolver: loaded: " + name); 120 } 121 else { 122 if (Report.should_report(TOPICS, 3)) 123 Report.report(3, "CachingResolver: cached: " + name); 124 } 125 126 if (q instanceof ParsedClassType) { 127 extInfo.addDependencyToCurrentJob(((ParsedClassType)q).fromSource()); 128 } 129 130 return q; 131 } 132 133 137 public Type checkType(String name) { 138 return (Type) check(name); 139 } 140 141 145 public Named check(String name) { 146 Object o = cache.get(name); 147 if (o == NOT_FOUND) return null; 148 return (Named) cache.get(name); 149 } 150 151 156 public void install(String name, Named q) { 157 cache.put(name, q); 158 } 159 160 165 public void addNamed(String name, Named q) throws SemanticException { 166 install(name, q); 167 168 if (q instanceof Type && packageExists(name)) { 169 throw new SemanticException("Type \"" + name + 170 "\" clashes with package of the same name.", q.position()); 171 } 172 } 173 174 private static final Collection TOPICS = 175 CollectionUtil.list(Report.types, 176 Report.resolver); 177 } 178 | Popular Tags |