KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > visit > ClassSerializer


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 /**
12  * Visitor which serializes class objects and adds a field to the class
13  * containing the serialization.
14  */

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         // Stop at class members. We only want to encode top-level classes.
35
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             // HACK: force class members to get created from lazy class
54
// initializer.
55
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         /* Add the compiler version number. */
67             String JavaDoc suffix = ver.name();
68
69         // Check if we've already serialized.
70
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         /* Add the compiler version number. */
88         String JavaDoc 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         /* Add the date of the last source file modification. */
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         /* Add the class type info. */
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