1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
|
22 | |
|
23 | |
|
24 | |
|
25 | |
|
26 | |
package com.sun.tools.javafx.comp; |
27 | |
|
28 | |
import java.util.HashMap; |
29 | |
import java.util.Map; |
30 | |
|
31 | |
import com.sun.tools.javac.code.*; |
32 | |
import com.sun.tools.javac.code.Type.ClassType; |
33 | |
import com.sun.tools.javac.code.Type.MethodType; |
34 | |
import com.sun.tools.javac.tree.JCTree.*; |
35 | |
import com.sun.tools.javac.util.*; |
36 | |
import com.sun.tools.javafx.code.JavafxFlags; |
37 | |
import com.sun.tools.javafx.code.JavafxSymtab; |
38 | |
import com.sun.tools.javafx.code.JavafxTypes; |
39 | |
import com.sun.tools.javafx.code.JavafxVarSymbol; |
40 | |
import com.sun.tools.javafx.code.JavafxClassSymbol; |
41 | |
import static com.sun.tools.javafx.code.JavafxVarSymbol.*; |
42 | |
import static com.sun.tools.javafx.comp.JavafxDefs.locationPackageNameString; |
43 | |
import static com.sun.tools.javafx.comp.JavafxDefs.sequencePackageNameString; |
44 | |
|
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | 38390 | public class JavafxTypeMorpher { |
50 | 12 | protected static final Context.Key<JavafxTypeMorpher> typeMorpherKey = |
51 | |
new Context.Key<JavafxTypeMorpher>(); |
52 | |
|
53 | |
private final JavafxDefs defs; |
54 | |
private final Name.Table names; |
55 | |
final JavafxClassReader reader; |
56 | |
private final JavafxSymtab syms; |
57 | |
private final JavafxToJava toJava; |
58 | |
private final JavafxTypes types; |
59 | |
|
60 | |
public final LocationNameSymType[] bindingNCT; |
61 | |
public final LocationNameSymType[] locationNCT; |
62 | |
public final LocationNameSymType[] variableNCT; |
63 | |
public final LocationNameSymType[] boundComprehensionNCT; |
64 | |
public final LocationNameSymType[] constantLocationNCT; |
65 | |
public final LocationNameSymType baseLocation; |
66 | |
|
67 | |
private final Object[] defaultValueByKind; |
68 | |
|
69 | 10374 | public class LocationNameSymType { |
70 | |
public final Name name; |
71 | |
public final ClassSymbol sym; |
72 | |
public final Type type; |
73 | 10374 | private LocationNameSymType(Name name) { |
74 | 10374 | this.name = name; |
75 | 10374 | sym = reader.jreader.enterClass(name); |
76 | 10374 | type = sym.type; |
77 | 10374 | } |
78 | |
private LocationNameSymType(String which) { |
79 | 4389 | this(locationPackageNameString, which); |
80 | 4389 | } |
81 | |
private LocationNameSymType(String pkg, String which) { |
82 | 6384 | this(Name.fromString(names, pkg + "." + which)); |
83 | 6384 | } |
84 | |
} |
85 | |
|
86 | 399 | private Map<Symbol, VarMorphInfo> vmiMap = new HashMap<Symbol, VarMorphInfo>(); |
87 | |
|
88 | |
public class VarMorphInfo extends TypeMorphInfo { |
89 | |
private final Symbol sym; |
90 | |
private final boolean isMethod; |
91 | 4205 | private boolean mustMorph = false; |
92 | 4205 | private boolean haveDeterminedMorphability = false; |
93 | 4205 | private boolean isBoundTo = false; |
94 | 4205 | private boolean isAssignedTo = false; |
95 | |
|
96 | 4205 | VarMorphInfo(Symbol sym) { |
97 | 4205 | super((sym.kind == Kinds.MTH)? ((MethodType)sym.type).getReturnType() : sym.type); |
98 | 4205 | this.sym = sym; |
99 | 4205 | this.isMethod = (sym.kind == Kinds.MTH); |
100 | 4205 | } |
101 | |
|
102 | |
private void determineMorphability() { |
103 | 3554 | if (!isMethod) { |
104 | 3554 | Symbol owner = getSymbol().owner; |
105 | 3554 | if (owner.kind == Kinds.MTH) { |
106 | |
|
107 | 2557 | long flag_fields = getSymbol().flags(); |
108 | |
|
109 | |
|
110 | 2557 | if ( (flag_fields & JavafxFlags.INNER_ACCESS) != 0) { |
111 | 11 | if ( (flag_fields & JavafxFlags.ASSIGNED_TO) != 0) |
112 | 3 | markMustMorph(); |
113 | |
} |
114 | |
|
115 | |
|
116 | 2557 | if ((isBoundTo() || isSequence()) && (flag_fields & Flags.PARAMETER) == 0) { |
117 | 488 | markMustMorph(); |
118 | |
} |
119 | 2557 | } else if (owner.kind == Kinds.TYP) { |
120 | 997 | if (getSymbol() instanceof JavafxVarSymbol) { |
121 | 510 | markMustMorph(); |
122 | 487 | } else if (sym.flatName() != names._super && sym.flatName() != names._this) { |
123 | 487 | if (types.isJFXClass(owner)) { |
124 | |
|
125 | 231 | markMustMorph(); |
126 | |
} |
127 | |
} |
128 | |
} |
129 | |
} |
130 | 3554 | markDeterminedMorphability(); |
131 | 3554 | } |
132 | |
|
133 | |
public boolean mustMorph() { |
134 | 18628 | if (!haveDeterminedMorphability()) { |
135 | 3554 | determineMorphability(); |
136 | |
} |
137 | 18628 | return mustMorph; |
138 | |
} |
139 | |
|
140 | 1232 | private void markMustMorph() { mustMorph = true; } |
141 | 3554 | private void markDeterminedMorphability() { haveDeterminedMorphability = true; } |
142 | 18628 | private boolean haveDeterminedMorphability() { return haveDeterminedMorphability; } |
143 | 2557 | public boolean isBoundTo() { return isBoundTo; } |
144 | 0 | public boolean isAssignedTo() { return isAssignedTo; } |
145 | 889 | public void markBoundTo() { this.isBoundTo = true; haveDeterminedMorphability = false; } |
146 | 928 | public void markAssignedTo() { this.isAssignedTo = true; } |
147 | |
|
148 | |
public Symbol getSymbol() { |
149 | 20005 | return sym; |
150 | |
} |
151 | |
} |
152 | |
|
153 | 6 | public class TypeMorphInfo { |
154 | |
private Type realType; |
155 | |
private final Type morphedVariableType; |
156 | |
private final Type morphedLocationType; |
157 | |
private int typeKind; |
158 | 7072 | private Type elementType = null; |
159 | |
|
160 | 7072 | TypeMorphInfo(Type symType) { |
161 | 7072 | TypeSymbol realTsym = symType.tsym; |
162 | |
|
163 | |
assert |
164 | |
(realTsym != variableNCT[TYPE_KIND_OBJECT].sym) && |
165 | |
(realTsym != variableNCT[TYPE_KIND_SEQUENCE].sym) && |
166 | |
(realTsym != variableNCT[TYPE_KIND_BOOLEAN].sym) && |
167 | |
(realTsym != variableNCT[TYPE_KIND_DOUBLE].sym) && |
168 | 7072 | (realTsym != variableNCT[TYPE_KIND_INT].sym) : "Locations should have been converted"; |
169 | |
|
170 | 7072 | this.realType = symType; |
171 | |
|
172 | 7072 | if (symType.isPrimitive()) { |
173 | 2935 | if (realTsym == syms.doubleType.tsym |
174 | |
) { |
175 | 597 | typeKind = TYPE_KIND_DOUBLE; |
176 | 2338 | } else if (realTsym == syms.intType.tsym |
177 | |
|| realTsym == syms.byteType.tsym |
178 | |
|| realTsym == syms.charType.tsym |
179 | |
|
180 | |
|| realTsym == syms.shortType.tsym) { |
181 | 1883 | typeKind = TYPE_KIND_INT; |
182 | 455 | } else if (realTsym == syms.booleanType.tsym) { |
183 | 453 | typeKind = TYPE_KIND_BOOLEAN; |
184 | |
} else { |
185 | |
|
186 | 2 | this.realType = types.boxedClass(realType).type; |
187 | 2 | elementType = realType; |
188 | 2 | typeKind = TYPE_KIND_OBJECT; |
189 | |
} |
190 | |
} else { |
191 | 4137 | if (isSequence()) { |
192 | 1394 | typeKind = TYPE_KIND_SEQUENCE; |
193 | 1394 | elementType = toJava.elementType(symType); |
194 | |
} else { |
195 | 2743 | typeKind = TYPE_KIND_OBJECT; |
196 | 2743 | elementType = realType; |
197 | |
} |
198 | |
} |
199 | |
|
200 | |
|
201 | 7072 | this.morphedVariableType = symType == syms.voidType ? symType : generifyIfNeeded(variableType(typeKind), this); |
202 | 7072 | this.morphedLocationType = symType == syms.voidType ? symType : generifyIfNeeded(locationType(typeKind), this); |
203 | 7072 | } |
204 | |
|
205 | |
protected boolean isSequence() { |
206 | 6445 | return types.isSequence(realType); |
207 | |
} |
208 | |
|
209 | 4990 | public Type getRealType() { return realType; } |
210 | 0 | public Type getRealBoxedType() { return (realType.isPrimitive())? types.boxedClass(realType).type : realType; } |
211 | 162 | public Type getRealFXType() { return (realType.isPrimitive() && typeKind==TYPE_KIND_OBJECT)? types.boxedClass(realType).type : realType; } |
212 | |
|
213 | 829 | public Type getLocationType() { return morphedLocationType; } |
214 | 3048 | public Type getVariableType() { return morphedVariableType; } |
215 | 211 | public Type getConstantLocationType() { return generifyIfNeeded(constantLocationNCT[typeKind].type, this); } |
216 | 1461 | public Object getDefaultValue() { return defaultValueByKind[typeKind]; } |
217 | 15663 | public Type getElementType() { return elementType; } |
218 | |
|
219 | 46427 | public int getTypeKind() { return typeKind; } |
220 | |
} |
221 | |
|
222 | |
VarMorphInfo varMorphInfo(Symbol sym) { |
223 | 33328 | VarMorphInfo vmi = vmiMap.get(sym); |
224 | 33328 | if (vmi == null) { |
225 | 4205 | vmi = new VarMorphInfo(sym); |
226 | 4205 | vmiMap.put(sym, vmi); |
227 | |
} |
228 | 33328 | return vmi; |
229 | |
} |
230 | |
|
231 | |
TypeMorphInfo typeMorphInfo(Type type) { |
232 | 2867 | return new TypeMorphInfo(type); |
233 | |
} |
234 | |
|
235 | |
public static JavafxTypeMorpher instance(Context context) { |
236 | 1596 | JavafxTypeMorpher instance = context.get(typeMorpherKey); |
237 | 1596 | if (instance == null) |
238 | 399 | instance = new JavafxTypeMorpher(context); |
239 | 1596 | return instance; |
240 | |
} |
241 | |
|
242 | 399 | protected JavafxTypeMorpher(Context context) { |
243 | 399 | context.put(typeMorpherKey, this); |
244 | |
|
245 | 399 | defs = JavafxDefs.instance(context); |
246 | 399 | syms = (JavafxSymtab)(JavafxSymtab.instance(context)); |
247 | 399 | types = JavafxTypes.instance(context); |
248 | 399 | names = Name.Table.instance(context); |
249 | 399 | reader = JavafxClassReader.instance(context); |
250 | 399 | toJava = JavafxToJava.instance(context); |
251 | |
|
252 | 399 | variableNCT = new LocationNameSymType[TYPE_KIND_COUNT]; |
253 | 399 | locationNCT = new LocationNameSymType[TYPE_KIND_COUNT]; |
254 | 399 | bindingNCT = new LocationNameSymType[TYPE_KIND_COUNT]; |
255 | 399 | boundComprehensionNCT = new LocationNameSymType[TYPE_KIND_COUNT]; |
256 | 399 | constantLocationNCT = new LocationNameSymType[TYPE_KIND_COUNT]; |
257 | |
|
258 | 2394 | for (int kind = 0; kind < TYPE_KIND_COUNT; ++kind) { |
259 | 1995 | variableNCT[kind] = new LocationNameSymType(defs.locationVariableName[kind]); |
260 | 1995 | locationNCT[kind] = new LocationNameSymType(defs.locationInterfaceName[kind]); |
261 | 1995 | bindingNCT[kind] = new LocationNameSymType(JavafxVarSymbol.getTypePrefix(kind) + "BindingExpression"); |
262 | 1995 | boundComprehensionNCT[kind] = new LocationNameSymType(sequencePackageNameString, JavafxVarSymbol.getTypePrefix(kind) + "BoundComprehension"); |
263 | 1995 | constantLocationNCT[kind] = new LocationNameSymType(JavafxVarSymbol.getTypePrefix(kind) + "Constant"); |
264 | |
} |
265 | |
|
266 | 399 | baseLocation = new LocationNameSymType("Location"); |
267 | |
|
268 | 399 | defaultValueByKind = new Object[TYPE_KIND_COUNT]; |
269 | 399 | defaultValueByKind[TYPE_KIND_OBJECT] = null; |
270 | 399 | defaultValueByKind[TYPE_KIND_DOUBLE] = 0.0; |
271 | 399 | defaultValueByKind[TYPE_KIND_BOOLEAN] = 0; |
272 | 399 | defaultValueByKind[TYPE_KIND_INT] = 0; |
273 | 399 | defaultValueByKind[TYPE_KIND_SEQUENCE] = null; |
274 | 399 | } |
275 | |
|
276 | |
Type variableType(int typeKind) { |
277 | 15418 | return variableNCT[typeKind].type; |
278 | |
} |
279 | |
|
280 | |
Type locationType(int typeKind) { |
281 | 7126 | return locationNCT[typeKind].type; |
282 | |
} |
283 | |
|
284 | |
Type bindingExpressionType(int typeKind) { |
285 | 153 | return bindingNCT[typeKind].type; |
286 | |
} |
287 | |
|
288 | |
|
289 | |
|
290 | |
|
291 | |
|
292 | |
|
293 | |
Type generifyIfNeeded(Type aLocationType, TypeMorphInfo tmi) { |
294 | |
Type newType; |
295 | 14381 | Type elemType = tmi.getElementType(); |
296 | 14381 | if ((tmi.getTypeKind() == TYPE_KIND_OBJECT || |
297 | |
tmi.getTypeKind() == TYPE_KIND_SEQUENCE) ) { |
298 | 8346 | if (elemType == null) { |
299 | |
|
300 | 0 | elemType = syms.objectType; |
301 | |
} |
302 | 8346 | List<Type> actuals = List.of(elemType); |
303 | 8346 | Type clazzOuter = variableType(tmi.getTypeKind()).getEnclosingType(); |
304 | |
|
305 | 8346 | List<Type> newActuals = List.nil(); |
306 | 8346 | for (Type t : actuals) { |
307 | 8346 | if ((t.tsym instanceof ClassSymbol) && |
308 | |
(t.tsym.flags_field & JavafxFlags.COMPOUND_CLASS) != 0) { |
309 | 1976 | String str = t.tsym.name.toString().replace("$", "."); |
310 | 1976 | ClassSymbol csym = new JavafxClassSymbol(0, names.fromString(str), t.tsym.owner); |
311 | 1976 | csym.flags_field |= JavafxFlags.COMPOUND_CLASS; |
312 | 1976 | Type tp = new ClassType(null, null, csym); |
313 | 1976 | newActuals = newActuals.append(tp); |
314 | 1976 | break; |
315 | |
} |
316 | |
|
317 | 6370 | newActuals = newActuals.append(t); |
318 | |
} |
319 | |
|
320 | 8346 | newType = new ClassType(clazzOuter, newActuals, aLocationType.tsym); |
321 | 8346 | } else { |
322 | 6035 | newType = aLocationType; |
323 | |
} |
324 | 14381 | return newType; |
325 | |
} |
326 | |
} |