1 package polyglot.visit; 2 3 import polyglot.main.*; 4 import polyglot.ast.*; 5 import polyglot.types.*; 6 import polyglot.util.*; 7 8 import java.io.*; 9 import java.util.*; 10 11 15 public class ClassSerializer extends NodeVisitor 16 { 17 protected TypeEncoder te; 18 protected ErrorQueue eq; 19 protected Date date; 20 protected TypeSystem ts; 21 protected NodeFactory nf; 22 protected Version ver; 23 24 public ClassSerializer(TypeSystem ts, NodeFactory nf, Date date, ErrorQueue eq, Version ver) { 25 this.ts = ts; 26 this.nf = nf; 27 this.te = new TypeEncoder( ts); 28 this.eq = eq; 29 this.date = date; 30 this.ver = ver; 31 } 32 33 public Node override(Node n) { 34 if (n instanceof ClassMember && ! (n instanceof ClassDecl)) { 36 return n; 37 } 38 39 return null; 40 } 41 42 public Node leave(Node old, Node n, NodeVisitor v) { 43 if (! (n instanceof ClassDecl)) { 44 return n; 45 } 46 47 try { 48 ClassDecl cn = (ClassDecl) n; 49 ClassBody body = cn.body(); 50 ParsedClassType ct = cn.type(); 51 byte[] b; 52 53 ct.superType(); 56 ct.interfaces(); 57 ct.memberClasses(); 58 ct.constructors(); 59 ct.methods(); 60 ct.fields(); 61 62 if (! (ct.isTopLevel() || ct.isMember())) { 63 return n; 64 } 65 66 67 String suffix = ver.name(); 68 69 if (ct.fieldNamed("jlc$CompilerVersion$" + suffix) != null || 71 ct.fieldNamed("jlc$SourceLastModified$" + suffix) != null || 72 ct.fieldNamed("jlc$ClassType$" + suffix) != null) { 73 74 eq.enqueue(ErrorInfo.SEMANTIC_ERROR, 75 "Cannot encode Polyglot type information " + 76 "more than once."); 77 78 return n; 79 } 80 81 Flags flags = Flags.PUBLIC.set(Flags.STATIC).set(Flags.FINAL); 82 83 FieldDecl f; 84 FieldInstance fi; 85 InitializerInstance ii; 86 87 88 String version = ver.major() + "." + 89 ver.minor() + "." + 90 ver.patch_level(); 91 92 Position pos = Position.COMPILER_GENERATED; 93 94 fi = ts.fieldInstance(pos, ct, 95 flags, ts.String(), 96 "jlc$CompilerVersion$" + suffix); 97 ii = ts.initializerInstance(pos, ct, Flags.STATIC); 98 f = nf.FieldDecl(fi.position(), fi.flags(), 99 nf.CanonicalTypeNode(fi.position(), fi.type()), 100 fi.name(), 101 nf.StringLit(pos, version).type(ts.String())); 102 103 f = f.fieldInstance(fi); 104 f = f.initializerInstance(ii); 105 body = body.addMember(f); 106 107 108 long time = date.getTime(); 109 110 fi = ts.fieldInstance(pos, ct, 111 flags, ts.Long(), 112 "jlc$SourceLastModified$" + suffix); 113 ii = ts.initializerInstance(pos, ct, Flags.STATIC); 114 f = nf.FieldDecl(fi.position(), fi.flags(), 115 nf.CanonicalTypeNode(fi.position(), fi.type()), 116 fi.name(), 117 nf.IntLit(pos, IntLit.LONG, time).type(ts.Long())); 118 119 f = f.fieldInstance(fi); 120 f = f.initializerInstance(ii); 121 body = body.addMember(f); 122 123 124 fi = ts.fieldInstance(pos, ct, 125 flags, ts.String(), 126 "jlc$ClassType$" + suffix); 127 ii = ts.initializerInstance(pos, ct, Flags.STATIC); 128 f = nf.FieldDecl(fi.position(), fi.flags(), 129 nf.CanonicalTypeNode(fi.position(), fi.type()), 130 fi.name(), 131 nf.StringLit(pos, te.encode(ct)).type(ts.String())); 132 133 f = f.fieldInstance(fi); 134 f = f.initializerInstance(ii); 135 body = body.addMember(f); 136 137 return cn.body(body); 138 } 139 catch (IOException e) { 140 eq.enqueue(ErrorInfo.IO_ERROR, 141 "Unable to encode Polyglot type information."); 142 return n; 143 } 144 } 145 } 146 | Popular Tags |