1 //
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 26 Dec 05 Brian Frank Creation
7 // 19 Aug 06 Brian Frank Ported from Java to Fan
8 //
9
10 **
11 ** FType is the read/write fcode representation of sys::Type.
12 **
13 class FType : CType
14 {
15
16 //////////////////////////////////////////////////////////////////////////
17 // Constructor
18 //////////////////////////////////////////////////////////////////////////
19
20 new make(FPod fpod)
21 {
22 this.fpod = fpod
23 this.fattrs = FAttr[,]
24 }
25
26 //////////////////////////////////////////////////////////////////////////
27 // CType
28 //////////////////////////////////////////////////////////////////////////
29
30 override Namespace ns() { return fpod.ns }
31 override FPod pod() { return fpod }
32 override Str name() { return fpod.n(fpod.typeRef(self).typeName) }
33 override Str qname() { return "${fpod.name}::${name}" }
34 override Str signature() { return qname }
35 override Str toStr() { return signature }
36
37 override CType base
38 {
39 get
40 {
41 if (@base == null) @base = fpod.toType(fbase)
42 return @base
43 }
44 }
45
46 override CType[] mixins
47 {
48 get
49 {
50 if (@mixins == null) @mixins = fpod.resolveTypes(fmixins)
51 return @mixins
52 }
53 }
54
55 override Str:CSlot slots
56 {
57 get
58 {
59 if (@slots == null) reflect
60 return @slots
61 }
62 }
63
64 override Bool isGeneric()
65 {
66 return fpod.name == "sys" && (name == "List" || name == "Map" || name == "Func")
67 }
68
69 override Bool isParameterized() { return false }
70
71 override Bool isGenericParameter()
72 {
73 return fpod.name == "sys" && name.size == 1
74 }
75
76 override ListType toListOf()
77 {
78 if (listOf == null) listOf = ListType.make(this)
79 return listOf
80 }
81
82 //////////////////////////////////////////////////////////////////////////
83 // Reflection
84 //////////////////////////////////////////////////////////////////////////
85
86 private Void reflect()
87 {
88 // lazy read from the pod file
89 read
90
91 // map all the declared fields and methods
92 @slots = Str:CSlot[:]
93 ffields.each |FField f| { slots[f.name] = f }
94 fmethods.each |FMethod m|
95 {
96 f := (FField)slots[m.name]
97 if (f != null)
98 {
99 // if already mapped to field must be getter/setter
100 if ((m.flags & FConst.Getter) != 0)
101 f.getter = m
102 else if ((m.flags & FConst.Setter) != 0)
103 f.setter = m
104 else
105 throw Err.make("Conflicting slots: $f and $m")
106 }
107 else
108 {
109 slots[m.name] = m
110 }
111 }
112
113 // inherited slots
114 if (base != null) inherit(base)
115 mixins.each |CType t| { inherit(t) }
116 }
117
118 private Void inherit(CType t)
119 {
120 t.slots.each |CSlot newSlot|
121 {
122 // if slot already mapped, skip it
123 if (@slots[newSlot.name] != null) return
124
125 // we never inherit constructors, private slots,
126 // or internal slots outside of the pod
127 if (newSlot.isCtor || newSlot.isPrivate ||
128 (newSlot.isInternal && newSlot.parent.pod != t.pod))
129 return
130
131 // inherit it
132 @slots[newSlot.name] = newSlot
133 }
134 }
135
136 //////////////////////////////////////////////////////////////////////////
137 // Meta IO
138 //////////////////////////////////////////////////////////////////////////
139
140 Void writeMeta(OutStream out)
141 {
142 out.writeI2(self)
143 out.writeI2(fbase)
144 out.writeI2(fmixins.size)
145 fmixins.each |Int m| { out.writeI2(m) }
146 out.writeI4(flags & FConst.FlagsMask)
147 }
148
149 FType readMeta(InStream in)
150 {
151 self = in.readU2
152 fbase = in.readU2
153 fmixins = Int[,]
154 in.readU2.times |,| { fmixins.add(in.readU2) }
155 flags = in.readU4
156 return this
157 }
158
159 //////////////////////////////////////////////////////////////////////////
160 // Body IO
161 //////////////////////////////////////////////////////////////////////////
162
163 Uri uri()
164 {
165 return Uri.fromStr("/" + fpod.n(fpod.typeRef(self).typeName) + ".fcode")
166 }
167
168 Void write()
169 {
170 out := fpod.out(uri)
171
172 out.writeI2(ffields.size)
173 ffields.each |FField f| { f.write(out) }
174
175 out.writeI2(fmethods.size)
176 fmethods.each |FMethod m| { m.write(out) }
177
178 out.writeI2(fattrs.size)
179 fattrs.each |FAttr a| { a.write(out) }
180
181 out.close
182 }
183
184 Void read()
185 {
186 in := fpod.in(uri)
187
188 ffields = FField[,]
189 in.readU2.times |,| { ffields.add(FField.make(this).read(in)) }
190
191 fmethods = FMethod[,]
192 in.readU2.times |,| { fmethods.add(FMethod.make(this).read(in)) }
193
194 fattrs = FAttr[,]
195 in.readU2.times |,| { fattrs.add(FAttr.make.read(in)) }
196
197 in.close
198 }
199
200 //////////////////////////////////////////////////////////////////////////
201 // Fields
202 //////////////////////////////////////////////////////////////////////////
203
204 override Int flags // bitmask
205 Bool hollow := true // have we only read meta-data
206 FPod fpod // parent pod
207 Int self // self typeRef index
208 Int fbase // base typeRef index
209 Int[] fmixins // mixin typeRef indexes
210 FField[] ffields // fields
211 FMethod[] fmethods // methods
212 FAttr[] fattrs // type attributes
213 ListType listOf // CType.listOf cache
214
215 }
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 26 Dec 05 Brian Frank Creation
7 // 19 Aug 06 Brian Frank Ported from Java to Fan
8 //
9
10 **
11 ** FType is the read/write fcode representation of sys::Type.
12 **
13 class FType : CType
14 {
15
16 //////////////////////////////////////////////////////////////////////////
17 // Constructor
18 //////////////////////////////////////////////////////////////////////////
19
20 new make(FPod fpod)
21 {
22 this.fpod = fpod
23 this.fattrs = FAttr[,]
24 }
25
26 //////////////////////////////////////////////////////////////////////////
27 // CType
28 //////////////////////////////////////////////////////////////////////////
29
30 override Namespace ns() { return fpod.ns }
31 override FPod pod() { return fpod }
32 override Str name() { return fpod.n(fpod.typeRef(self).typeName) }
33 override Str qname() { return "${fpod.name}::${name}" }
34 override Str signature() { return qname }
35 override Str toStr() { return signature }
36
37 override CType base
38 {
39 get
40 {
41 if (@base == null) @base = fpod.toType(fbase)
42 return @base
43 }
44 }
45
46 override CType[] mixins
47 {
48 get
49 {
50 if (@mixins == null) @mixins = fpod.resolveTypes(fmixins)
51 return @mixins
52 }
53 }
54
55 override Str:CSlot slots
56 {
57 get
58 {
59 if (@slots == null) reflect
60 return @slots
61 }
62 }
63
64 override Bool isGeneric()
65 {
66 return fpod.name == "sys" && (name == "List" || name == "Map" || name == "Func")
67 }
68
69 override Bool isParameterized() { return false }
70
71 override Bool isGenericParameter()
72 {
73 return fpod.name == "sys" && name.size == 1
74 }
75
76 override ListType toListOf()
77 {
78 if (listOf == null) listOf = ListType.make(this)
79 return listOf
80 }
81
82 //////////////////////////////////////////////////////////////////////////
83 // Reflection
84 //////////////////////////////////////////////////////////////////////////
85
86 private Void reflect()
87 {
88 // lazy read from the pod file
89 read
90
91 // map all the declared fields and methods
92 @slots = Str:CSlot[:]
93 ffields.each |FField f| { slots[f.name] = f }
94 fmethods.each |FMethod m|
95 {
96 f := (FField)slots[m.name]
97 if (f != null)
98 {
99 // if already mapped to field must be getter/setter
100 if ((m.flags & FConst.Getter) != 0)
101 f.getter = m
102 else if ((m.flags & FConst.Setter) != 0)
103 f.setter = m
104 else
105 throw Err.make("Conflicting slots: $f and $m")
106 }
107 else
108 {
109 slots[m.name] = m
110 }
111 }
112
113 // inherited slots
114 if (base != null) inherit(base)
115 mixins.each |CType t| { inherit(t) }
116 }
117
118 private Void inherit(CType t)
119 {
120 t.slots.each |CSlot newSlot|
121 {
122 // if slot already mapped, skip it
123 if (@slots[newSlot.name] != null) return
124
125 // we never inherit constructors, private slots,
126 // or internal slots outside of the pod
127 if (newSlot.isCtor || newSlot.isPrivate ||
128 (newSlot.isInternal && newSlot.parent.pod != t.pod))
129 return
130
131 // inherit it
132 @slots[newSlot.name] = newSlot
133 }
134 }
135
136 //////////////////////////////////////////////////////////////////////////
137 // Meta IO
138 //////////////////////////////////////////////////////////////////////////
139
140 Void writeMeta(OutStream out)
141 {
142 out.writeI2(self)
143 out.writeI2(fbase)
144 out.writeI2(fmixins.size)
145 fmixins.each |Int m| { out.writeI2(m) }
146 out.writeI4(flags & FConst.FlagsMask)
147 }
148
149 FType readMeta(InStream in)
150 {
151 self = in.readU2
152 fbase = in.readU2
153 fmixins = Int[,]
154 in.readU2.times |,| { fmixins.add(in.readU2) }
155 flags = in.readU4
156 return this
157 }
158
159 //////////////////////////////////////////////////////////////////////////
160 // Body IO
161 //////////////////////////////////////////////////////////////////////////
162
163 Uri uri()
164 {
165 return Uri.fromStr("/" + fpod.n(fpod.typeRef(self).typeName) + ".fcode")
166 }
167
168 Void write()
169 {
170 out := fpod.out(uri)
171
172 out.writeI2(ffields.size)
173 ffields.each |FField f| { f.write(out) }
174
175 out.writeI2(fmethods.size)
176 fmethods.each |FMethod m| { m.write(out) }
177
178 out.writeI2(fattrs.size)
179 fattrs.each |FAttr a| { a.write(out) }
180
181 out.close
182 }
183
184 Void read()
185 {
186 in := fpod.in(uri)
187
188 ffields = FField[,]
189 in.readU2.times |,| { ffields.add(FField.make(this).read(in)) }
190
191 fmethods = FMethod[,]
192 in.readU2.times |,| { fmethods.add(FMethod.make(this).read(in)) }
193
194 fattrs = FAttr[,]
195 in.readU2.times |,| { fattrs.add(FAttr.make.read(in)) }
196
197 in.close
198 }
199
200 //////////////////////////////////////////////////////////////////////////
201 // Fields
202 //////////////////////////////////////////////////////////////////////////
203
204 override Int flags // bitmask
205 Bool hollow := true // have we only read meta-data
206 FPod fpod // parent pod
207 Int self // self typeRef index
208 Int fbase // base typeRef index
209 Int[] fmixins // mixin typeRef indexes
210 FField[] ffields // fields
211 FMethod[] fmethods // methods
212 FAttr[] fattrs // type attributes
213 ListType listOf // CType.listOf cache
214
215 }