1 package polyglot.visit; 2 3 import java.io.File ; 4 import java.io.IOException ; 5 import java.io.Writer ; 6 import java.util.Collection ; 7 import java.util.Iterator ; 8 import java.util.LinkedList ; 9 import java.util.List ; 10 11 import polyglot.ast.Import; 12 import polyglot.ast.Node; 13 import polyglot.ast.NodeFactory; 14 import polyglot.ast.SourceCollection; 15 import polyglot.ast.SourceFile; 16 import polyglot.ast.TopLevelDecl; 17 import polyglot.frontend.Job; 18 import polyglot.frontend.TargetFactory; 19 import polyglot.types.ClassType; 20 import polyglot.types.Context; 21 import polyglot.types.Package; 22 import polyglot.types.TypeSystem; 23 import polyglot.util.CodeWriter; 24 import polyglot.util.Copy; 25 import polyglot.util.ErrorInfo; 26 import polyglot.util.InternalCompilerError; 27 28 49 public class Translator extends PrettyPrinter implements Copy 50 { 51 protected Job job; 52 protected NodeFactory nf; 53 protected TargetFactory tf; 54 protected TypeSystem ts; 55 protected Context context; 56 protected ClassType outerClass = null; 57 58 62 public Translator(Job job, TypeSystem ts, NodeFactory nf, TargetFactory tf) { 63 super(); 64 65 this.job = job; 66 this.nf = nf; 67 this.tf = tf; 68 this.ts = ts; 69 this.context = job.context(); 70 71 if (this.context == null) { 72 this.context = ts.createContext(); 73 } 74 } 75 76 79 public Job job() { 80 return job; 81 } 82 83 85 public Translator context(Context c) { 86 if (c == this.context) { 87 return this; 88 } 89 Translator tr = (Translator) copy(); 90 tr.context = c; 91 return tr; 92 } 93 94 95 public Object copy() { 96 try { 97 return super.clone(); 98 } 99 catch (CloneNotSupportedException e) { 100 throw new InternalCompilerError("Java clone() weirdness."); 101 } 102 } 103 104 110 public ClassType outerClass() { 111 return outerClass; 112 } 113 114 115 public void setOuterClass(ClassType ct) { 116 this.outerClass = ct; 117 } 118 119 120 public TypeSystem typeSystem() { 121 return ts; 122 } 123 124 125 public Context context() { 126 return context; 127 } 128 129 130 public NodeFactory nodeFactory() { 131 return nf; 132 } 133 134 139 public void print(Node parent, Node child, CodeWriter w) { 140 Translator tr; 141 142 if (parent != null) { 143 Context c = parent.del().enterScope(child, context); 144 tr = this.context(c); 145 } 146 else { 147 Context c = child.del().enterScope(context); 148 tr = this.context(c); 149 } 150 151 child.del().translate(w, tr); 152 153 if (parent != null) { 154 parent.addDecls(context); 155 } 156 } 157 158 159 public boolean translate(Node ast) { 160 if (ast instanceof SourceFile) { 161 SourceFile sfn = (SourceFile) ast; 162 return translateSource(sfn); 163 } 164 else if (ast instanceof SourceCollection) { 165 SourceCollection sc = (SourceCollection) ast; 166 167 boolean okay = true; 168 169 for (Iterator i = sc.sources().iterator(); i.hasNext(); ) { 170 SourceFile sfn = (SourceFile) i.next(); 171 okay &= translateSource(sfn); 172 } 173 174 return okay; 175 } 176 else { 177 throw new InternalCompilerError("AST root must be a SourceFile; " + 178 "found a " + ast.getClass().getName()); 179 } 180 } 181 182 183 protected boolean translateSource(SourceFile sfn) { 184 TypeSystem ts = typeSystem(); 185 NodeFactory nf = nodeFactory(); 186 TargetFactory tf = this.tf; 187 int outputWidth = job.compiler().outputWidth(); 188 Collection outputFiles = job.compiler().outputFiles(); 189 190 List exports = exports(sfn); 196 197 try { 198 File of; 199 Writer ofw; 200 CodeWriter w; 201 202 String pkg = ""; 203 204 if (sfn.package_() != null) { 205 Package p = sfn.package_().package_(); 206 pkg = p.toString(); 207 } 208 209 Context c = sfn.del().enterScope(context); 210 211 TopLevelDecl first = null; 212 213 if (exports.size() == 0) { 214 of = tf.outputFile(pkg, sfn.source()); 216 } 217 else { 218 first = (TopLevelDecl) exports.get(0); 219 of = tf.outputFile(pkg, first.name(), sfn.source()); 220 } 221 222 String opfPath = of.getPath(); 223 if (!opfPath.endsWith("$")) outputFiles.add(of.getPath()); 224 ofw = tf.outputWriter(of); 225 w = new CodeWriter(ofw, outputWidth); 226 227 writeHeader(sfn, w); 228 229 for (Iterator i = sfn.decls().iterator(); i.hasNext(); ) { 230 TopLevelDecl decl = (TopLevelDecl) i.next(); 231 232 if (decl.flags().isPublic() && decl != first) { 233 w.flush(); 236 ofw.close(); 237 238 of = tf.outputFile(pkg, decl.name(), sfn.source()); 239 outputFiles.add(of.getPath()); 240 ofw = tf.outputWriter(of); 241 w = new CodeWriter(ofw, outputWidth); 242 243 writeHeader(sfn, w); 244 } 245 246 decl.del().translate(w, this.context(c)); 247 248 if (i.hasNext()) { 249 w.newline(0); 250 } 251 } 252 253 w.flush(); 254 ofw.close(); 255 return true; 256 } 257 catch (IOException e) { 258 job.compiler().errorQueue().enqueue(ErrorInfo.IO_ERROR, 259 "I/O error while translating: " + e.getMessage()); 260 return false; 261 } 262 } 263 264 265 protected void writeHeader(SourceFile sfn, CodeWriter w) { 266 if (sfn.package_() != null) { 267 w.write("package "); 268 sfn.package_().del().translate(w, this); 269 w.write(";"); 270 w.newline(0); 271 w.newline(0); 272 } 273 274 boolean newline = false; 275 276 for (Iterator i = sfn.imports().iterator(); i.hasNext(); ) { 277 Import imp = (Import) i.next(); 278 imp.del().translate(w, this); 279 newline = true; 280 } 281 282 if (newline) { 283 w.newline(0); 284 } 285 } 286 287 288 protected List exports(SourceFile sfn) { 289 List exports = new LinkedList (); 290 291 for (Iterator i = sfn.decls().iterator(); i.hasNext(); ) { 292 TopLevelDecl decl = (TopLevelDecl) i.next(); 293 294 if (decl.flags().isPublic()) { 295 exports.add(decl); 296 } 297 } 298 299 return exports; 300 } 301 302 public String toString() { 303 return "Translator"; 304 } 305 } 306 | Popular Tags |