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.HashSet; |
30 | |
import java.util.Map; |
31 | |
import java.util.ArrayList; |
32 | |
import java.util.Set; |
33 | |
import javax.lang.model.element.ElementKind; |
34 | |
import javax.tools.JavaFileObject; |
35 | |
|
36 | |
import com.sun.javafx.api.tree.ForExpressionInClauseTree; |
37 | |
import com.sun.javafx.api.tree.InterpolateValueTree; |
38 | |
import com.sun.javafx.api.tree.TypeTree.Cardinality; |
39 | |
import com.sun.tools.javac.code.*; |
40 | |
import static com.sun.tools.javac.code.Flags.*; |
41 | |
import static com.sun.tools.javac.code.Flags.ANNOTATION; |
42 | |
import static com.sun.tools.javac.code.Flags.BLOCK; |
43 | |
import static com.sun.tools.javac.code.Kinds.*; |
44 | |
import static com.sun.tools.javac.code.Kinds.ERRONEOUS; |
45 | |
import com.sun.tools.javac.code.Symbol.*; |
46 | |
import com.sun.tools.javac.code.Type.*; |
47 | |
import static com.sun.tools.javac.code.TypeTags.*; |
48 | |
import static com.sun.tools.javac.code.TypeTags.WILDCARD; |
49 | |
import com.sun.tools.javac.comp.*; |
50 | |
import com.sun.tools.javac.jvm.ByteCodes; |
51 | |
import com.sun.tools.javac.jvm.Target; |
52 | |
import com.sun.tools.javac.tree.JCTree; |
53 | |
import com.sun.tools.javac.tree.JCTree.*; |
54 | |
import com.sun.tools.javac.tree.TreeInfo; |
55 | |
import com.sun.tools.javac.util.*; |
56 | |
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
57 | |
import com.sun.tools.javafx.code.*; |
58 | |
import com.sun.tools.javafx.tree.*; |
59 | |
import com.sun.tools.javafx.util.MsgSym; |
60 | |
|
61 | |
|
62 | |
|
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
|
69 | |
|
70 | |
|
71 | |
|
72 | |
|
73 | |
|
74 | |
|
75 | |
|
76 | |
|
77 | 12 | public class JavafxAttr extends JCTree.Visitor implements JavafxVisitor { |
78 | 12 | protected static final Context.Key<JavafxAttr> javafxAttrKey = |
79 | |
new Context.Key<JavafxAttr>(); |
80 | |
|
81 | |
|
82 | |
|
83 | |
|
84 | |
private final JavafxDefs defs; |
85 | |
private final Name.Table names; |
86 | |
private final Log log; |
87 | |
private final JavafxResolve rs; |
88 | |
private final JavafxSymtab syms; |
89 | |
private final JavafxCheck chk; |
90 | |
private final JavafxMemberEnter memberEnter; |
91 | |
private final JavafxTreeMaker make; |
92 | |
private final ConstFold cfolder; |
93 | |
private final JavafxEnter enter; |
94 | |
private final Target target; |
95 | |
private final JavafxTypes types; |
96 | |
private final Annotate annotate; |
97 | |
|
98 | |
|
99 | |
|
100 | |
|
101 | |
private final Name numberTypeName; |
102 | |
private final Name integerTypeName; |
103 | |
private final Name booleanTypeName; |
104 | |
private final Name stringTypeName; |
105 | |
private final Name voidTypeName; |
106 | |
private final Source source; |
107 | |
|
108 | |
|
109 | |
private static final boolean allowOldStyleTriggers = false; |
110 | |
|
111 | 399 | Map<JavafxVarSymbol, JFXVar> varSymToTree = new HashMap<JavafxVarSymbol, JFXVar>(); |
112 | |
|
113 | |
public static JavafxAttr instance(Context context) { |
114 | 1197 | JavafxAttr instance = context.get(javafxAttrKey); |
115 | 1197 | if (instance == null) |
116 | 399 | instance = new JavafxAttr(context); |
117 | 1197 | return instance; |
118 | |
} |
119 | |
|
120 | 399 | protected JavafxAttr(Context context) { |
121 | 399 | context.put(javafxAttrKey, this); |
122 | |
|
123 | 399 | defs = JavafxDefs.instance(context); |
124 | 399 | syms = (JavafxSymtab)JavafxSymtab.instance(context); |
125 | 399 | names = Name.Table.instance(context); |
126 | 399 | log = Log.instance(context); |
127 | 399 | rs = JavafxResolve.instance(context); |
128 | 399 | chk = JavafxCheck.instance(context); |
129 | 399 | memberEnter = JavafxMemberEnter.instance(context); |
130 | 399 | make = (JavafxTreeMaker)JavafxTreeMaker.instance(context); |
131 | 399 | enter = JavafxEnter.instance(context); |
132 | 399 | cfolder = ConstFold.instance(context); |
133 | 399 | target = Target.instance(context); |
134 | 399 | types = JavafxTypes.instance(context); |
135 | 399 | annotate = Annotate.instance(context); |
136 | |
|
137 | 399 | Options options = Options.instance(context); |
138 | |
|
139 | 399 | source = Source.instance(context); |
140 | 399 | allowGenerics = source.allowGenerics(); |
141 | 399 | allowVarargs = source.allowVarargs(); |
142 | 399 | allowEnums = source.allowEnums(); |
143 | 399 | allowBoxing = source.allowBoxing(); |
144 | 399 | allowCovariantReturns = source.allowCovariantReturns(); |
145 | 399 | allowAnonOuterThis = source.allowAnonOuterThis(); |
146 | 399 | relax = (options.get("-retrofit") != null || |
147 | |
options.get("-relax") != null); |
148 | |
|
149 | 399 | numberTypeName = names.fromString("Number"); |
150 | 399 | integerTypeName = names.fromString("Integer"); |
151 | 399 | booleanTypeName = names.fromString("Boolean"); |
152 | 399 | stringTypeName = names.fromString("String"); |
153 | 399 | voidTypeName = names.fromString("Void"); |
154 | 399 | } |
155 | |
|
156 | |
|
157 | |
|
158 | |
protected |
159 | |
|
160 | |
boolean relax; |
161 | |
|
162 | |
|
163 | |
protected |
164 | |
|
165 | |
|
166 | |
|
167 | |
boolean allowGenerics; |
168 | |
|
169 | |
|
170 | |
|
171 | |
|
172 | |
protected |
173 | |
|
174 | |
boolean allowVarargs; |
175 | |
|
176 | |
|
177 | |
protected |
178 | |
|
179 | |
|
180 | |
|
181 | |
boolean allowEnums; |
182 | |
|
183 | |
|
184 | |
protected |
185 | |
|
186 | |
|
187 | |
|
188 | |
boolean allowBoxing; |
189 | |
|
190 | |
|
191 | |
protected |
192 | |
|
193 | |
|
194 | |
|
195 | |
boolean allowCovariantReturns; |
196 | |
|
197 | |
|
198 | |
protected |
199 | |
|
200 | |
|
201 | |
|
202 | |
|
203 | |
boolean allowAnonOuterThis; |
204 | |
|
205 | 36 | public enum Sequenceness { |
206 | 9 | DISALLOWED, |
207 | 9 | PERMITTED, |
208 | 9 | REQUIRED |
209 | |
} |
210 | |
|
211 | |
|
212 | |
|
213 | |
|
214 | |
|
215 | |
|
216 | |
|
217 | |
|
218 | |
|
219 | |
|
220 | |
|
221 | |
|
222 | |
|
223 | |
|
224 | |
protected |
225 | |
Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt, Sequenceness pSequenceness) { |
226 | 40409 | if (owntype != null && owntype != syms.javafx_UnspecifiedType && owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) { |
227 | |
|
228 | 37037 | if ((pkind & VAL) != 0 && ownkind == MTH) { |
229 | 9 | ownkind = VAL; |
230 | 9 | if (owntype instanceof MethodType) |
231 | 9 | owntype = syms.makeFunctionType((MethodType) owntype); |
232 | |
} |
233 | 37037 | if ((ownkind & ~pkind) == 0) { |
234 | 37037 | owntype = chk.checkType(tree.pos(), owntype, pt, pSequenceness); |
235 | |
} else { |
236 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_UNEXPECTED_TYPE, |
237 | |
Resolve.kindNames(pkind), |
238 | |
Resolve.kindName(ownkind)); |
239 | 0 | owntype = syms.errType; |
240 | |
} |
241 | |
} |
242 | 40409 | tree.type = owntype; |
243 | 40409 | return owntype; |
244 | |
} |
245 | |
|
246 | |
|
247 | |
|
248 | |
static boolean isType(Symbol sym) { |
249 | 21875 | return sym != null && sym.kind == TYP; |
250 | |
} |
251 | |
|
252 | |
|
253 | |
|
254 | |
|
255 | |
Symbol thisSym(DiagnosticPosition pos, JavafxEnv<JavafxAttrContext> env) { |
256 | 0 | return rs.resolveSelf(pos, env, env.enclClass.sym, names._this); |
257 | |
} |
258 | |
|
259 | |
|
260 | |
|
261 | |
|
262 | |
|
263 | |
|
264 | |
|
265 | |
JavafxEnv<JavafxAttrContext> env; |
266 | |
|
267 | |
|
268 | |
|
269 | |
int pkind; |
270 | |
|
271 | |
|
272 | |
|
273 | |
Type pt; |
274 | |
|
275 | |
|
276 | |
|
277 | |
Sequenceness pSequenceness; |
278 | |
|
279 | |
|
280 | |
|
281 | |
Type result; |
282 | |
|
283 | |
|
284 | |
|
285 | |
|
286 | |
|
287 | |
|
288 | |
|
289 | |
|
290 | |
|
291 | |
Type attribTree(JCTree tree, JavafxEnv<JavafxAttrContext> env, int pkind, Type pt) { |
292 | 13548 | return attribTree(tree, env, pkind, pt, pSequenceness); |
293 | |
} |
294 | |
|
295 | |
Type attribTree(JCTree tree, JavafxEnv<JavafxAttrContext> env, int pkind, Type pt, Sequenceness pSequenceness) { |
296 | 53683 | JavafxEnv<JavafxAttrContext> prevEnv = this.env; |
297 | 53683 | int prevPkind = this.pkind; |
298 | 53683 | Type prevPt = this.pt; |
299 | 53683 | Sequenceness prevSequenceness = this.pSequenceness; |
300 | |
try { |
301 | 53683 | this.env = env; |
302 | 53683 | this.pkind = pkind; |
303 | 53683 | this.pt = pt; |
304 | 53683 | this.pSequenceness = pSequenceness; |
305 | 53683 | tree.accept(this); |
306 | 53671 | return result; |
307 | 0 | } catch (CompletionFailure ex) { |
308 | 0 | tree.type = syms.errType; |
309 | 0 | return chk.completionError(tree.pos(), ex); |
310 | |
} finally { |
311 | 53683 | this.env = prevEnv; |
312 | 53683 | this.pkind = prevPkind; |
313 | 53683 | this.pt = prevPt; |
314 | 53683 | this.pSequenceness = prevSequenceness; |
315 | |
} |
316 | |
} |
317 | |
|
318 | |
|
319 | |
|
320 | |
public Type attribExpr(JCTree tree, JavafxEnv<JavafxAttrContext> env, Type pt, Sequenceness pSequenceness) { |
321 | 0 | return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType, pt.tag != ERROR ? pSequenceness : Sequenceness.PERMITTED); |
322 | |
} |
323 | |
|
324 | |
|
325 | |
|
326 | |
|
327 | |
|
328 | |
public Type attribExpr(JCTree tree, JavafxEnv<JavafxAttrContext> env, Type pt) { |
329 | 13691 | return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType, |
330 | |
(pt.tag == ERROR || pt == Type.noType)? |
331 | |
Sequenceness.PERMITTED : |
332 | |
types.isSequence(pt)? Sequenceness.REQUIRED : Sequenceness.DISALLOWED); |
333 | |
} |
334 | |
|
335 | |
|
336 | |
|
337 | |
|
338 | |
Type attribExpr(JCTree tree, JavafxEnv<JavafxAttrContext> env) { |
339 | 8715 | return attribTree(tree, env, VAL, Type.noType, Sequenceness.PERMITTED); |
340 | |
} |
341 | |
|
342 | |
|
343 | |
|
344 | |
Type attribType(JCTree tree, JavafxEnv<JavafxAttrContext> env) { |
345 | 6550 | Type localResult = attribTree(tree, env, TYP, Type.noType, Sequenceness.DISALLOWED); |
346 | 6550 | return localResult; |
347 | |
} |
348 | |
|
349 | |
|
350 | |
|
351 | |
public Type attribStat(JCTree tree, JavafxEnv<JavafxAttrContext> env) { |
352 | 2690 | return attribTree(tree, env, NIL, Type.noType, Sequenceness.DISALLOWED); |
353 | |
} |
354 | |
|
355 | |
public Type attribVar(JFXVar tree, JavafxEnv<JavafxAttrContext> env) { |
356 | 1438 | memberEnter.memberEnter(tree, env); |
357 | 1438 | return attribTree(tree, env, NIL, Type.noType, Sequenceness.DISALLOWED); |
358 | |
} |
359 | |
|
360 | |
|
361 | |
|
362 | |
List<Type> attribExprs(List<JCExpression> trees, JavafxEnv<JavafxAttrContext> env, Type pt) { |
363 | 0 | ListBuffer<Type> ts = new ListBuffer<Type>(); |
364 | 0 | for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) |
365 | 0 | ts.append(attribExpr(l.head, env, pt)); |
366 | 0 | return ts.toList(); |
367 | |
} |
368 | |
|
369 | |
|
370 | |
|
371 | |
List<Type> attribArgs(List<JCExpression> trees, JavafxEnv<JavafxAttrContext> env) { |
372 | 641 | ListBuffer<Type> argtypes = new ListBuffer<Type>(); |
373 | 739 | for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) |
374 | 98 | argtypes.append(chk.checkNonVoid( |
375 | |
l.head.pos(), types.upperBound(attribTree(l.head, env, VAL, Infer.anyPoly)))); |
376 | 641 | return argtypes.toList(); |
377 | |
} |
378 | |
|
379 | |
|
380 | |
|
381 | |
|
382 | |
|
383 | |
|
384 | |
boolean isStaticReference(JCTree tree) { |
385 | 0 | if (tree.getTag() == JCTree.SELECT) { |
386 | 0 | Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected); |
387 | 0 | if (lsym == null || lsym.kind != TYP) { |
388 | 0 | return false; |
389 | |
} |
390 | |
} |
391 | 0 | return true; |
392 | |
} |
393 | |
|
394 | |
|
395 | |
|
396 | |
<T extends JCTree> void attribStats(List<T> trees, JavafxEnv<JavafxAttrContext> env) { |
397 | 1332 | for (List<T> l = trees; l.nonEmpty(); l = l.tail) |
398 | 390 | attribStat(l.head, env); |
399 | 942 | } |
400 | |
|
401 | |
|
402 | |
protected |
403 | |
|
404 | |
|
405 | |
|
406 | |
List<Type> attribTypes(List<JCExpression> trees, JavafxEnv<JavafxAttrContext> env) { |
407 | 3327 | ListBuffer<Type> argtypes = new ListBuffer<Type>(); |
408 | 3327 | for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) |
409 | 0 | argtypes.append(chk.checkRefType(l.head.pos(), attribType(l.head, env))); |
410 | 3327 | return argtypes.toList(); |
411 | |
} |
412 | |
|
413 | |
|
414 | |
|
415 | |
|
416 | |
|
417 | |
|
418 | |
|
419 | |
void attribTypeVariables(List<JCTypeParameter> typarams, JavafxEnv<JavafxAttrContext> env) { |
420 | 702 | for (JCTypeParameter tvar : typarams) { |
421 | 0 | TypeVar a = (TypeVar)tvar.type; |
422 | 0 | if (!tvar.bounds.isEmpty()) { |
423 | 0 | List<Type> bounds = List.of(attribType(tvar.bounds.head, env)); |
424 | 0 | for (JCExpression bound : tvar.bounds.tail) |
425 | 0 | bounds = bounds.prepend(attribType(bound, env)); |
426 | 0 | types.setBounds(a, bounds.reverse()); |
427 | 0 | } else { |
428 | |
|
429 | |
|
430 | 0 | types.setBounds(a, List.of(syms.objectType)); |
431 | |
} |
432 | 0 | } |
433 | 702 | for (JCTypeParameter tvar : typarams) |
434 | 0 | chk.checkNonCyclic(tvar.pos(), (TypeVar)tvar.type); |
435 | 702 | attribStats(typarams, env); |
436 | 702 | } |
437 | |
|
438 | |
void attribBounds(List<JCTypeParameter> typarams) { |
439 | 670 | for (JCTypeParameter typaram : typarams) { |
440 | 0 | Type bound = typaram.type.getUpperBound(); |
441 | 0 | if (bound != null && bound.tsym instanceof ClassSymbol) { |
442 | 0 | ClassSymbol c = (ClassSymbol)bound.tsym; |
443 | 0 | if ((c.flags_field & COMPOUND) != 0) { |
444 | 0 | assert (c.flags_field & UNATTRIBUTED) != 0 : c; |
445 | 0 | attribClass(typaram.pos(), null, c); |
446 | |
} |
447 | |
} |
448 | 0 | } |
449 | 670 | } |
450 | |
|
451 | |
|
452 | |
|
453 | |
|
454 | |
void attribAnnotationTypes(List<JCAnnotation> annotations, |
455 | |
JavafxEnv<JavafxAttrContext> env) { |
456 | 702 | for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) { |
457 | 0 | JCAnnotation a = al.head; |
458 | 0 | attribType(a.annotationType, env); |
459 | |
} |
460 | 702 | } |
461 | |
|
462 | |
|
463 | |
|
464 | |
|
465 | |
|
466 | |
|
467 | |
|
468 | |
|
469 | |
Type attribBase(JCTree tree, |
470 | |
JavafxEnv<JavafxAttrContext> env, |
471 | |
boolean classExpected, |
472 | |
boolean interfaceExpected, |
473 | |
boolean checkExtensible) { |
474 | 26 | Type t = attribType(tree, env); |
475 | 26 | return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible); |
476 | |
} |
477 | |
|
478 | |
Type checkBase(Type t, |
479 | |
JCTree tree, |
480 | |
JavafxEnv<JavafxAttrContext> env, |
481 | |
boolean classExpected, |
482 | |
boolean interfaceExpected, |
483 | |
boolean checkExtensible) { |
484 | 26 | if (t.tag == TYPEVAR && !classExpected && !interfaceExpected) { |
485 | |
|
486 | 0 | if (t.getUpperBound() == null) { |
487 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_ILLEGAL_FORWARD_REF); |
488 | 0 | return syms.errType; |
489 | |
} |
490 | |
} else { |
491 | 26 | t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics); |
492 | |
} |
493 | 26 | if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) { |
494 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_INTF_EXPECTED_HERE); |
495 | |
|
496 | |
|
497 | 0 | return syms.errType; |
498 | 26 | } else if (checkExtensible && |
499 | |
classExpected && |
500 | |
(t.tsym.flags() & INTERFACE) != 0) { |
501 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_NO_INTF_EXPECTED_HERE); |
502 | 0 | return syms.errType; |
503 | |
} |
504 | 26 | if (checkExtensible && |
505 | |
((t.tsym.flags() & FINAL) != 0)) { |
506 | 0 | log.error(tree.pos(), |
507 | |
MsgSym.MESSAGE_CANNOT_INHERIT_FROM_FINAL, t.tsym); |
508 | |
} |
509 | 26 | chk.checkNonCyclic(tree.pos(), t); |
510 | 26 | return t; |
511 | |
} |
512 | |
|
513 | |
JavafxEnv<JavafxAttrContext> newLocalEnv(JCTree tree) { |
514 | 763 | JavafxEnv<JavafxAttrContext> localEnv = |
515 | |
env.dup(tree, env.info.dup(env.info.scope.dupUnshared())); |
516 | 763 | localEnv.outer = env; |
517 | 763 | localEnv.info.scope.owner = new MethodSymbol(BLOCK, names.empty, null, env.enclClass.sym); |
518 | 763 | return localEnv; |
519 | |
} |
520 | |
|
521 | |
@Override |
522 | |
public void visitTypeCast(JCTypeCast tree) { |
523 | 121 | Type clazztype = attribType(tree.clazz, env); |
524 | 121 | Type exprtype = attribExpr(tree.expr, env, Infer.anyPoly); |
525 | 121 | if (clazztype.isPrimitive() && ! exprtype.isPrimitive()) |
526 | 11 | clazztype = types.boxedClass(clazztype).type; |
527 | 121 | Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype); |
528 | 121 | if (exprtype.constValue() != null) |
529 | 0 | owntype = cfolder.coerce(exprtype, owntype); |
530 | 121 | result = check(tree, capture(owntype), VAL, pkind, pt, Sequenceness.DISALLOWED); |
531 | 121 | } |
532 | |
|
533 | |
@Override |
534 | |
public void visitTypeTest(JCInstanceOf tree) { |
535 | 37 | Type exprtype = chk.checkNullOrRefType( |
536 | |
tree.expr.pos(), attribExpr(tree.expr, env)); |
537 | 37 | Type clazztype = chk.checkReifiableReferenceType( |
538 | |
tree.clazz.pos(), attribType(tree.clazz, env)); |
539 | 37 | chk.checkCastable(tree.expr.pos(), exprtype, clazztype); |
540 | 37 | result = check(tree, syms.booleanType, VAL, pkind, pt, Sequenceness.DISALLOWED); |
541 | 37 | } |
542 | |
|
543 | |
@Override |
544 | |
public void visitIndexed(JCArrayAccess tree) { |
545 | 0 | assert false : "This tree should not exist"; |
546 | 0 | } |
547 | |
|
548 | |
@Override |
549 | |
public void visitIdent(JCIdent tree) { |
550 | |
Symbol sym; |
551 | 12853 | boolean varArgs = false; |
552 | |
|
553 | |
|
554 | 12853 | if (tree.sym != null && tree.sym.kind != VAR) { |
555 | 1437 | sym = tree.sym; |
556 | |
} else { |
557 | 11416 | sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind, pt); |
558 | |
} |
559 | 12853 | tree.sym = sym; |
560 | 12853 | sym.complete(); |
561 | 12853 | if (sym.type == null) { |
562 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_JAVAFX_TYPE_INFER_CYCLE, tree.name); |
563 | 0 | sym.type = syms.objectType; |
564 | |
} |
565 | |
|
566 | |
|
567 | |
|
568 | |
|
569 | |
|
570 | |
|
571 | |
|
572 | |
|
573 | 12853 | JavafxEnv<JavafxAttrContext> symEnv = env; |
574 | 12853 | boolean noOuterThisPath = false; |
575 | 12853 | if (env.enclClass.sym.owner.kind != PCK && |
576 | |
(sym.kind & (VAR | MTH | TYP)) != 0 && |
577 | |
sym.owner.kind == TYP && |
578 | |
tree.name != names._this && tree.name != names._super) { |
579 | |
|
580 | |
|
581 | 1611 | while (symEnv.outer != null && |
582 | |
!sym.isMemberOf(symEnv.enclClass.sym, types)) { |
583 | 776 | if ((symEnv.enclClass.sym.flags() & NOOUTERTHIS) != 0) |
584 | 0 | noOuterThisPath = !allowAnonOuterThis; |
585 | 776 | symEnv = symEnv.outer; |
586 | |
} |
587 | |
} |
588 | |
|
589 | |
|
590 | 12853 | if (sym.kind == VAR) { |
591 | 6954 | VarSymbol v = (VarSymbol)sym; |
592 | |
|
593 | |
|
594 | |
|
595 | 6954 | checkInit(tree, env, v, false); |
596 | |
|
597 | |
|
598 | |
|
599 | 6954 | if (pkind == VAR) |
600 | 1231 | checkAssignable(tree.pos(), v, null, env); |
601 | |
} |
602 | |
|
603 | |
|
604 | |
|
605 | |
|
606 | 12853 | if ((symEnv.info.isSelfCall || noOuterThisPath) && |
607 | |
(sym.kind & (VAR | MTH)) != 0 && |
608 | |
sym.owner.kind == TYP && |
609 | |
(sym.flags() & STATIC) == 0) { |
610 | 0 | chk.earlyRefError(tree.pos(), sym.kind == VAR ? sym : thisSym(tree.pos(), env)); |
611 | |
} |
612 | 12853 | JavafxEnv<JavafxAttrContext> env1 = env; |
613 | 12853 | if (sym.kind != ERR && sym.owner != null && sym.owner != env1.enclClass.sym) { |
614 | |
|
615 | |
|
616 | |
|
617 | 33441 | while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym)) |
618 | 23286 | env1 = env1.outer; |
619 | |
} |
620 | 12853 | result = checkId(tree, env1.enclClass.sym.type, sym, env, pkind, pt, pSequenceness, varArgs); |
621 | 12853 | } |
622 | |
|
623 | |
@Override |
624 | |
public void visitSelect(JCFieldAccess tree) { |
625 | |
|
626 | 7961 | int skind = 0; |
627 | 7961 | if (tree.name == names._this || tree.name == names._super || |
628 | |
tree.name == names._class) |
629 | |
{ |
630 | 0 | skind = TYP; |
631 | |
} else { |
632 | 7961 | if ((pkind & PCK) != 0) skind = skind | PCK; |
633 | 7961 | if ((pkind & TYP) != 0) skind = skind | TYP | PCK; |
634 | 7961 | if ((pkind & (VAL | MTH)) != 0) skind = skind | VAL | TYP; |
635 | |
} |
636 | |
|
637 | |
|
638 | 7961 | Type site = attribTree(tree.selected, env, skind, Infer.anyPoly); |
639 | 7961 | if ((pkind & (PCK | TYP)) == 0) |
640 | 3178 | site = capture(site); |
641 | |
|
642 | |
|
643 | 7961 | if (skind == TYP) { |
644 | 0 | Type elt = site; |
645 | 0 | while (elt.tag == ARRAY) |
646 | 0 | elt = ((ArrayType)elt).elemtype; |
647 | 0 | if (elt.tag == TYPEVAR) { |
648 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_TYPE_VAR_CANNOT_BE_DEREF); |
649 | 0 | result = syms.errType; |
650 | 0 | return; |
651 | |
} |
652 | |
} |
653 | |
|
654 | |
|
655 | |
|
656 | |
|
657 | 7961 | Symbol sitesym = TreeInfo.symbol(tree.selected); |
658 | 7961 | boolean selectSuperPrev = env.info.selectSuper; |
659 | 7961 | env.info.selectSuper = |
660 | |
sitesym != null && |
661 | |
sitesym.name == names._super; |
662 | |
|
663 | |
|
664 | |
|
665 | |
|
666 | 7961 | if (tree.selected.type.tag == FORALL) { |
667 | 0 | ForAll pstype = (ForAll)tree.selected.type; |
668 | 0 | env.info.tvars = pstype.tvars; |
669 | 0 | site = tree.selected.type = pstype.qtype; |
670 | |
} |
671 | |
|
672 | |
|
673 | 7961 | env.info.varArgs = false; |
674 | 7961 | if (sitesym instanceof ClassSymbol && |
675 | |
env.enclClass.sym.isSubClass(sitesym, types)) |
676 | 3 | env.info.selectSuper = true; |
677 | 7961 | Symbol sym = selectSym(tree, site, env, pt, pkind); |
678 | 7961 | sym.complete(); |
679 | 7961 | if (sym.exists() && !isType(sym) && (pkind & (PCK | TYP)) != 0) { |
680 | 1579 | site = capture(site); |
681 | 1579 | sym = selectSym(tree, site, env, pt, pkind); |
682 | |
} |
683 | 7961 | boolean varArgs = env.info.varArgs; |
684 | 7961 | tree.sym = sym; |
685 | |
|
686 | 7961 | if (sym.type == null) { |
687 | 1 | log.error(tree.pos(), MsgSym.MESSAGE_JAVAFX_TYPE_INFER_CYCLE, sym.name); |
688 | 1 | sym.type = syms.objectType; |
689 | |
} |
690 | |
|
691 | 7961 | if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR) |
692 | 0 | site = capture(site.getUpperBound()); |
693 | |
|
694 | |
|
695 | 7961 | if (sym.kind == VAR) { |
696 | 2311 | VarSymbol v = (VarSymbol)sym; |
697 | |
|
698 | |
|
699 | |
|
700 | 2311 | checkInit(tree, env, v, true); |
701 | |
|
702 | |
|
703 | |
|
704 | 2311 | if (pkind == VAR) |
705 | 198 | checkAssignable(tree.pos(), v, tree.selected, env); |
706 | |
} |
707 | |
|
708 | |
|
709 | 7961 | if (isType(sym) && (sitesym==null || (sitesym.kind&(TYP|PCK)) == 0)) { |
710 | 0 | tree.type = check(tree.selected, pt, |
711 | |
sitesym == null ? VAL : sitesym.kind, TYP|PCK, pt, pSequenceness); |
712 | |
} |
713 | |
|
714 | 7961 | if (isType(sitesym)) { |
715 | 2047 | if (sym.name == names._this) { |
716 | |
|
717 | |
|
718 | 0 | if (env.info.isSelfCall && |
719 | |
site.tsym == env.enclClass.sym) { |
720 | 0 | chk.earlyRefError(tree.pos(), sym); |
721 | |
} |
722 | |
} |
723 | |
} |
724 | |
|
725 | |
|
726 | 7961 | if (env.info.selectSuper && (sym.flags() & STATIC) == 0) { |
727 | |
|
728 | |
|
729 | 11 | rs.checkNonAbstract(tree.pos(), sym); |
730 | |
|
731 | 11 | if (site.isRaw()) { |
732 | |
|
733 | 0 | Type site1 = types.asSuper(env.enclClass.sym.type, site.tsym); |
734 | 0 | if (site1 != null) site = site1; |
735 | |
} |
736 | |
} |
737 | |
|
738 | 7961 | env.info.selectSuper = selectSuperPrev; |
739 | 7961 | result = checkId(tree, site, sym, env, pkind, pt, pSequenceness, varArgs); |
740 | 7961 | env.info.tvars = List.nil(); |
741 | 7961 | } |
742 | |
|
743 | |
|
744 | |
|
745 | |
|
746 | |
|
747 | |
|
748 | |
|
749 | |
|
750 | |
|
751 | |
@SuppressWarnings("fallthrough") |
752 | |
private Symbol selectSym(JCFieldAccess tree, |
753 | |
Type site, |
754 | |
JavafxEnv<JavafxAttrContext> env, |
755 | |
Type pt, |
756 | |
int pkind) { |
757 | 9540 | DiagnosticPosition pos = tree.pos(); |
758 | 9540 | Name name = tree.name; |
759 | |
|
760 | 9540 | switch (site.tag) { |
761 | |
case PACKAGE: |
762 | 3226 | return rs.access( |
763 | |
rs.findIdentInPackage(env, site.tsym, name, pkind), |
764 | |
pos, site, name, true); |
765 | |
case ARRAY: |
766 | |
case CLASS: |
767 | 6284 | if (pt.tag == METHOD || pt.tag == FORALL) { |
768 | 2413 | return rs.resolveQualifiedMethod(pos, env, site, name, pt); |
769 | 3871 | } else if (name == names._this || name == names._super) { |
770 | 0 | return rs.resolveSelf(pos, env, site.tsym, name); |
771 | 3871 | } else if (name == names._class) { |
772 | |
|
773 | |
|
774 | 0 | Type t = syms.classType; |
775 | 0 | List<Type> typeargs = allowGenerics |
776 | |
? List.of(types.erasure(site)) |
777 | |
: List.<Type>nil(); |
778 | 0 | t = new ClassType(t.getEnclosingType(), typeargs, t.tsym); |
779 | 0 | return new VarSymbol( |
780 | |
STATIC | PUBLIC | FINAL, names._class, t, site.tsym); |
781 | |
} else { |
782 | |
|
783 | 3871 | Symbol sym = rs.findIdentInType(env, site, name, pkind); |
784 | 3871 | if ((pkind & ERRONEOUS) == 0) |
785 | 3871 | sym = rs.access(sym, pos, site, name, true); |
786 | 3871 | return sym; |
787 | |
} |
788 | |
case WILDCARD: |
789 | 0 | throw new AssertionError(tree); |
790 | |
case TYPEVAR: |
791 | |
|
792 | |
|
793 | |
|
794 | |
|
795 | |
|
796 | |
|
797 | 0 | Symbol sym = (site.getUpperBound() != null) |
798 | |
? selectSym(tree, capture(site.getUpperBound()), env, pt, pkind) |
799 | |
: null; |
800 | 0 | if (sym == null || isType(sym)) { |
801 | 0 | log.error(pos, MsgSym.MESSAGE_TYPE_VAR_CANNOT_BE_DEREF); |
802 | 0 | return syms.errSymbol; |
803 | |
} else { |
804 | 0 | return sym; |
805 | |
} |
806 | |
case ERROR: |
807 | |
|
808 | 1 | return new ErrorType(name, site.tsym).tsym; |
809 | |
case INT: |
810 | |
case DOUBLE: |
811 | |
case BOOLEAN: |
812 | 29 | if (pt.tag == METHOD || pt.tag == FORALL) { |
813 | 29 | Type boxedSite = types.boxedClass(site).type; |
814 | 29 | return rs.resolveQualifiedMethod(pos, env, boxedSite, name, pt); |
815 | |
} |
816 | |
|
817 | |
default: |
818 | |
|
819 | |
|
820 | 0 | if (name == names._class) { |
821 | |
|
822 | |
|
823 | 0 | Type t = syms.classType; |
824 | 0 | Type arg = types.boxedClass(site).type; |
825 | 0 | t = new ClassType(t.getEnclosingType(), List.of(arg), t.tsym); |
826 | 0 | return new VarSymbol( |
827 | |
STATIC | PUBLIC | FINAL, names._class, t, site.tsym); |
828 | |
} else { |
829 | 0 | log.error(pos, MsgSym.MESSAGE_CANNOT_DEREF, site); |
830 | 0 | return syms.errSymbol; |
831 | |
} |
832 | |
} |
833 | |
} |
834 | |
|
835 | |
|
836 | |
@Override |
837 | |
public void visitParens(JCParens tree) { |
838 | 0 | Type owntype = attribTree(tree.expr, env, pkind, pt); |
839 | 0 | result = check(tree, owntype, pkind, pkind, pt, pSequenceness); |
840 | 0 | Symbol sym = TreeInfo.symbol(tree); |
841 | 0 | if (sym != null && (sym.kind&(TYP|PCK)) != 0) |
842 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_ILLEGAL_START_OF_TYPE); |
843 | 0 | } |
844 | |
|
845 | |
@Override |
846 | |
public void visitAssign(JCAssign tree) { |
847 | |
|
848 | |
|
849 | |
|
850 | |
|
851 | |
|
852 | 910 | Type owntype = null; |
853 | 910 | JavafxEnv<JavafxAttrContext> dupEnv = env.dup(tree); |
854 | 910 | dupEnv.outer = env; |
855 | 910 | owntype = attribTree(tree.lhs, dupEnv, VAR, Type.noType); |
856 | 910 | boolean hasLhsType = false; |
857 | 910 | if (owntype == null || owntype == syms.javafx_UnspecifiedType) { |
858 | 0 | owntype = attribExpr(tree.rhs, env, Type.noType); |
859 | 0 | hasLhsType = false; |
860 | |
} |
861 | |
else { |
862 | 910 | hasLhsType = true; |
863 | |
} |
864 | |
|
865 | 910 | Symbol lhsSym = JavafxTreeInfo.symbol(tree.lhs); |
866 | 910 | Type capturedType = capture(owntype); |
867 | |
|
868 | 910 | if (hasLhsType) { |
869 | 910 | attribExpr(tree.rhs, dupEnv, owntype); |
870 | |
} |
871 | |
else { |
872 | 0 | if (tree.lhs.getTag() == JCTree.SELECT) { |
873 | 0 | JCFieldAccess fa = (JCFieldAccess)tree.lhs; |
874 | 0 | fa.type = owntype; |
875 | 0 | } |
876 | 0 | else if (tree.lhs.getTag() == JCTree.IDENT) { |
877 | 0 | JCIdent id = (JCIdent)tree.lhs; |
878 | 0 | id.type = owntype; |
879 | |
} |
880 | |
|
881 | 0 | attribTree(tree.lhs, dupEnv, VAR, owntype); |
882 | 0 | lhsSym.type = owntype; |
883 | |
} |
884 | 910 | lhsSym.flags_field |= JavafxFlags.ASSIGNED_TO; |
885 | 910 | result = check(tree, capturedType, VAL, pkind, pt, pSequenceness); |
886 | |
|
887 | 910 | if (tree.rhs != null && tree.lhs.getTag() == JCTree.IDENT) { |
888 | 752 | JFXVar lhsVar = varSymToTree.get(lhsSym); |
889 | 752 | if (lhsVar != null && (lhsVar.getJFXType() instanceof JFXTypeUnknown)) { |
890 | 523 | if (lhsVar.type == null || |
891 | |
lhsVar.type == syms.javafx_AnyType || |
892 | |
lhsVar.type == syms.javafx_UnspecifiedType) { |
893 | 2 | if (tree.rhs.type != null && lhsVar.type != tree.rhs.type) { |
894 | 2 | lhsVar.type = lhsSym.type = tree.rhs.type; |
895 | 2 | JCExpression jcExpr = make.at(tree.pos()).Ident(lhsSym); |
896 | 2 | lhsVar.setJFXType(make.at(tree.pos()).TypeClass(jcExpr, lhsVar.getJFXType().getCardinality())); |
897 | |
} |
898 | |
} |
899 | |
} |
900 | |
} |
901 | 910 | } |
902 | |
|
903 | |
@Override |
904 | |
public void visitVarDef(JCVariableDecl tree) { |
905 | 0 | assert false : "SHOULD NOT REACH HERE"; |
906 | 0 | } |
907 | |
|
908 | |
public void finishVar(JFXVar tree, JavafxEnv<JavafxAttrContext> env) { |
909 | 3276 | VarSymbol v = tree.sym; |
910 | 3276 | Type declType = attribType(tree.getJFXType(), env); |
911 | 3276 | if (declType != syms.javafx_UnspecifiedType) { |
912 | 1873 | result = tree.type = v.type = declType; |
913 | |
} |
914 | |
|
915 | |
|
916 | |
|
917 | |
|
918 | |
|
919 | |
|
920 | |
|
921 | |
|
922 | 3276 | JavafxEnv<JavafxAttrContext> lintEnv = env; |
923 | 3557 | while (lintEnv.info.lint == null) |
924 | 281 | lintEnv = lintEnv.next; |
925 | 3276 | Lint lint = lintEnv.info.lint.augment(v.attributes_field, v.flags()); |
926 | 3276 | Lint prevLint = chk.setLint(lint); |
927 | 3276 | JavaFileObject prev = log.useSource(env.toplevel.sourcefile); |
928 | |
|
929 | |
try { |
930 | 3276 | chk.checkDeprecatedAnnotation(tree.pos(), v); |
931 | |
|
932 | |
Type initType; |
933 | 3276 | if (tree.init != null) { |
934 | |
|
935 | |
|
936 | 1482 | Scope initScope = new Scope(new MethodSymbol(BLOCK, v.name, null, env.enclClass.sym)); |
937 | 1482 | initScope.next = env.info.scope; |
938 | 1482 | JavafxEnv<JavafxAttrContext> initEnv = |
939 | |
env.dup(tree, env.info.dup(initScope)); |
940 | 1482 | initEnv.outer = env; |
941 | 1482 | initEnv.info.lint = lint; |
942 | 1482 | if ((tree.getModifiers().flags & STATIC) != 0) |
943 | 42 | initEnv.info.staticLevel++; |
944 | |
|
945 | |
|
946 | |
|
947 | |
|
948 | 1482 | v.pos = Position.MAXPOS; |
949 | 1482 | initType = attribExpr(tree.init, initEnv, declType); |
950 | 1479 | initType = chk.checkNonVoid(tree.pos(), initType); |
951 | 1479 | chk.checkType(tree.pos(), initType, declType, Sequenceness.DISALLOWED); |
952 | 1479 | if (initType == syms.botType |
953 | |
|| initType == syms.unreachableType) |
954 | 1 | initType = syms.objectType; |
955 | 1478 | else if (initType.isPrimitive() |
956 | |
&& initType != syms.javafx_NumberType |
957 | |
&& initType != syms.javafx_IntegerType |
958 | |
&& initType != syms.javafx_BooleanType) |
959 | 5 | initType = types.boxedClass(initType).type; |
960 | 1473 | else if (types.isArray(initType)) { |
961 | 7 | initType = types.elemtype(initType); |
962 | 7 | if (initType.isPrimitive()) { |
963 | 1 | if (initType == syms.shortType || |
964 | |
initType == syms.byteType) |
965 | 1 | initType = syms.javafx_IntegerType; |
966 | 0 | else if (initType == syms.floatType) |
967 | 0 | initType = syms.javafx_NumberType; |
968 | 0 | else if (initType == syms.charType || |
969 | |
initType == syms.longType) |
970 | 0 | initType = types.boxedClass(initType).type; |
971 | |
} |
972 | 7 | initType = types.sequenceType(initType); |
973 | |
} |
974 | 1479 | } |
975 | 1794 | else if (tree.type != null) |
976 | 1675 | initType = tree.type; |
977 | |
else |
978 | 119 | initType = syms.objectType; |
979 | 3273 | if (declType == syms.javafx_UnspecifiedType && v.type == null) |
980 | 1398 | result = tree.type = v.type = initType; |
981 | 3273 | chk.validateAnnotations(tree.mods.annotations, v); |
982 | |
} |
983 | |
finally { |
984 | 3276 | chk.setLint(prevLint); |
985 | 3276 | log.useSource(prev); |
986 | 3273 | } |
987 | 3273 | } |
988 | |
|
989 | |
|
990 | |
@Override |
991 | |
public void visitVar(JFXVar tree) { |
992 | 3276 | Symbol sym = tree.sym; |
993 | 3276 | sym.complete(); |
994 | |
|
995 | 3273 | JFXOnReplace onReplace = tree.getOnReplace(); |
996 | 3273 | if (onReplace != null) { |
997 | 120 | JFXVar oldValue = onReplace.getOldValue(); |
998 | 120 | if (oldValue != null && oldValue.type == null) { |
999 | 61 | oldValue.type = tree.type; |
1000 | |
} |
1001 | |
|
1002 | 120 | JFXVar newElements = onReplace.getNewElements(); |
1003 | 120 | if (newElements != null && newElements.type == null) |
1004 | 28 | newElements.type = tree.type; |
1005 | |
|
1006 | |
|
1007 | 120 | if (env.info.scope.owner.kind == TYP) { |
1008 | |
|
1009 | |
|
1010 | |
|
1011 | 113 | long flags = tree.getModifiers().flags; |
1012 | 113 | JavafxEnv<JavafxAttrContext> localEnv = newLocalEnv(tree); |
1013 | 113 | if ((flags & STATIC) != 0) { |
1014 | 0 | localEnv.info.staticLevel++; |
1015 | |
} |
1016 | 113 | attribStat(onReplace, localEnv); |
1017 | 113 | } else { |
1018 | |
|
1019 | 7 | JavafxEnv<JavafxAttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup())); |
1020 | 7 | attribStat(onReplace, localEnv); |
1021 | 7 | localEnv.info.scope.leave(); |
1022 | |
} |
1023 | |
|
1024 | |
} |
1025 | 3273 | } |
1026 | |
|
1027 | |
|
1028 | |
|
1029 | |
|
1030 | |
|
1031 | |
|
1032 | |
|
1033 | |
|
1034 | |
|
1035 | |
public void finishOverrideAttribute(JFXOverrideAttribute tree, JavafxEnv<JavafxAttrContext> env) { |
1036 | 9 | VarSymbol v = tree.sym; |
1037 | 9 | Type declType = tree.getId().type; |
1038 | 9 | result = tree.type = declType; |
1039 | |
|
1040 | |
|
1041 | |
|
1042 | |
|
1043 | |
|
1044 | |
|
1045 | 9 | JavafxEnv<JavafxAttrContext> lintEnv = env; |
1046 | 9 | while (lintEnv.info.lint == null) { |
1047 | 0 | lintEnv = lintEnv.next; |
1048 | |
} |
1049 | 9 | Lint lint = lintEnv.info.lint.augment(v.attributes_field, v.flags()); |
1050 | 9 | Lint prevLint = chk.setLint(lint); |
1051 | 9 | JavaFileObject prev = log.useSource(env.toplevel.sourcefile); |
1052 | |
|
1053 | |
try { |
1054 | 9 | if (tree.getInitializer() != null) { |
1055 | |
|
1056 | |
|
1057 | 9 | Scope initScope = new Scope(new MethodSymbol(BLOCK, v.name, null, env.enclClass.sym)); |
1058 | 9 | initScope.next = env.info.scope; |
1059 | 9 | JavafxEnv<JavafxAttrContext> initEnv = |
1060 | |
env.dup(tree, env.info.dup(initScope)); |
1061 | 9 | initEnv.outer = env; |
1062 | |
|
1063 | |
|
1064 | |
|
1065 | |
|
1066 | 9 | v.pos = Position.MAXPOS; |
1067 | |
|
1068 | 9 | attribExpr(tree.getInitializer(), initEnv, declType); |
1069 | |
} |
1070 | |
} finally { |
1071 | 9 | chk.setLint(prevLint); |
1072 | 9 | log.useSource(prev); |
1073 | 9 | } |
1074 | 9 | } |
1075 | |
|
1076 | |
@Override |
1077 | |
public void visitOverrideAttribute(JFXOverrideAttribute tree) { |
1078 | |
|
1079 | 9 | JCIdent id = tree.getId(); |
1080 | 9 | JFXOnReplace onr = tree.getOnReplace(); |
1081 | |
|
1082 | |
|
1083 | |
|
1084 | 9 | JavafxEnv<JavafxAttrContext> localEnv = newLocalEnv(tree); |
1085 | |
|
1086 | 9 | Type type = attribExpr(id, localEnv); |
1087 | 9 | tree.type = type; |
1088 | 9 | Symbol sym = id.sym; |
1089 | |
|
1090 | 9 | if (onr != null) { |
1091 | 6 | attribStat(onr, localEnv); |
1092 | 6 | JFXVar oldValue = onr.getOldValue(); |
1093 | 6 | if (oldValue != null && oldValue.type == null) { |
1094 | 0 | oldValue.type = type; |
1095 | |
} |
1096 | 6 | JFXVar newElements = onr.getNewElements(); |
1097 | 6 | if (newElements != null && newElements.type == null) { |
1098 | 0 | newElements.type = type; |
1099 | |
} |
1100 | |
} |
1101 | |
|
1102 | |
|
1103 | 9 | if (sym.kind != VAR) { |
1104 | 0 | log.error(id.pos(), MsgSym.MESSAGE_JAVAFX_MUST_BE_AN_ATTRIBUTE, id.name); |
1105 | |
} else { |
1106 | 9 | VarSymbol v = (VarSymbol) sym; |
1107 | 9 | tree.sym = v; |
1108 | 9 | finishOverrideAttribute(tree, env); |
1109 | |
} |
1110 | 9 | } |
1111 | |
|
1112 | |
|
1113 | |
|
1114 | |
|
1115 | |
|
1116 | |
|
1117 | |
|
1118 | |
|
1119 | |
|
1120 | |
|
1121 | |
|
1122 | |
|
1123 | |
|
1124 | |
|
1125 | |
|
1126 | |
|
1127 | |
|
1128 | |
@Override |
1129 | |
public void visitOnReplace(JFXOnReplace tree) { |
1130 | 126 | JFXVar lastIndex = tree.getLastIndex(); |
1131 | 126 | if (lastIndex != null) { |
1132 | 21 | lastIndex.mods.flags |= Flags.FINAL; |
1133 | 21 | attribVar(lastIndex, env); |
1134 | 21 | lastIndex.sym.type = syms.intType; |
1135 | |
} |
1136 | 126 | JFXVar newElements = tree.getNewElements(); |
1137 | 126 | if (newElements != null) { |
1138 | 28 | newElements.mods.flags |= Flags.FINAL; |
1139 | 28 | attribVar(newElements, env); |
1140 | |
} |
1141 | |
|
1142 | 126 | JFXVar firstIndex = tree.getFirstIndex(); |
1143 | 126 | if (firstIndex != null) { |
1144 | 21 | firstIndex.mods.flags |= Flags.FINAL; |
1145 | 21 | attribVar(firstIndex, env); |
1146 | 21 | firstIndex.sym.type = syms.intType; |
1147 | |
} |
1148 | |
|
1149 | 126 | JFXVar oldValue = tree.getOldValue(); |
1150 | 126 | if (oldValue != null) { |
1151 | 61 | oldValue.mods.flags |= Flags.FINAL; |
1152 | 61 | attribVar(oldValue, env); |
1153 | |
} |
1154 | 126 | attribStat(tree.getBody(), env); |
1155 | 126 | } |
1156 | |
|
1157 | |
|
1158 | |
|
1159 | 399 | ArrayList<JFXForExpressionInClause> forClauses = null; |
1160 | |
|
1161 | |
@Override |
1162 | |
public void visitForExpression(JFXForExpression tree) { |
1163 | 198 | JavafxEnv<JavafxAttrContext> forExprEnv = |
1164 | |
env.dup(tree, env.info.dup(env.info.scope.dup())); |
1165 | |
|
1166 | 198 | if (forClauses == null) |
1167 | 72 | forClauses = new ArrayList<JFXForExpressionInClause>(); |
1168 | 198 | int forClausesOldSize = forClauses.size(); |
1169 | |
|
1170 | 198 | for (ForExpressionInClauseTree cl : tree.getInClauses()) { |
1171 | 206 | JFXForExpressionInClause clause = (JFXForExpressionInClause)cl; |
1172 | 206 | forClauses.add(clause); |
1173 | 206 | Type exprType = types.upperBound(attribExpr((JCExpression)clause.getSequenceExpression(), forExprEnv)); |
1174 | 206 | if (clause.getVar() != null && |
1175 | |
clause.getVar().getJFXType() instanceof JFXTypeUnknown && |
1176 | |
exprType.allparams() != null && exprType.allparams().nonEmpty()) { |
1177 | 201 | Type sequenceType = types.upperBound(exprType.allparams().last()); |
1178 | 201 | clause.getVar().setJFXType(make.TypeClass(make.Ident(sequenceType.tsym), Cardinality.SINGLETON)); |
1179 | 201 | clause.getVar().type = sequenceType; |
1180 | |
} |
1181 | 206 | attribVar(clause.getVar(), forExprEnv); |
1182 | 206 | chk.checkNonVoid(((JCTree)clause).pos(), exprType); |
1183 | |
Type elemtype; |
1184 | |
|
1185 | 206 | Type base = types.asSuper(exprType, syms.javafx_SequenceType.tsym); |
1186 | 206 | if (base == null) { |
1187 | 5 | elemtype = exprType; |
1188 | |
} else { |
1189 | 201 | List<Type> iterableParams = base.allparams(); |
1190 | 201 | if (iterableParams.isEmpty()) { |
1191 | 0 | elemtype = syms.errType; |
1192 | |
} else { |
1193 | 201 | elemtype = types.upperBound(iterableParams.last()); |
1194 | |
} |
1195 | |
} |
1196 | 206 | if (elemtype == syms.errType) { |
1197 | 0 | log.error(((JCTree)(clause.getSequenceExpression())).pos(), MsgSym.MESSAGE_FOREACH_NOT_APPLICABLE_TO_TYPE); |
1198 | 206 | } else if (elemtype == syms.botType || elemtype == syms.unreachableType) { |
1199 | 2 | elemtype = syms.objectType; |
1200 | |
} else { |
1201 | |
|
1202 | 204 | Type unboxed = types.unboxedType(elemtype); |
1203 | 204 | if (unboxed != Type.noType) { |
1204 | 153 | elemtype = unboxed; |
1205 | |
} |
1206 | |
} |
1207 | |
|
1208 | 206 | clause.getVar().type = elemtype; |
1209 | 206 | clause.getVar().sym.type = elemtype; |
1210 | |
|
1211 | 206 | chk.checkType(clause.getSequenceExpression().pos(), elemtype, clause.var.sym.type, Sequenceness.DISALLOWED); |
1212 | |
|
1213 | 206 | if (clause.getWhereExpression() != null) { |
1214 | 36 | attribExpr(clause.getWhereExpression(), env, syms.booleanType); |
1215 | |
} |
1216 | 206 | } |
1217 | |
|
1218 | 198 | forExprEnv.tree = tree; |
1219 | 198 | attribExpr(tree.getBodyExpression(), forExprEnv); |
1220 | |
|
1221 | 198 | Type bodyType = tree.getBodyExpression().type; |
1222 | 198 | Type owntype = (bodyType == null || bodyType == syms.voidType)? |
1223 | |
syms.voidType : |
1224 | |
types.isSequence(bodyType) ? |
1225 | |
bodyType : |
1226 | |
types.sequenceType(bodyType); |
1227 | 404 | while (forClauses.size() > forClausesOldSize) |
1228 | 206 | forClauses.remove(forClauses.size()-1); |
1229 | 198 | forExprEnv.info.scope.leave(); |
1230 | 198 | result = check(tree, owntype, VAL, pkind, pt, pSequenceness); |
1231 | 198 | } |
1232 | |
|
1233 | |
@Override |
1234 | |
public void visitForExpressionInClause(JFXForExpressionInClause that) { |
1235 | 0 | assert false : "should not reach here"; |
1236 | 0 | } |
1237 | |
|
1238 | |
public void visitIndexof(JFXIndexof tree) { |
1239 | 28 | for (int n = forClauses == null ? 0 : forClauses.size(); ; ) { |
1240 | 29 | if (--n < 0) { |
1241 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_JAVAFX_INDEXOF_NOT_FOUND, tree.fname); |
1242 | 0 | break; |
1243 | |
} |
1244 | 29 | JFXForExpressionInClause clause = forClauses.get(n); |
1245 | 29 | if (clause.getVar().getName() == tree.fname) { |
1246 | 28 | tree.clause = clause; |
1247 | 28 | clause.setIndexUsed(true); |
1248 | 28 | break; |
1249 | |
} |
1250 | 1 | } |
1251 | 28 | result = check(tree, syms.javafx_IntegerType, VAL, |
1252 | |
pkind, pt, pSequenceness); |
1253 | 28 | } |
1254 | |
|
1255 | |
@Override |
1256 | |
public void visitSkip(JCSkip tree) { |
1257 | 0 | result = null; |
1258 | 0 | } |
1259 | |
|
1260 | |
public void visitBindExpression(JFXBindExpression tree) { |
1261 | 0 | Type owntype = attribTree(tree.getExpression(), env, VAL, pt); |
1262 | 0 | result = check(tree, owntype, pkind, pkind, pt, pSequenceness); |
1263 | 0 | } |
1264 | |
|
1265 | |
@Override |
1266 | |
public void visitBlock(JCBlock tree) { |
1267 | 240 | if (env.info.scope.owner.kind == TYP) { |
1268 | |
|
1269 | |
|
1270 | |
|
1271 | 0 | JavafxEnv<JavafxAttrContext> localEnv = newLocalEnv(tree); |
1272 | 0 | if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; |
1273 | 0 | memberEnter.memberEnter(tree.stats, localEnv); |
1274 | 0 | attribStats(tree.stats, localEnv); |
1275 | 0 | } else { |
1276 | |
|
1277 | 240 | JavafxEnv<JavafxAttrContext> localEnv = |
1278 | |
env.dup(tree, env.info.dup(env.info.scope.dup())); |
1279 | 240 | localEnv.outer = env; |
1280 | 240 | memberEnter.memberEnter(tree.stats, localEnv); |
1281 | 240 | attribStats(tree.stats, localEnv); |
1282 | 240 | localEnv.info.scope.leave(); |
1283 | |
} |
1284 | 240 | result = null; |
1285 | 240 | } |
1286 | |
|
1287 | |
@Override |
1288 | |
public void visitBlockExpression(JFXBlockExpression tree) { |
1289 | |
|
1290 | 1926 | Scope localScope = new Scope(env.info.scope.owner); |
1291 | 1926 | localScope.next = env.info.scope; |
1292 | 1926 | JavafxEnv<JavafxAttrContext> localEnv = |
1293 | |
env.dup(tree, env.info.dup(localScope)); |
1294 | 1926 | localEnv.outer = env; |
1295 | |
|
1296 | 1926 | if (env.tree instanceof JFXFunctionDefinition && |
1297 | |
env.enclClass.runMethod == env.tree) { |
1298 | 385 | env.enclClass.runBodyScope = localEnv.info.scope; |
1299 | |
} |
1300 | |
else |
1301 | 1541 | localEnv.info.scope.owner = new MethodSymbol(BLOCK, names.empty, null, env.enclClass.sym); |
1302 | 1926 | memberEnter.memberEnter(tree.stats, localEnv); |
1303 | 1926 | boolean canReturn = true; |
1304 | 1926 | boolean unreachableReported = false; |
1305 | 6402 | for (List<JCStatement> l = tree.stats; l.nonEmpty(); l = l.tail) { |
1306 | 4479 | if (! canReturn && ! unreachableReported) { |
1307 | 0 | unreachableReported = true; |
1308 | 0 | log.error(l.head.pos(), MsgSym.MESSAGE_UNREACHABLE_STMT); |
1309 | |
} |
1310 | 4479 | Type stype = attribTree(l.head, localEnv, |
1311 | |
NIL, Type.noType, Sequenceness.DISALLOWED); |
1312 | 4476 | if (stype == syms.unreachableType) |
1313 | 213 | canReturn = false; |
1314 | |
} |
1315 | 1923 | Type owntype = null; |
1316 | 1923 | if (tree.value != null) { |
1317 | 1328 | if (! canReturn && ! unreachableReported) |
1318 | 0 | log.error(tree.value.pos(), MsgSym.MESSAGE_UNREACHABLE_STMT); |
1319 | 1328 | owntype = attribExpr(tree.value, localEnv); |
1320 | |
} |
1321 | 1923 | if (owntype == null) { |
1322 | 595 | JCStatement lastStat = tree.stats.last(); |
1323 | 595 | if (lastStat != null) { |
1324 | 469 | if (lastStat.getTag() == JCTree.RETURN && |
1325 | |
((JCReturn)lastStat).expr != null) { |
1326 | 189 | owntype = ((JCReturn)lastStat).expr.type; |
1327 | |
} |
1328 | |
|
1329 | |
} |
1330 | |
|
1331 | 595 | if (owntype == null) { |
1332 | 406 | owntype = syms.voidType; |
1333 | |
} |
1334 | |
} |
1335 | 1923 | if (! canReturn) |
1336 | 213 | owntype = syms.unreachableType; |
1337 | 1923 | result = check(tree, owntype, VAL, pkind, pt, pSequenceness); |
1338 | 1923 | localEnv.info.scope.leave(); |
1339 | 1923 | } |
1340 | |
|
1341 | |
@Override |
1342 | |
public void visitDoLoop(JCDoWhileLoop tree) { |
1343 | 0 | attribStat(tree.body, env.dup(tree)); |
1344 | 0 | attribExpr(tree.cond, env, syms.booleanType); |
1345 | 0 | result = null; |
1346 | 0 | } |
1347 | |
|
1348 | |
@Override |
1349 | |
public void visitWhileLoop(JCWhileLoop tree) { |
1350 | 11 | attribExpr(tree.cond, env, syms.booleanType); |
1351 | 11 | attribStat(tree.body, env.dup(tree)); |
1352 | 11 | result = null; |
1353 | 11 | } |
1354 | |
|
1355 | |
@Override |
1356 | |
public void visitForLoop(JCForLoop tree) { |
1357 | 0 | assert false; |
1358 | 0 | } |
1359 | |
|
1360 | |
@Override |
1361 | |
public void visitForeachLoop(JCEnhancedForLoop tree) { |
1362 | 0 | assert false; |
1363 | 0 | } |
1364 | |
|
1365 | |
@Override |
1366 | |
public void visitLabelled(JCLabeledStatement tree) { |
1367 | 0 | assert false; |
1368 | 0 | } |
1369 | |
|
1370 | |
@Override |
1371 | |
public void visitSwitch(JCSwitch tree) { |
1372 | 0 | assert false; |
1373 | 0 | } |
1374 | |
|
1375 | |
@Override |
1376 | |
public void visitNewArray(JCNewArray tree) { |
1377 | 0 | assert false; |
1378 | 0 | } |
1379 | |
|
1380 | |
|
1381 | |
@Override |
1382 | |
public void visitNewClass(JCNewClass tree) { |
1383 | 0 | assert false : "remove me"; |
1384 | 0 | } |
1385 | |
|
1386 | |
@Override |
1387 | |
public void visitInstanciate(JFXInstanciate tree) { |
1388 | 641 | Type owntype = syms.errType; |
1389 | |
|
1390 | |
|
1391 | |
|
1392 | 641 | JavafxEnv<JavafxAttrContext> localEnv = newLocalEnv(tree); |
1393 | |
|
1394 | 641 | List<JFXVar> vars = tree.getLocalvars(); |
1395 | 641 | memberEnter.memberEnter(vars, localEnv); |
1396 | 649 | for (List<JFXVar> l = vars; l.nonEmpty(); l = l.tail) |
1397 | 8 | attribExpr(l.head, localEnv); |
1398 | |
|
1399 | |
|
1400 | |
|
1401 | 641 | JFXClassDeclaration cdef = tree.getClassBody(); |
1402 | |
|
1403 | |
|
1404 | |
|
1405 | 641 | JCExpression clazz = tree.getIdentifier(); |
1406 | |
|
1407 | |
|
1408 | |
|
1409 | 641 | Type clazztype = chk.checkClassType( |
1410 | |
clazz.pos(), attribType(clazz, env), true); |
1411 | 641 | chk.validate(clazz); |
1412 | 641 | if (!clazztype.tsym.isInterface() && |
1413 | |
clazztype.getEnclosingType().tag == CLASS) { |
1414 | |
|
1415 | 0 | rs.resolveImplicitThis(tree.pos(), env, clazztype); |
1416 | |
} |
1417 | |
|
1418 | |
|
1419 | 641 | List<Type> argtypes = attribArgs(tree.getArgs(), localEnv); |
1420 | |
|
1421 | |
|
1422 | 641 | if (clazztype.tag == CLASS) { |
1423 | |
|
1424 | 641 | if (cdef == null && |
1425 | |
(clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) { |
1426 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_ABSTRACT_CANNOT_BE_INSTANTIATED, |
1427 | |
clazztype.tsym); |
1428 | 641 | } else if (cdef != null && clazztype.tsym.isInterface()) { |
1429 | |
|
1430 | |
|
1431 | 12 | if (!argtypes.isEmpty()) |
1432 | 0 | log.error(tree.getArgs().head.pos(), MsgSym.MESSAGE_ANON_CLASS_IMPL_INTF_NO_ARGS); |
1433 | |
|
1434 | |
|
1435 | |
|
1436 | 12 | argtypes = List.nil(); |
1437 | |
} |
1438 | |
|
1439 | |
|
1440 | |
|
1441 | |
|
1442 | |
else { |
1443 | 629 | localEnv.info.selectSuper = cdef != null; |
1444 | 629 | localEnv.info.varArgs = false; |
1445 | |
|
1446 | 629 | if (! types.isJFXClass(clazztype.tsym)) |
1447 | 83 | tree.constructor = rs.resolveConstructor( |
1448 | |
tree.pos(), localEnv, clazztype, argtypes, null); |
1449 | |
|
1450 | |
|
1451 | |
|
1452 | |
|
1453 | |
|
1454 | |
|
1455 | |
|
1456 | |
|
1457 | |
|
1458 | |
|
1459 | |
|
1460 | |
|
1461 | |
|
1462 | |
|
1463 | |
|
1464 | |
} |
1465 | |
|
1466 | 641 | if (cdef != null) { |
1467 | |
|
1468 | |
|
1469 | |
|
1470 | |
|
1471 | |
|
1472 | |
|
1473 | |
|
1474 | |
|
1475 | |
|
1476 | |
|
1477 | |
|
1478 | |
|
1479 | |
|
1480 | |
|
1481 | |
|
1482 | |
|
1483 | |
|
1484 | |
|
1485 | |
|
1486 | |
|
1487 | |
|
1488 | |
|
1489 | |
|
1490 | |
|
1491 | |
|
1492 | |
|
1493 | |
|
1494 | |
|
1495 | |
|
1496 | |
|
1497 | |
|
1498 | |
|
1499 | |
|
1500 | |
|
1501 | |
|
1502 | 26 | cdef.mods.flags |= STATIC; |
1503 | |
|
1504 | |
|
1505 | |
|
1506 | |
|
1507 | |
|
1508 | |
|
1509 | |
|
1510 | |
|
1511 | 26 | if (cdef.sym == null) |
1512 | 0 | enter.classEnter(cdef, env); |
1513 | |
|
1514 | 26 | attribStat(cdef, localEnv); |
1515 | 26 | attribClass(cdef.pos(), null, cdef.sym); |
1516 | |
|
1517 | |
|
1518 | 26 | clazztype = cdef.sym.type; |
1519 | 26 | Symbol sym = rs.resolveConstructor( |
1520 | |
tree.pos(), localEnv, clazztype, argtypes, |
1521 | |
List.<Type>nil(), true, false); |
1522 | |
|
1523 | 26 | tree.constructor = sym; |
1524 | |
} |
1525 | |
|
1526 | |
|
1527 | 641 | owntype = clazz.type; |
1528 | |
} |
1529 | |
|
1530 | 641 | for (JFXObjectLiteralPart localPt : tree.getParts()) { |
1531 | 736 | JFXObjectLiteralPart part = (JFXObjectLiteralPart)localPt; |
1532 | 736 | Symbol memberSym = rs.findIdentInType(env, clazz.type, part.name, VAR); |
1533 | 736 | memberSym = rs.access(memberSym, localPt.pos(), clazz.type, part.name, true); |
1534 | 736 | memberSym.complete(); |
1535 | 736 | attribExpr(part.getExpression(), localEnv, memberSym.type); |
1536 | 736 | part.type = memberSym.type; |
1537 | 736 | part.sym = memberSym; |
1538 | 736 | } |
1539 | |
|
1540 | 641 | result = check(tree, owntype, VAL, pkind, pt, pSequenceness); |
1541 | 641 | localEnv.info.scope.leave(); |
1542 | 641 | } |
1543 | |
|
1544 | |
|
1545 | |
|
1546 | |
public JCExpression makeNullCheck(JCExpression arg) { |
1547 | |
|
1548 | 0 | Name name = TreeInfo.name(arg); |
1549 | 0 | if (name == names._this || name == names._super) return arg; |
1550 | |
|
1551 | 0 | int optag = JCTree.NULLCHK; |
1552 | 0 | JCUnary tree = make.at(arg.pos).Unary(optag, arg); |
1553 | 0 | tree.operator = syms.nullcheck; |
1554 | 0 | tree.type = arg.type; |
1555 | 0 | return tree; |
1556 | |
} |
1557 | |
|
1558 | |
@Override |
1559 | |
public void visitClassDef(JCClassDecl tree) { |
1560 | 0 | assert false : "Should never reach here"; |
1561 | 0 | } |
1562 | |
|
1563 | |
@Override |
1564 | |
public void visitMethodDef(JCMethodDecl tree) { |
1565 | 0 | assert false : "Should never reach here"; |
1566 | 0 | } |
1567 | |
|
1568 | |
@Override |
1569 | |
public void visitFunctionValue(JFXFunctionValue tree) { |
1570 | 174 | Scope enclScope = JavafxEnter.enterScope(env); |
1571 | 174 | JFXFunctionDefinition def = new JFXFunctionDefinition(make.Modifiers(Flags.SYNTHETIC), defs.lambdaName, tree); |
1572 | 174 | tree.definition = def; |
1573 | 174 | MethodSymbol m = new MethodSymbol(SYNTHETIC, def.name, null, env.enclClass.sym); |
1574 | |
|
1575 | 174 | def.sym = m; |
1576 | 174 | finishOperationDefinition(def, env); |
1577 | 174 | result = tree.type = syms.makeFunctionType((MethodType) def.type); |
1578 | 174 | } |
1579 | |
|
1580 | |
@Override |
1581 | |
public void visitFunctionDefinition(JFXFunctionDefinition tree) { |
1582 | 1307 | MethodSymbol m = tree.sym; |
1583 | 1307 | m.complete(); |
1584 | 1304 | } |
1585 | |
|
1586 | |
|
1587 | |
|
1588 | |
|
1589 | |
|
1590 | |
|
1591 | |
|
1592 | |
|
1593 | |
|
1594 | |
|
1595 | |
|
1596 | |
|
1597 | |
|
1598 | |
|
1599 | |
|
1600 | |
Type searchSupersForParamType (ClassSymbol c, Name name, int paramCount, int paramNum) { |
1601 | 1162 | Type found = null; |
1602 | |
|
1603 | 1162 | for (Scope.Entry e = c.members().lookup(name); |
1604 | 1570 | e.scope != null; |
1605 | 408 | e = e.next()) { |
1606 | 408 | if ((e.sym.kind & MTH) == 0 || |
1607 | |
(e.sym.flags_field & (STATIC|SYNTHETIC)) != 0) |
1608 | 66 | continue; |
1609 | 342 | Type mt = types.memberType(c.type, e.sym); |
1610 | 342 | if (mt == null) |
1611 | 315 | continue; |
1612 | 27 | List<Type> formals = mt.getParameterTypes(); |
1613 | 27 | if (formals.size() != paramCount) |
1614 | 20 | continue; |
1615 | 7 | Type t = paramNum >= 0 ? formals.get(paramNum) : mt.getReturnType(); |
1616 | 7 | if (t == Type.noType) |
1617 | 0 | return t; |
1618 | 7 | if (found == null) |
1619 | 7 | found = t; |
1620 | 0 | else if (t != null && found != t) |
1621 | 0 | return Type.noType; |
1622 | |
} |
1623 | |
|
1624 | 1162 | Type st = types.supertype(c.type); |
1625 | 1162 | if (st.tag == CLASS) { |
1626 | 612 | Type t = searchSupersForParamType((ClassSymbol)st.tsym, name, paramCount, paramNum); |
1627 | 612 | if (t == Type.noType) |
1628 | 0 | return t; |
1629 | 612 | if (found == null) |
1630 | 606 | found = t; |
1631 | 6 | else if (t != null && found != t) |
1632 | 0 | return Type.noType; |
1633 | |
} |
1634 | 1162 | for (List<Type> l = types.interfaces(c.type); |
1635 | 1218 | l.nonEmpty(); |
1636 | 56 | l = l.tail) { |
1637 | 56 | Type t = searchSupersForParamType((ClassSymbol)l.head.tsym, name, paramCount, paramNum); |
1638 | 56 | if (t == Type.noType) |
1639 | 0 | return t; |
1640 | 56 | if (found == null) |
1641 | 53 | found = t; |
1642 | 3 | else if (t != null && found != t) |
1643 | 0 | return Type.noType; |
1644 | |
} |
1645 | 1162 | return found; |
1646 | |
} |
1647 | |
|
1648 | |
public void finishOperationDefinition(JFXFunctionDefinition tree, JavafxEnv<JavafxAttrContext> env) { |
1649 | 1240 | MethodSymbol m = tree.sym; |
1650 | 1240 | JFXFunctionValue opVal = tree.operation; |
1651 | 1240 | JavafxEnv<JavafxAttrContext> localEnv = memberEnter.methodEnv(tree, env); |
1652 | |
Type returnType; |
1653 | |
|
1654 | |
|
1655 | |
|
1656 | 1240 | JavafxEnv<JavafxAttrContext> lintEnv = env; |
1657 | 1383 | while (lintEnv.info.lint == null) |
1658 | 143 | lintEnv = lintEnv.next; |
1659 | |
|
1660 | 1240 | JavaFileObject prev = log.useSource(env.toplevel.sourcefile); |
1661 | 1240 | Lint lint = lintEnv.info.lint.augment(m.attributes_field, m.flags()); |
1662 | 1240 | Lint prevLint = chk.setLint(lint); |
1663 | |
try { |
1664 | 1240 | chk.checkDeprecatedAnnotation(tree.pos(), m); |
1665 | |
|
1666 | 1240 | localEnv.info.lint = lint; |
1667 | |
|
1668 | 1240 | ClassSymbol owner = env.enclClass.sym; |
1669 | 1240 | if ((owner.flags() & ANNOTATION) != 0 && |
1670 | |
tree.operation.funParams.nonEmpty()) |
1671 | 0 | log.error(tree.operation.funParams.head.pos(), |
1672 | |
MsgSym.MESSAGE_INTF_ANNOTATION_MEMBERS_CANNOT_HAVE_PARAMS); |
1673 | |
|
1674 | |
|
1675 | 1240 | ListBuffer<Type> argbuf = new ListBuffer<Type>(); |
1676 | 1240 | List<Type> pparam = null; |
1677 | 1240 | MethodType mtype = null; |
1678 | 1240 | if (pt.tag == TypeTags.METHOD || pt instanceof FunctionType) { |
1679 | 23 | mtype = pt.asMethodType(); |
1680 | 23 | pparam = mtype.getParameterTypes(); |
1681 | |
} |
1682 | 1240 | int paramNum = 0; |
1683 | 1240 | List<JFXVar> params = tree.getParameters(); |
1684 | 1240 | int paramCount = params.size(); |
1685 | 2341 | for (List<JFXVar> l = params; l.nonEmpty(); l = l.tail) { |
1686 | 1101 | JFXVar pvar = l.head; |
1687 | |
Type type; |
1688 | 1101 | if (pparam != null && pparam.nonEmpty()) { |
1689 | 9 | type = pparam.head; |
1690 | 9 | pparam = pparam.tail; |
1691 | |
} |
1692 | |
else { |
1693 | 1092 | type = syms.objectType; |
1694 | 1092 | if (pvar.getJFXType() instanceof JFXTypeUnknown) { |
1695 | 13 | Type t = searchSupersForParamType (owner, m.name, paramCount, paramNum); |
1696 | 13 | if (t == Type.noType) |
1697 | 0 | log.warning(pvar.pos(), MsgSym.MESSAGE_JAVAFX_AMBIGUOUS_PARAM_TYPE_FROM_SUPER); |
1698 | 13 | else if (t != null) |
1699 | 0 | type = t; |
1700 | |
} |
1701 | |
} |
1702 | 1101 | pvar.type = type; |
1703 | 1101 | type = attribVar(pvar, localEnv); |
1704 | 1101 | argbuf.append(type); |
1705 | 1101 | paramNum++; |
1706 | |
} |
1707 | 1240 | returnType = syms.unknownType; |
1708 | 1240 | if (opVal.getJFXReturnType().getTag() != JavafxTag.TYPEUNKNOWN) |
1709 | 739 | returnType = attribType(tree.getJFXReturnType(), localEnv); |
1710 | 501 | else if (mtype != null) { |
1711 | 20 | Type mrtype = mtype.getReturnType(); |
1712 | 20 | if (mrtype != null && mrtype.tag != TypeTags.NONE) |
1713 | 20 | returnType = mrtype; |
1714 | 20 | } else { |
1715 | |
|
1716 | |
|
1717 | |
|
1718 | 481 | Type t = searchSupersForParamType (owner, m.name, paramCount, -1); |
1719 | 481 | if (t == Type.noType) |
1720 | 0 | log.warning(tree.pos(), MsgSym.MESSAGE_JAVAFX_AMBIGUOUS_RETURN_TYPE_FROM_SUPER); |
1721 | 481 | else if (t != null) |
1722 | 7 | returnType = t; |
1723 | |
} |
1724 | 1240 | if (returnType == syms.javafx_java_lang_VoidType) |
1725 | 0 | returnType = syms.voidType; |
1726 | 1240 | mtype = new MethodType(argbuf.toList(), |
1727 | |
returnType, |
1728 | |
List.<Type>nil(), |
1729 | |
syms.methodClass); |
1730 | 1240 | m.type = mtype; |
1731 | |
|
1732 | 1240 | if (tree.getBodyExpression() == null) { |
1733 | |
|
1734 | |
|
1735 | |
|
1736 | 10 | if ((owner.flags() & INTERFACE) == 0 && |
1737 | |
(tree.mods.flags & (ABSTRACT | NATIVE)) == 0 && |
1738 | |
!relax) |
1739 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_MISSING_METH_BODY_OR_DECL_ABSTRACT); |
1740 | 10 | else if (returnType == syms.unknownType) |
1741 | |
|
1742 | |
|
1743 | 0 | returnType = syms.javafx_AnyType; |
1744 | 1230 | } else if ((owner.flags() & INTERFACE) != 0) { |
1745 | 0 | log.error(tree.getBodyExpression().pos(), MsgSym.MESSAGE_INTF_METH_CANNOT_HAVE_BODY); |
1746 | 1230 | } else if ((tree.mods.flags & ABSTRACT) != 0) { |
1747 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_ABSTRACT_METH_CANNOT_HAVE_BODY); |
1748 | 1230 | } else if ((tree.mods.flags & NATIVE) != 0) { |
1749 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_NATIVE_METH_CANNOT_HAVE_BODY); |
1750 | |
} else { |
1751 | 1230 | JFXBlockExpression body = opVal.getBodyExpression(); |
1752 | 1230 | if (body.value == null && returnType == syms.unknownType) { |
1753 | 172 | JCStatement last = body.stats.last(); |
1754 | 172 | if (last instanceof JCReturn) { |
1755 | 9 | ListBuffer<JCStatement> rstats = |
1756 | |
new ListBuffer<JCStatement>(); |
1757 | 9 | for (List<JCStatement> l = body.stats; |
1758 | 14 | l.tail.tail != null; |
1759 | 5 | l = l.tail) { |
1760 | 5 | rstats.append(l.head); |
1761 | |
} |
1762 | 9 | body.stats = rstats.toList(); |
1763 | 9 | body.value = ((JCReturn) last).expr; |
1764 | |
} |
1765 | |
} |
1766 | |
|
1767 | 1230 | Type typeToCheck = returnType; |
1768 | 1230 | if(tree.name == defs.runMethodName) { |
1769 | 385 | typeToCheck = Type.noType; |
1770 | |
} |
1771 | 845 | else if (returnType == syms.voidType) { |
1772 | 94 | typeToCheck = Type.noType; |
1773 | |
} |
1774 | |
|
1775 | 1230 | Type bodyType = attribExpr(body, localEnv, typeToCheck); |
1776 | 1227 | if (body.value == null) { |
1777 | 505 | if (returnType == syms.unknownType) |
1778 | 163 | returnType = syms.javafx_VoidType; |
1779 | |
} else { |
1780 | 722 | if (returnType == syms.unknownType) |
1781 | 311 | returnType = bodyType == syms.unreachableType ? syms.javafx_VoidType : bodyType; |
1782 | 411 | else if (returnType != syms.javafx_VoidType && tree.getName() != defs.runMethodName) |
1783 | 98 | chk.checkType(tree.pos(), bodyType, returnType, Sequenceness.DISALLOWED); |
1784 | |
} |
1785 | |
} |
1786 | 1237 | localEnv.info.scope.leave(); |
1787 | |
|
1788 | 1237 | mtype.restype = returnType; |
1789 | 1237 | result = tree.type = mtype; |
1790 | |
|
1791 | |
|
1792 | |
|
1793 | 1237 | if (m.owner instanceof ClassSymbol) { |
1794 | |
|
1795 | 1237 | fixOverride(tree, m); |
1796 | 1237 | chk.checkOverride(tree, m); |
1797 | |
} |
1798 | |
} |
1799 | |
finally { |
1800 | 1240 | chk.setLint(prevLint); |
1801 | 1240 | log.useSource(prev); |
1802 | 1237 | } |
1803 | |
|
1804 | |
|
1805 | |
|
1806 | |
|
1807 | |
|
1808 | 1237 | List<VarSymbol> paramSyms = List.<VarSymbol>nil(); |
1809 | 1237 | List<Type> paramTypes = List.<Type>nil(); |
1810 | 1237 | for (JFXVar var : tree.getParameters()) { |
1811 | 1098 | paramSyms = paramSyms.append(var.sym); |
1812 | 1098 | paramTypes = paramTypes.append(var.type); |
1813 | |
} |
1814 | |
|
1815 | 1237 | m.params = paramSyms; |
1816 | 1237 | if (m.type != null && m.type instanceof MethodType) { |
1817 | 1237 | ((MethodType)m.type).argtypes = paramTypes; |
1818 | |
} |
1819 | 1237 | } |
1820 | |
|
1821 | |
@Override |
1822 | |
public void visitSynchronized(JCSynchronized tree) { |
1823 | 0 | chk.checkRefType(tree.pos(), attribExpr(tree.lock, env)); |
1824 | 0 | attribStat(tree.body, env); |
1825 | 0 | result = null; |
1826 | 0 | } |
1827 | |
|
1828 | |
@Override |
1829 | |
public void visitTry(JCTry tree) { |
1830 | |
|
1831 | 24 | attribStat(tree.body, env.dup(tree, env.info.dup())); |
1832 | |
|
1833 | |
|
1834 | 59 | for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { |
1835 | 35 | JCCatch c = l.head; |
1836 | 35 | JavafxEnv<JavafxAttrContext> catchEnv = |
1837 | |
env.dup(c, env.info.dup(env.info.scope.dup())); |
1838 | 35 | memberEnter.memberEnter(c.param, env); |
1839 | 35 | if (c.param.type == null) |
1840 | 35 | c.param.sym.type = c.param.type = syms.throwableType; |
1841 | 35 | Type ctype = attribStat((JFXVar) c.param, catchEnv); |
1842 | 35 | if (c.param.type.tsym.kind == Kinds.VAR) { |
1843 | 0 | c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER); |
1844 | |
} |
1845 | |
|
1846 | |
|
1847 | |
|
1848 | |
|
1849 | 35 | attribStat(c.body, catchEnv); |
1850 | 35 | catchEnv.info.scope.leave(); |
1851 | |
} |
1852 | |
|
1853 | |
|
1854 | 24 | if (tree.finalizer != null) attribStat(tree.finalizer, env); |
1855 | 24 | result = null; |
1856 | 24 | } |
1857 | |
|
1858 | |
@Override |
1859 | |
public void visitConditional(JCConditional tree) { |
1860 | 466 | attribExpr(tree.cond, env, syms.booleanType); |
1861 | 466 | attribTree(tree.truepart, env, VAL, pt, pSequenceness); |
1862 | |
Type falsepartType; |
1863 | 466 | if (tree.falsepart == null) { |
1864 | 164 | falsepartType = syms.voidType; |
1865 | |
} else { |
1866 | 302 | falsepartType = attribTree(tree.falsepart, env, VAL, pt, pSequenceness); |
1867 | |
{ |
1868 | |
|
1869 | |
|
1870 | |
|
1871 | |
|
1872 | 302 | if (tree.truepart instanceof JFXSequenceEmpty |
1873 | |
|| tree.truepart.type.tag == BOT) |
1874 | 3 | tree.truepart.type = falsepartType; |
1875 | 299 | else if (tree.falsepart instanceof JFXSequenceEmpty |
1876 | |
|| falsepartType.tag == BOT) |
1877 | 7 | falsepartType = tree.falsepart.type = tree.truepart.type; |
1878 | |
} |
1879 | |
} |
1880 | 466 | result = check(tree, |
1881 | |
capture(condType(tree.pos(), tree.cond.type, |
1882 | |
tree.truepart.type, falsepartType)), |
1883 | |
VAL, pkind, pt, pSequenceness); |
1884 | 466 | } |
1885 | |
|
1886 | |
|
1887 | |
|
1888 | |
|
1889 | |
|
1890 | |
|
1891 | |
|
1892 | |
|
1893 | |
|
1894 | |
|
1895 | |
private Type condType(DiagnosticPosition pos, |
1896 | |
Type condtype, |
1897 | |
Type thentype, |
1898 | |
Type elsetype) { |
1899 | 466 | Type ctype = unionType(pos, thentype, elsetype); |
1900 | |
|
1901 | |
|
1902 | |
|
1903 | 466 | return ((condtype.constValue() != null) && |
1904 | |
(thentype.constValue() != null) && |
1905 | |
(elsetype.constValue() != null)) |
1906 | |
? cfolder.coerce(condtype.isTrue()?thentype:elsetype, ctype) |
1907 | |
: ctype; |
1908 | |
} |
1909 | |
|
1910 | |
|
1911 | |
|
1912 | |
|
1913 | |
|
1914 | |
|
1915 | |
|
1916 | |
|
1917 | |
|
1918 | |
|
1919 | |
|
1920 | |
private Type unionType(DiagnosticPosition pos, |
1921 | |
Type type1, Type type2) { |
1922 | 1582 | if (type1 == syms.unreachableType) |
1923 | 28 | return type2; |
1924 | 1554 | if (type2 == syms.unreachableType) |
1925 | 3 | return type1; |
1926 | 1551 | if (type1 == type2) |
1927 | 1256 | return type1; |
1928 | 295 | if (type1.tag == VOID || type2.tag == VOID) |
1929 | 233 | return syms.voidType; |
1930 | |
|
1931 | 62 | boolean isSequence1 = types.isSequence(type1); |
1932 | 62 | boolean isSequence2 = types.isSequence(type2); |
1933 | 62 | if (isSequence1 || isSequence2) { |
1934 | 19 | if (isSequence1) |
1935 | 16 | type1 = types.elementType(type1); |
1936 | 19 | if (isSequence2) |
1937 | 19 | type2 = types.elementType(type2); |
1938 | 19 | Type union = unionType(pos, type1, type2); |
1939 | 19 | return union.tag == ERROR ? union : types.sequenceType(union); |
1940 | |
} |
1941 | |
|
1942 | 43 | if (types.isSameType(type1, type2)) |
1943 | 5 | return type1.baseType(); |
1944 | |
|
1945 | 38 | Type thenUnboxed = (!allowBoxing || type1.isPrimitive()) |
1946 | |
? type1 : types.unboxedType(type1); |
1947 | 38 | Type elseUnboxed = (!allowBoxing || type2.isPrimitive()) |
1948 | |
? type2 : types.unboxedType(type2); |
1949 | |
|
1950 | |
|
1951 | |
|
1952 | |
|
1953 | |
|
1954 | 38 | if (thenUnboxed.isPrimitive() && elseUnboxed.isPrimitive()) { |
1955 | |
|
1956 | |
|
1957 | |
|
1958 | 4 | if (thenUnboxed.tag < INT && elseUnboxed.tag == INT && |
1959 | |
types.isAssignable(elseUnboxed, thenUnboxed)) |
1960 | 0 | return thenUnboxed.baseType(); |
1961 | 4 | if (elseUnboxed.tag < INT && thenUnboxed.tag == INT && |
1962 | |
types.isAssignable(thenUnboxed, elseUnboxed)) |
1963 | 0 | return elseUnboxed.baseType(); |
1964 | |
|
1965 | 28 | for (int i = BYTE; i < VOID; i++) { |
1966 | 28 | Type candidate = syms.typeOfTag[i]; |
1967 | 28 | if (types.isSubtype(thenUnboxed, candidate) && |
1968 | |
types.isSubtype(elseUnboxed, candidate)) |
1969 | 4 | return candidate; |
1970 | |
} |
1971 | |
} |
1972 | |
|
1973 | |
|
1974 | 34 | if (allowBoxing) { |
1975 | 34 | type1 = syms.boxIfNeeded(type1); |
1976 | 34 | type2 = syms.boxIfNeeded(type2); |
1977 | |
} |
1978 | |
|
1979 | 34 | if (types.isSubtype(type1, type2)) |
1980 | 9 | return type2.baseType(); |
1981 | 25 | if (types.isSubtype(type2, type1)) |
1982 | 2 | return type1.baseType(); |
1983 | |
|
1984 | 23 | if (!allowBoxing) { |
1985 | 0 | log.error(pos, MsgSym.MESSAGE_NEITHER_CONDITIONAL_SUBTYPE, |
1986 | |
type1, type2); |
1987 | 0 | return type1.baseType(); |
1988 | |
} |
1989 | |
|
1990 | |
|
1991 | |
|
1992 | |
|
1993 | 23 | return types.lub(type1.baseType(), type2.baseType()); |
1994 | |
} |
1995 | |
|
1996 | |
@Override |
1997 | |
public void visitIf(JCIf tree) { |
1998 | 0 | attribExpr(tree.cond, env, syms.booleanType); |
1999 | 0 | attribStat(tree.thenpart, env); |
2000 | 0 | if (tree.elsepart != null) |
2001 | 0 | attribStat(tree.elsepart, env); |
2002 | 0 | chk.checkEmptyIf(tree); |
2003 | 0 | result = null; |
2004 | 0 | } |
2005 | |
|
2006 | |
@Override |
2007 | |
public void visitExec(JCExpressionStatement tree) { |
2008 | 3041 | Type type = attribExpr(tree.expr, env); |
2009 | 3041 | result = type == syms.unreachableType ? type : null; |
2010 | 3041 | } |
2011 | |
|
2012 | |
@Override |
2013 | |
public void visitBreak(JCBreak tree) { |
2014 | 5 | tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env); |
2015 | 5 | result = null; |
2016 | 5 | } |
2017 | |
|
2018 | |
@Override |
2019 | |
public void visitContinue(JCContinue tree) { |
2020 | 3 | tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env); |
2021 | 3 | result = null; |
2022 | 3 | } |
2023 | |
|
2024 | |
|
2025 | |
|
2026 | |
|
2027 | |
|
2028 | |
|
2029 | |
|
2030 | |
|
2031 | |
|
2032 | |
|
2033 | |
|
2034 | |
|
2035 | |
|
2036 | |
|
2037 | |
private JCTree findJumpTarget(DiagnosticPosition pos, |
2038 | |
int tag, |
2039 | |
Name label, |
2040 | |
JavafxEnv<JavafxAttrContext> env) { |
2041 | |
|
2042 | 8 | JavafxEnv<JavafxAttrContext> env1 = env; |
2043 | |
LOOP: |
2044 | 23 | while (env1 != null) { |
2045 | 23 | switch (env1.tree.getTag()) { |
2046 | |
case JCTree.LABELLED: |
2047 | 0 | JCLabeledStatement labelled = (JCLabeledStatement)env1.tree; |
2048 | 0 | if (label == labelled.label) { |
2049 | |
|
2050 | 0 | if (tag == JCTree.CONTINUE) { |
2051 | 0 | if (labelled.body.getTag() != JCTree.DOLOOP && |
2052 | |
labelled.body.getTag() != JCTree.WHILELOOP) |
2053 | 0 | log.error(pos, MsgSym.MESSAGE_NOT_LOOP_LABEL, label); |
2054 | |
|
2055 | |
|
2056 | 0 | return TreeInfo.referencedStatement(labelled); |
2057 | |
} else { |
2058 | 0 | return labelled; |
2059 | |
} |
2060 | |
} |
2061 | |
break; |
2062 | |
case JCTree.WHILELOOP: |
2063 | |
case JavafxTag.FOR_EXPRESSION: |
2064 | 8 | if (label == null) return env1.tree; |
2065 | |
break; |
2066 | |
case JCTree.SWITCH: |
2067 | 0 | if (label == null && tag == JCTree.BREAK) return env1.tree; |
2068 | |
break; |
2069 | |
case JCTree.METHODDEF: |
2070 | |
case JCTree.CLASSDEF: |
2071 | 0 | break LOOP; |
2072 | |
default: |
2073 | |
} |
2074 | 15 | env1 = env1.next; |
2075 | |
} |
2076 | 0 | if (label != null) |
2077 | 0 | log.error(pos, MsgSym.MESSAGE_UNDEF_LABEL, label); |
2078 | 0 | else if (tag == JCTree.CONTINUE) |
2079 | 0 | log.error(pos, MsgSym.MESSAGE_CONT_OUTSIDE_LOOP); |
2080 | |
else |
2081 | 0 | log.error(pos, MsgSym.MESSAGE_BREAK_OUTSIDE_SWITCH_LOOP); |
2082 | 0 | return null; |
2083 | |
} |
2084 | |
|
2085 | |
@Override |
2086 | |
public void visitReturn(JCReturn tree) { |
2087 | 190 | if (env.enclMethod == null) { |
2088 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_RETURN_OUTSIDE_METH); |
2089 | |
|
2090 | |
} else { |
2091 | |
|
2092 | |
|
2093 | 190 | Symbol m = env.enclMethod.sym; |
2094 | 190 | Type rtype = m.type.getReturnType(); |
2095 | 190 | if (rtype == null) |
2096 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_JAVAFX_CANNOT_INFER_RETURN_TYPE); |
2097 | 190 | else if (rtype.tag == VOID) { |
2098 | 1 | if (tree.expr != null) |
2099 | 0 | log.error(tree.expr.pos(), |
2100 | |
MsgSym.MESSAGE_CANNOT_RET_VAL_FROM_METH_DECL_VOID); |
2101 | 189 | } else if (tree.expr == null) { |
2102 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_MISSING_RET_VAL); |
2103 | |
} else { |
2104 | 189 | attribExpr(tree.expr, env, m.type.getReturnType()); |
2105 | |
} |
2106 | |
} |
2107 | |
|
2108 | 190 | result = syms.unreachableType; |
2109 | 190 | } |
2110 | |
|
2111 | |
@Override |
2112 | |
public void visitThrow(JCThrow tree) { |
2113 | 24 | attribExpr(tree.expr, env, syms.throwableType); |
2114 | 24 | result = syms.unreachableType; |
2115 | 24 | } |
2116 | |
|
2117 | |
@Override |
2118 | |
public void visitAssert(JCAssert tree) { |
2119 | 0 | attribExpr(tree.cond, env, syms.booleanType); |
2120 | 0 | if (tree.detail != null) { |
2121 | 0 | chk.checkNonVoid(tree.detail.pos(), attribExpr(tree.detail, env)); |
2122 | |
} |
2123 | 0 | result = null; |
2124 | 0 | } |
2125 | |
|
2126 | |
void searchParameterTypes (JCExpression meth, Type[] paramTypes) { |
2127 | |
|
2128 | |
|
2129 | |
|
2130 | |
|
2131 | |
|
2132 | 3327 | } |
2133 | |
|
2134 | |
@Override |
2135 | |
public void visitApply(JCMethodInvocation tree) { |
2136 | |
|
2137 | |
|
2138 | 3327 | JavafxEnv<JavafxAttrContext> localEnv = env.dup(tree, env.info.dup()); |
2139 | |
|
2140 | |
|
2141 | |
List<Type> typeargtypes; |
2142 | |
|
2143 | 3327 | Name methName = JavafxTreeInfo.name(tree.meth); |
2144 | |
|
2145 | 3327 | int argcount = tree.args.size(); |
2146 | |
|
2147 | 3327 | Type[] paramTypes = new Type[argcount]; |
2148 | 3327 | searchParameterTypes(tree.meth, paramTypes); |
2149 | |
|
2150 | 3327 | ListBuffer<Type> argtypebuffer = new ListBuffer<Type>(); |
2151 | 3327 | int i = 0; |
2152 | 6950 | for (List<JCExpression> l = tree.args; l.nonEmpty(); l = l.tail, i++) { |
2153 | 3623 | Type argtype = paramTypes[i]; |
2154 | 3623 | if (argtype != null) |
2155 | 0 | attribExpr(l.head, env, argtype); |
2156 | |
else |
2157 | 3623 | argtype = chk.checkNonVoid(l.head.pos(), |
2158 | |
types.upperBound(attribTree(l.head, env, VAL, Infer.anyPoly))); |
2159 | 3623 | argtypebuffer.append(argtype); |
2160 | |
} |
2161 | 3327 | List<Type> argtypes = argtypebuffer.toList(); |
2162 | |
|
2163 | 3327 | typeargtypes = attribTypes(tree.typeargs, localEnv); |
2164 | |
|
2165 | |
|
2166 | |
|
2167 | |
|
2168 | 3327 | Type mpt = new MethodType(argtypes, pt, null, syms.methodClass); |
2169 | 3327 | if (typeargtypes.nonEmpty()) mpt = new ForAll(typeargtypes, mpt); |
2170 | 3327 | localEnv.info.varArgs = false; |
2171 | 3327 | Type mtype = attribExpr(tree.meth, localEnv, mpt); |
2172 | 3327 | if (localEnv.info.varArgs) |
2173 | 4 | assert mtype.isErroneous() || tree.varargsElement != null; |
2174 | |
|
2175 | |
|
2176 | 3327 | Type restype = mtype.getReturnType(); |
2177 | 3327 | if (restype == syms.unknownType) { |
2178 | 0 | log.error(tree.meth.pos(), MsgSym.MESSAGE_JAVAFX_FUNC_TYPE_INFER_CYCLE, methName); |
2179 | 0 | restype = syms.objectType; |
2180 | |
} |
2181 | |
|
2182 | |
|
2183 | 3327 | if (tree.meth.getTag() == JCTree.SELECT && |
2184 | |
allowCovariantReturns && |
2185 | |
methName == names.clone && |
2186 | |
types.isArray(((JCFieldAccess) tree.meth).selected.type)) |
2187 | 0 | restype = ((JCFieldAccess) tree.meth).selected.type; |
2188 | |
|
2189 | |
|
2190 | 3327 | if (allowGenerics && |
2191 | |
methName == names.getClass && tree.args.isEmpty()) { |
2192 | 7 | Type qualifier = (tree.meth.getTag() == JCTree.SELECT) |
2193 | |
? ((JCFieldAccess) tree.meth).selected.type |
2194 | |
: env.enclClass.sym.type; |
2195 | 7 | qualifier = syms.boxIfNeeded(qualifier); |
2196 | 7 | restype = new |
2197 | |
ClassType(restype.getEnclosingType(), |
2198 | |
List.<Type>of(new WildcardType(types.erasure(qualifier), |
2199 | |
BoundKind.EXTENDS, |
2200 | |
syms.boundClass)), |
2201 | |
restype.tsym); |
2202 | |
} |
2203 | |
|
2204 | 3327 | if (restype == null) { |
2205 | 0 | log.error(tree, |
2206 | |
MsgSym.MESSAGE_JAVAFX_NOT_A_FUNC, |
2207 | |
mtype, |
2208 | |
typeargtypes, |
2209 | |
Type.toString(argtypes)); |
2210 | 0 | tree.type = pt; |
2211 | 0 | result = pt; |
2212 | |
} |
2213 | |
else { |
2214 | |
|
2215 | |
|
2216 | 3327 | result = check(tree, capture(restype), VAL, pkind, pt, pSequenceness); |
2217 | |
} |
2218 | |
|
2219 | 3327 | chk.validate(tree.typeargs); |
2220 | 3327 | } |
2221 | |
|
2222 | |
@Override |
2223 | |
public void visitAssignop(JCAssignOp tree) { |
2224 | |
|
2225 | 38 | Type owntype = attribTree(tree.lhs, env, VAR, Type.noType); |
2226 | 38 | Type operand = attribExpr(tree.rhs, env); |
2227 | |
|
2228 | |
|
2229 | 38 | Symbol lhsSym = TreeInfo.symbol(tree.lhs); |
2230 | 38 | if (lhsSym != null && tree.lhs instanceof JCExpression && |
2231 | |
(lhsSym.type == null || lhsSym.type == Type.noType || lhsSym.type == syms.javafx_AnyType)) { |
2232 | 1 | JFXVar lhsVarTree = varSymToTree.get(lhsSym); |
2233 | 1 | owntype = setBinaryTypes(tree.getTag(), (JCExpression)tree.lhs, lhsVarTree, lhsSym.type, lhsSym); |
2234 | |
} |
2235 | |
|
2236 | 38 | Symbol rhsSym = TreeInfo.symbol(tree.rhs); |
2237 | 38 | if (rhsSym != null && tree.rhs instanceof JCExpression && |
2238 | |
(rhsSym.type == null || rhsSym.type == Type.noType || rhsSym.type == syms.javafx_AnyType)) { |
2239 | 0 | JFXVar rhsVarTree = varSymToTree.get(rhsSym); |
2240 | 0 | operand = setBinaryTypes(tree.getTag(), (JCExpression)tree.rhs, rhsVarTree, rhsSym.type, rhsSym); |
2241 | |
} |
2242 | |
|
2243 | |
|
2244 | 38 | Symbol operator = tree.operator = rs.resolveBinaryOperator( |
2245 | |
tree.pos(), tree.getTag() - JCTree.ASGOffset, env, |
2246 | |
owntype, operand); |
2247 | |
|
2248 | 38 | if (operator.kind == MTH) { |
2249 | 38 | chk.checkOperator(tree.pos(), |
2250 | |
(OperatorSymbol)operator, |
2251 | |
tree.getTag() - JCTree.ASGOffset, |
2252 | |
owntype, |
2253 | |
operand); |
2254 | 38 | if (types.isSameType(operator.type.getReturnType(), syms.stringType)) { |
2255 | |
|
2256 | 0 | chk.checkType(tree.lhs.pos(), |
2257 | |
owntype, |
2258 | |
syms.stringType, Sequenceness.DISALLOWED); |
2259 | |
} else { |
2260 | 38 | chk.checkDivZero(tree.rhs.pos(), operator, operand); |
2261 | 38 | chk.checkCastable(tree.rhs.pos(), |
2262 | |
operator.type.getReturnType(), |
2263 | |
owntype); |
2264 | |
} |
2265 | |
} |
2266 | 38 | if (tree.lhs instanceof JCIdent) |
2267 | 34 | ((JCIdent) (tree.lhs)).sym.flags_field |= JavafxFlags.ASSIGNED_TO; |
2268 | 38 | result = check(tree, owntype, VAL, pkind, pt, pSequenceness); |
2269 | |
|
2270 | 38 | if (lhsSym != null && tree.rhs != null) { |
2271 | 34 | JFXVar lhsVar = varSymToTree.get(lhsSym); |
2272 | 34 | if (lhsVar != null && (lhsVar.getJFXType() instanceof JFXTypeUnknown)) { |
2273 | 24 | if ((lhsVar.type == null || lhsVar.type == syms.javafx_AnyType)) { |
2274 | 0 | if (tree.rhs.type != null && lhsVar.type != tree.rhs.type) { |
2275 | 0 | lhsVar.type = lhsSym.type = tree.rhs.type; |
2276 | 0 | JCExpression jcExpr = make.at(tree.pos()).Ident(lhsSym); |
2277 | 0 | lhsVar.setJFXType(make.at(tree.pos()).TypeClass(jcExpr, lhsVar.getJFXType().getCardinality())); |
2278 | |
} |
2279 | |
} |
2280 | |
} |
2281 | |
} |
2282 | 38 | } |
2283 | |
|
2284 | |
@Override |
2285 | |
public void visitUnary(JCUnary tree) { |
2286 | 700 | switch (tree.getTag()) { |
2287 | |
case JavafxTag.SIZEOF: { |
2288 | 201 | attribExpr(tree.arg, env); |
2289 | 201 | result = check(tree, syms.javafx_IntegerType, VAL, pkind, pt, pSequenceness); |
2290 | 201 | return; |
2291 | |
} |
2292 | |
case JavafxTag.REVERSE: { |
2293 | 67 | Type argtype = chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env)); |
2294 | 67 | result = check(tree, argtype, VAL, pkind, pt, pSequenceness); |
2295 | 67 | return; |
2296 | |
} |
2297 | |
} |
2298 | |
|
2299 | 432 | Type argtype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC) |
2300 | |
? attribTree(tree.arg, env, VAR, Type.noType) |
2301 | |
: chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env)); |
2302 | 432 | Symbol sym = rs.resolveUnaryOperator(tree.pos(), tree.getTag(), env, argtype); |
2303 | 432 | Type owntype = syms.errType; |
2304 | 432 | if (sym instanceof OperatorSymbol) { |
2305 | |
|
2306 | 432 | Symbol operator = tree.operator = sym; |
2307 | 432 | if (operator.kind == MTH) { |
2308 | 432 | owntype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC) |
2309 | |
? tree.arg.type |
2310 | |
: operator.type.getReturnType(); |
2311 | |
|
2312 | |
|
2313 | |
|
2314 | |
|
2315 | |
|
2316 | |
|
2317 | |
|
2318 | |
|
2319 | |
|
2320 | |
|
2321 | |
|
2322 | |
|
2323 | |
|
2324 | |
|
2325 | |
|
2326 | |
|
2327 | |
|
2328 | |
|
2329 | |
|
2330 | |
|
2331 | |
|
2332 | |
} |
2333 | 432 | } else { |
2334 | 0 | owntype = sym.type.getReturnType(); |
2335 | |
} |
2336 | 432 | result = check(tree, owntype, VAL, pkind, pt, pSequenceness); |
2337 | 432 | } |
2338 | |
|
2339 | |
private Type setBinaryTypes(int opcode, JCExpression tree, JFXVar var, Type type, Symbol treeSym) { |
2340 | 20 | Type newType = type; |
2341 | 20 | JCExpression jcExpression = null; |
2342 | |
|
2343 | 20 | if (opcode == JCTree.OR || |
2344 | |
opcode == JCTree.AND) { |
2345 | 0 | newType = syms.javafx_BooleanType; |
2346 | 0 | jcExpression = make.at(tree.pos()).Ident(syms.javafx_BooleanType.tsym); |
2347 | |
} |
2348 | |
|
2349 | 20 | else if (opcode == JCTree.BITOR || |
2350 | |
opcode == JCTree.BITXOR || |
2351 | |
opcode == JCTree.BITAND || |
2352 | |
opcode == JCTree.SL || |
2353 | |
opcode == JCTree.SR || |
2354 | |
opcode == JCTree.USR || |
2355 | |
opcode == JCTree.MOD || |
2356 | |
opcode == JCTree.BITOR_ASG || |
2357 | |
opcode == JCTree.BITXOR_ASG || |
2358 | |
opcode == JCTree.BITAND_ASG || |
2359 | |
opcode == JCTree.SL_ASG || |
2360 | |
opcode == JCTree.SR_ASG || |
2361 | |
opcode == JCTree.USR_ASG || |
2362 | |
opcode == JCTree.MOD_ASG) { |
2363 | 0 | newType = syms.javafx_IntegerType; |
2364 | 0 | jcExpression = make.at(tree.pos()).Ident(syms.javafx_IntegerType.tsym); |
2365 | |
} |
2366 | |
|
2367 | 20 | else if (opcode == JCTree.LT || |
2368 | |
opcode == JCTree.GT || |
2369 | |
opcode == JCTree.LE || |
2370 | |
opcode == JCTree.GE || |
2371 | |
opcode == JCTree.PLUS || |
2372 | |
opcode == JCTree.MINUS || |
2373 | |
opcode == JCTree.MUL || |
2374 | |
opcode == JCTree.DIV || |
2375 | |
opcode == JCTree.PLUS_ASG || |
2376 | |
opcode == JCTree.MINUS_ASG || |
2377 | |
opcode == JCTree.MUL_ASG || |
2378 | |
opcode == JCTree.DIV_ASG) { |
2379 | 12 | newType = syms.javafx_NumberType; |
2380 | 12 | jcExpression = make.at(tree.pos()).Ident(syms.javafx_NumberType.tsym); |
2381 | |
} |
2382 | |
|
2383 | 20 | if (tree != null) { |
2384 | 20 | tree.setType(newType); |
2385 | 20 | treeSym.type = newType; |
2386 | |
} |
2387 | |
|
2388 | 20 | if (var != null) { |
2389 | 20 | var.setType(newType); |
2390 | 20 | JFXType jfxType = make.at(tree.pos()).TypeClass(jcExpression, Cardinality.SINGLETON); |
2391 | 20 | jfxType.type = newType; |
2392 | 20 | var.setJFXType(jfxType); |
2393 | 20 | var.vartype = jfxType; |
2394 | 20 | var.sym.type = newType; |
2395 | |
} |
2396 | |
|
2397 | 20 | return newType; |
2398 | |
} |
2399 | |
|
2400 | |
@Override |
2401 | |
public void visitBinary(JCBinary tree) { |
2402 | |
|
2403 | 1100 | Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env)); |
2404 | 1100 | Type right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, env)); |
2405 | |
|
2406 | 1100 | if (left == syms.javafx_UnspecifiedType) { |
2407 | 0 | left = setEffectiveExpressionType(tree.lhs, newTypeFromType(getEffectiveExpressionType(right))); |
2408 | |
} |
2409 | 1100 | else if (right == syms.javafx_UnspecifiedType) { |
2410 | 0 | right = setEffectiveExpressionType(tree.rhs, newTypeFromType(getEffectiveExpressionType(left))); |
2411 | |
} |
2412 | |
|
2413 | |
|
2414 | 1100 | boolean lhsSet = false; |
2415 | |
|
2416 | 1100 | Symbol lhsSym = TreeInfo.symbol(tree.lhs); |
2417 | 1100 | if (lhsSym != null && tree.lhs instanceof JCExpression && |
2418 | |
(lhsSym.type == null || lhsSym.type == Type.noType || lhsSym.type == syms.javafx_AnyType)) { |
2419 | 9 | JFXVar lhsVarTree = varSymToTree.get(lhsSym); |
2420 | 9 | left = setBinaryTypes(tree.getTag(), (JCExpression)tree.lhs, lhsVarTree, lhsSym.type, lhsSym); |
2421 | 9 | lhsSet = true; |
2422 | |
} |
2423 | |
|
2424 | 1100 | Symbol rhsSym = TreeInfo.symbol(tree.rhs); |
2425 | 1100 | if (rhsSym != null && ((tree.rhs instanceof JCExpression && |
2426 | |
(rhsSym.type == null || rhsSym.type == Type.noType || rhsSym.type == syms.javafx_AnyType))) || (lhsSet && lhsSym == rhsSym)) { |
2427 | 10 | JFXVar rhsVarTree = varSymToTree.get(rhsSym); |
2428 | 10 | right = setBinaryTypes(tree.getTag(), (JCExpression)tree.rhs, rhsVarTree, rhsSym.type, rhsSym); |
2429 | |
} |
2430 | |
|
2431 | 1100 | Symbol sym = |
2432 | |
rs.resolveBinaryOperator(tree.pos(), tree.getTag(), env, left, right); |
2433 | 1100 | Type owntype = syms.errType; |
2434 | 1100 | if (sym instanceof OperatorSymbol) { |
2435 | |
|
2436 | 1093 | Symbol operator = tree.operator = sym; |
2437 | |
|
2438 | 1093 | if (operator.kind == MTH) { |
2439 | 1093 | owntype = operator.type.getReturnType(); |
2440 | 1093 | int opc = chk.checkOperator(tree.lhs.pos(), |
2441 | |
(OperatorSymbol)operator, |
2442 | |
tree.getTag(), |
2443 | |
left, |
2444 | |
right); |
2445 | |
|
2446 | |
|
2447 | 1093 | if (left.constValue() != null && right.constValue() != null) { |
2448 | 0 | Type ctype = cfolder.fold2(opc, left, right); |
2449 | 0 | if (ctype != null) { |
2450 | 0 | owntype = cfolder.coerce(ctype, owntype); |
2451 | |
|
2452 | |
|
2453 | |
|
2454 | |
|
2455 | |
|
2456 | |
|
2457 | 0 | if (tree.lhs.type.tsym == syms.stringType.tsym) { |
2458 | 0 | tree.lhs.type = syms.stringType; |
2459 | |
} |
2460 | 0 | if (tree.rhs.type.tsym == syms.stringType.tsym) { |
2461 | 0 | tree.rhs.type = syms.stringType; |
2462 | |
} |
2463 | |
} |
2464 | |
} |
2465 | |
|
2466 | |
|
2467 | |
|
2468 | 1093 | if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) { |
2469 | 241 | if (!types.isCastable(left, right, new Warner(tree.pos()))) { |
2470 | 0 | boolean isError = true; |
2471 | 0 | if (right.tsym != null && right.tsym instanceof JavafxClassSymbol) { |
2472 | 0 | ListBuffer<Type> supertypes = ListBuffer.<Type>lb(); |
2473 | 0 | Set superSet = new HashSet<Type>(); |
2474 | 0 | supertypes.append(right); |
2475 | 0 | superSet.add(right); |
2476 | |
|
2477 | 0 | types.getSupertypes(right.tsym, supertypes, superSet); |
2478 | 0 | for (Type baseType : supertypes) { |
2479 | 0 | if (types.isCastable(left, baseType, new Warner(tree.pos()))){ |
2480 | 0 | isError = false; |
2481 | 0 | break; |
2482 | |
} |
2483 | |
} |
2484 | |
} |
2485 | |
|
2486 | 0 | if (isError) { |
2487 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_INCOMPARABLE_TYPES, left, right); |
2488 | |
} |
2489 | |
} |
2490 | |
} |
2491 | 1093 | chk.checkDivZero(tree.rhs.pos(), operator, right); |
2492 | |
} |
2493 | 1093 | } else { |
2494 | 7 | owntype = sym.type.getReturnType(); |
2495 | |
} |
2496 | 1100 | result = check(tree, owntype, VAL, pkind, pt, pSequenceness); |
2497 | 1100 | } |
2498 | |
|
2499 | |
@Override |
2500 | |
public void visitLiteral(JCLiteral tree) { |
2501 | 8196 | if (tree.typetag == TypeTags.BOT && types.isSequence(pt)) |
2502 | 3 | result = tree.type = pt; |
2503 | |
else |
2504 | 8193 | result = check( |
2505 | |
tree, litType(tree.typetag, pt), VAL, pkind, pt, pSequenceness); |
2506 | 8196 | } |
2507 | |
|
2508 | |
|
2509 | |
|
2510 | |
Type litType(int tag, Type pt) { |
2511 | 8193 | return (tag == TypeTags.CLASS) ? syms.stringType : |
2512 | |
(tag == TypeTags.BOT && pt.tag == TypeTags.CLASS) ? pt : |
2513 | |
syms.typeOfTag[tag]; |
2514 | |
} |
2515 | |
|
2516 | |
@Override |
2517 | |
public void visitTypeIdent(JCPrimitiveTypeTree tree) { |
2518 | 0 | result = check(tree, syms.typeOfTag[tree.typetag], TYP, pkind, pt, pSequenceness); |
2519 | 0 | } |
2520 | |
|
2521 | |
@Override |
2522 | |
public void visitTypeArray(JCArrayTypeTree tree) { |
2523 | 0 | assert false : "This tree should not exist"; |
2524 | 0 | } |
2525 | |
|
2526 | |
|
2527 | |
|
2528 | |
|
2529 | |
|
2530 | |
@Override |
2531 | |
public void visitTypeApply(JCTypeApply tree) { |
2532 | 0 | Type owntype = syms.errType; |
2533 | |
|
2534 | |
|
2535 | 0 | Type clazztype = chk.checkClassType(tree.clazz.pos(), attribType(tree.clazz, env)); |
2536 | |
|
2537 | |
|
2538 | 0 | List<Type> actuals = attribTypes(tree.arguments, env); |
2539 | |
|
2540 | 0 | if (clazztype.tag == CLASS) { |
2541 | 0 | List<Type> formals = clazztype.tsym.type.getTypeArguments(); |
2542 | |
|
2543 | 0 | if (actuals.length() == formals.length()) { |
2544 | 0 | List<Type> a = actuals; |
2545 | 0 | List<Type> f = formals; |
2546 | 0 | while (a.nonEmpty()) { |
2547 | 0 | a.head = a.head.withTypeVar(f.head); |
2548 | 0 | a = a.tail; |
2549 | 0 | f = f.tail; |
2550 | |
} |
2551 | |
|
2552 | 0 | Type clazzOuter = clazztype.getEnclosingType(); |
2553 | 0 | if (clazzOuter.tag == CLASS) { |
2554 | |
Type site; |
2555 | 0 | if (tree.clazz.getTag() == JCTree.IDENT) { |
2556 | 0 | site = env.enclClass.sym.type; |
2557 | 0 | } else if (tree.clazz.getTag() == JCTree.SELECT) { |
2558 | 0 | site = ((JCFieldAccess) tree.clazz).selected.type; |
2559 | 0 | } else throw new AssertionError(""+tree); |
2560 | 0 | if (clazzOuter.tag == CLASS && site != clazzOuter) { |
2561 | 0 | if (site.tag == CLASS) |
2562 | 0 | site = types.asOuterSuper(site, clazzOuter.tsym); |
2563 | 0 | if (site == null) |
2564 | 0 | site = types.erasure(clazzOuter); |
2565 | 0 | clazzOuter = site; |
2566 | |
} |
2567 | |
} |
2568 | 0 | owntype = new ClassType(clazzOuter, actuals, clazztype.tsym); |
2569 | 0 | } else { |
2570 | 0 | if (formals.length() != 0) { |
2571 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_WRONG_NUMBER_TYPE_ARGS, |
2572 | |
Integer.toString(formals.length())); |
2573 | |
} else { |
2574 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_TYPE_DOES_NOT_TAKE_PARAMS, clazztype.tsym); |
2575 | |
} |
2576 | 0 | owntype = syms.errType; |
2577 | |
} |
2578 | |
} |
2579 | 0 | result = check(tree, owntype, TYP, pkind, pt, pSequenceness); |
2580 | 0 | } |
2581 | |
|
2582 | |
@Override |
2583 | |
public void visitTypeParameter(JCTypeParameter tree) { |
2584 | 0 | assert false; |
2585 | 0 | } |
2586 | |
|
2587 | |
@Override |
2588 | |
public void visitWildcard(JCWildcard tree) { |
2589 | 0 | assert false; |
2590 | 0 | } |
2591 | |
|
2592 | |
@Override |
2593 | |
public void visitAnnotation(JCAnnotation tree) { |
2594 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_ANNOTATION_NOT_VALID_FOR_TYPE, pt); |
2595 | 0 | result = tree.type = syms.errType; |
2596 | 0 | } |
2597 | |
|
2598 | |
@Override |
2599 | |
public void visitErroneous(JCErroneous tree) { |
2600 | 0 | if (tree.errs != null) |
2601 | 0 | for (JCTree err : tree.errs) |
2602 | 0 | attribTree(err, env, ERR, pt); |
2603 | 0 | result = tree.type = syms.errType; |
2604 | 0 | } |
2605 | |
|
2606 | |
@Override |
2607 | |
public void visitTree(JCTree tree) { |
2608 | 0 | if (tree instanceof JFXBlockExpression) |
2609 | 0 | visitBlockExpression((JFXBlockExpression) tree); |
2610 | |
else |
2611 | 0 | super.visitTree(tree); |
2612 | 0 | } |
2613 | |
|
2614 | |
|
2615 | |
|
2616 | |
|
2617 | |
|
2618 | |
|
2619 | |
|
2620 | |
public void attribClass(DiagnosticPosition pos, JFXClassDeclaration tree, ClassSymbol c) { |
2621 | |
try { |
2622 | 702 | annotate.flush(); |
2623 | 702 | attribClass(tree, c); |
2624 | 0 | } catch (CompletionFailure ex) { |
2625 | 0 | chk.completionError(pos, ex); |
2626 | 699 | } |
2627 | 699 | } |
2628 | |
|
2629 | |
|
2630 | |
|
2631 | |
|
2632 | |
void attribClass(JFXClassDeclaration tree, ClassSymbol c) throws CompletionFailure { |
2633 | 1979 | if (c.type.tag == ERROR) return; |
2634 | |
|
2635 | |
|
2636 | |
|
2637 | 1973 | chk.checkNonCyclic(null, c.type); |
2638 | |
|
2639 | 1973 | Type st = types.supertype(c.type); |
2640 | 1973 | if ((c.flags_field & Flags.COMPOUND) == 0) { |
2641 | |
|
2642 | 1973 | if (st.tag == CLASS) |
2643 | 1017 | attribClass(null, (ClassSymbol)st.tsym); |
2644 | |
|
2645 | |
|
2646 | 1973 | if (c.owner.kind == TYP && c.owner.type.tag == CLASS) |
2647 | 260 | attribClass(null, (ClassSymbol)c.owner); |
2648 | |
} |
2649 | |
|
2650 | 1973 | if (tree != null) { |
2651 | 670 | attribSupertypes(tree, c); |
2652 | |
} |
2653 | |
|
2654 | |
|
2655 | |
|
2656 | |
|
2657 | 1973 | if ((c.flags_field & UNATTRIBUTED) != 0) { |
2658 | 670 | c.flags_field &= ~UNATTRIBUTED; |
2659 | |
|
2660 | |
|
2661 | 670 | JavafxEnv<JavafxAttrContext> localEnv = enter.typeEnvs.get(c); |
2662 | |
|
2663 | |
|
2664 | |
|
2665 | |
|
2666 | |
|
2667 | |
|
2668 | 670 | JavafxEnv<JavafxAttrContext> lintEnv = localEnv; |
2669 | 1340 | while (lintEnv.info.lint == null) |
2670 | 670 | lintEnv = lintEnv.next; |
2671 | |
|
2672 | |
|
2673 | 670 | localEnv.info.lint = lintEnv.info.lint.augment(c.attributes_field, c.flags()); |
2674 | |
|
2675 | 670 | Lint prevLint = chk.setLint(localEnv.info.lint); |
2676 | 670 | JavaFileObject prev = log.useSource(c.sourcefile); |
2677 | |
|
2678 | |
try { |
2679 | |
|
2680 | 670 | if (st.tsym == syms.enumSym && |
2681 | |
((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0)) |
2682 | 0 | log.error(localEnv.tree.pos(), MsgSym.MESSAGE_ENUM_NO_SUBCLASSING); |
2683 | |
|
2684 | |
|
2685 | 670 | if (st.tsym != null && |
2686 | |
((st.tsym.flags_field & Flags.ENUM) != 0) && |
2687 | |
((c.flags_field & Flags.ENUM) == 0) && |
2688 | |
!target.compilerBootstrap(c)) { |
2689 | 0 | log.error(localEnv.tree.pos(), MsgSym.MESSAGE_ENUM_TYPES_NOT_EXTENSIBLE); |
2690 | |
} |
2691 | 670 | attribClassBody(localEnv, c); |
2692 | |
|
2693 | 667 | chk.checkDeprecatedAnnotation(localEnv.tree.pos(), c); |
2694 | |
} finally { |
2695 | 670 | log.useSource(prev); |
2696 | 670 | chk.setLint(prevLint); |
2697 | 667 | } |
2698 | |
|
2699 | |
} |
2700 | 1970 | } |
2701 | |
|
2702 | |
|
2703 | |
|
2704 | |
|
2705 | |
|
2706 | |
public Type newTypeFromType(Type t) { |
2707 | 0 | if (t == null) return null; |
2708 | 0 | switch (t.tag) { |
2709 | |
case BYTE: |
2710 | 0 | return syms.byteType; |
2711 | |
case CHAR: |
2712 | 0 | return syms.charType; |
2713 | |
case SHORT: |
2714 | 0 | return syms.shortType; |
2715 | |
case INT: |
2716 | 0 | return syms.intType; |
2717 | |
case LONG: |
2718 | 0 | return syms.longType; |
2719 | |
case FLOAT: |
2720 | 0 | return syms.floatType; |
2721 | |
case DOUBLE: |
2722 | 0 | return syms.doubleType; |
2723 | |
case BOOLEAN: |
2724 | 0 | return syms.booleanType; |
2725 | |
case VOID: |
2726 | 0 | return syms.voidType; |
2727 | |
default: |
2728 | 0 | return t; |
2729 | |
} |
2730 | |
} |
2731 | |
|
2732 | |
|
2733 | |
|
2734 | |
|
2735 | |
|
2736 | |
private Type getEffectiveExpressionType(Type type) { |
2737 | 0 | if (type.tag == TypeTags.METHOD) { |
2738 | 0 | return type.getReturnType(); |
2739 | |
} |
2740 | |
|
2741 | 0 | return type; |
2742 | |
} |
2743 | |
|
2744 | |
|
2745 | |
|
2746 | |
|
2747 | |
|
2748 | |
private Type setEffectiveExpressionType(JCExpression expression, Type type) { |
2749 | 0 | if (expression.type.tag == TypeTags.METHOD) { |
2750 | 0 | ((MethodType)expression.type).restype = type; |
2751 | |
} |
2752 | |
else { |
2753 | 0 | expression.type = type; |
2754 | |
} |
2755 | |
|
2756 | 0 | return expression.type; |
2757 | |
} |
2758 | |
|
2759 | |
|
2760 | |
@Override |
2761 | |
public void visitClassDeclaration(JFXClassDeclaration tree) { |
2762 | |
|
2763 | 291 | if ((env.info.scope.owner.kind & (VAR | MTH)) != 0) |
2764 | 26 | enter.classEnter(tree, env); |
2765 | |
|
2766 | 291 | ClassSymbol c = tree.sym; |
2767 | 291 | if (c == null) { |
2768 | |
|
2769 | 0 | result = null; |
2770 | |
} else { |
2771 | |
|
2772 | 291 | c.complete(); |
2773 | |
|
2774 | |
|
2775 | |
|
2776 | |
|
2777 | |
|
2778 | |
|
2779 | 291 | if (env.info.isSelfCall && |
2780 | |
env.tree.getTag() == JCTree.NEWCLASS && |
2781 | |
((JCNewClass) env.tree).encl == null) |
2782 | |
{ |
2783 | 0 | c.flags_field |= NOOUTERTHIS; |
2784 | |
} |
2785 | |
|
2786 | 291 | attribSupertypes(tree, c); |
2787 | |
|
2788 | 291 | attribClass(tree.pos(), tree, c); |
2789 | |
|
2790 | 291 | result = tree.type = c.type; |
2791 | |
} |
2792 | |
|
2793 | 291 | types.addFxClass(c, tree); |
2794 | 291 | } |
2795 | |
|
2796 | |
private void attribSupertypes(JFXClassDeclaration tree, ClassSymbol c) { |
2797 | 961 | JavafxClassSymbol javafxClassSymbol = null; |
2798 | 961 | if (c instanceof JavafxClassSymbol) { |
2799 | 961 | javafxClassSymbol = (JavafxClassSymbol)c; |
2800 | |
} |
2801 | |
|
2802 | 961 | Symbol javaSupertypeSymbol = null; |
2803 | 961 | boolean addToSuperTypes = true; |
2804 | |
|
2805 | 961 | for (JCExpression superClass : tree.getSupertypes()) { |
2806 | 233 | Type supType = null; |
2807 | 233 | Symbol supSym = TreeInfo.symbol(superClass); |
2808 | 233 | if (supSym == null) { |
2809 | 0 | supType = attribType(superClass, env); |
2810 | |
} |
2811 | |
else { |
2812 | 233 | supType = supSym.type; |
2813 | |
} |
2814 | 233 | if (supType != null && !supType.isInterface() && |
2815 | |
!types.isJFXClass(supType.tsym) && |
2816 | |
!supType.isPrimitive() && |
2817 | |
javafxClassSymbol.type instanceof ClassType) { |
2818 | 25 | if (javaSupertypeSymbol == null) { |
2819 | 25 | javaSupertypeSymbol = supType.tsym; |
2820 | |
|
2821 | 25 | boolean hasNonParamCtor = true; |
2822 | 25 | for (Scope.Entry e1 = javaSupertypeSymbol.members().elems; |
2823 | 493 | e1 != null; |
2824 | 468 | e1 = e1.sibling) { |
2825 | 493 | Symbol s1 = e1.sym; |
2826 | 493 | if (s1 != null && |
2827 | |
s1.name == names.init && |
2828 | |
s1.kind == Kinds.MTH) { |
2829 | 56 | MethodType mtype = ((MethodSymbol)s1).type.asMethodType(); |
2830 | 56 | if (mtype != null && mtype.getParameterTypes().isEmpty()) { |
2831 | 25 | hasNonParamCtor = true; |
2832 | 25 | break; |
2833 | |
} |
2834 | |
else { |
2835 | 31 | hasNonParamCtor = false; |
2836 | |
} |
2837 | |
} |
2838 | |
} |
2839 | |
|
2840 | 25 | if (hasNonParamCtor) { |
2841 | 25 | ((ClassType)javafxClassSymbol.type).supertype_field = javaSupertypeSymbol.type; |
2842 | 25 | addToSuperTypes = false; |
2843 | |
} |
2844 | |
else { |
2845 | 0 | log.error(superClass.pos(), MsgSym.MESSAGE_JAVAFX_BASE_JAVA_CLASS_NON_PAPAR_CTOR, supType.tsym.name); |
2846 | |
|
2847 | |
} |
2848 | 25 | } |
2849 | |
else { |
2850 | |
|
2851 | 0 | log.error(superClass.pos(), MsgSym.MESSAGE_JAVAFX_ONLY_ONE_BASE_JAVA_CLASS_ALLOWED, supType.tsym.name); |
2852 | |
} |
2853 | |
} |
2854 | |
|
2855 | 233 | if (addToSuperTypes && |
2856 | |
supType != null && |
2857 | |
javafxClassSymbol != null) { |
2858 | 208 | javafxClassSymbol.addSuperType(supType); |
2859 | |
} |
2860 | 233 | addToSuperTypes = true; |
2861 | 233 | } |
2862 | |
|
2863 | 961 | } |
2864 | |
|
2865 | |
@Override |
2866 | |
public void visitInitDefinition(JFXInitDefinition that) { |
2867 | 30 | Symbol symOwner = env.info.scope.owner; |
2868 | |
try { |
2869 | 30 | MethodType mt = new MethodType(List.<Type>nil(), syms.voidType, List.<Type>nil(), (TypeSymbol)symOwner); |
2870 | 30 | that.sym = new MethodSymbol(0L, defs.initDefName, mt, symOwner); |
2871 | 30 | env.info.scope.owner = that.sym; |
2872 | 30 | ((JCBlock)that.getBody()).accept(this); |
2873 | |
} |
2874 | |
finally { |
2875 | 30 | env.info.scope.owner = symOwner; |
2876 | 30 | } |
2877 | 30 | } |
2878 | |
|
2879 | |
public void visitPostInitDefinition(JFXPostInitDefinition that) { |
2880 | 10 | Symbol symOwner = env.info.scope.owner; |
2881 | |
try { |
2882 | 10 | MethodType mt = new MethodType(List.<Type>nil(), syms.voidType, List.<Type>nil(), (TypeSymbol)symOwner); |
2883 | 10 | that.sym = new MethodSymbol(0L, defs.postInitDefName, mt, symOwner); |
2884 | 10 | env.info.scope.owner = that.sym; |
2885 | 10 | ((JCBlock)that.getBody()).accept(this); |
2886 | |
} |
2887 | |
finally { |
2888 | 10 | env.info.scope.owner = symOwner; |
2889 | 10 | } |
2890 | 10 | } |
2891 | |
|
2892 | |
@Override |
2893 | |
public void visitSequenceEmpty(JFXSequenceEmpty tree) { |
2894 | 54 | boolean isSeq = false; |
2895 | 54 | if (pt.tag != NONE && pt != syms.javafx_UnspecifiedType && !(isSeq = types.isSequence(pt)) && pSequenceness == Sequenceness.DISALLOWED) { |
2896 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_ARRAY_REQ_BUT_FOUND, pt); |
2897 | 0 | result = syms.errType; |
2898 | |
} else { |
2899 | 54 | Type owntype = pt.tag == NONE || pt.tag == UNKNOWN ? syms.botType : |
2900 | |
isSeq ? pt : types.sequenceType(pt); |
2901 | 54 | result = check(tree, owntype, VAL, pkind, Type.noType, pSequenceness); |
2902 | |
} |
2903 | 54 | } |
2904 | |
|
2905 | |
@Override |
2906 | |
public void visitSequenceRange(JFXSequenceRange tree) { |
2907 | 212 | Type lowerType = attribExpr(tree.getLower(), env); |
2908 | 212 | Type upperType = attribExpr(tree.getUpper(), env); |
2909 | 212 | Type stepType = tree.getStepOrNull() == null? syms.javafx_IntegerType : attribExpr(tree.getStepOrNull(), env); |
2910 | 212 | boolean allInt = true; |
2911 | 212 | if (lowerType != syms.javafx_IntegerType) { |
2912 | 6 | allInt = false; |
2913 | 6 | if (lowerType != syms.javafx_NumberType) { |
2914 | 1 | log.error(tree.getLower().pos(), MsgSym.MESSAGE_JAVAFX_RANGE_START_INT_OR_NUMBER); |
2915 | |
} |
2916 | |
} |
2917 | 212 | if (upperType != syms.javafx_IntegerType) { |
2918 | 11 | allInt = false; |
2919 | 11 | if (upperType != syms.javafx_NumberType) { |
2920 | 1 | log.error(tree.getLower().pos(), MsgSym.MESSAGE_JAVAFX_RANGE_END_INT_OR_NUMBER); |
2921 | |
} |
2922 | |
} |
2923 | 212 | if (stepType != syms.javafx_IntegerType) { |
2924 | 7 | allInt = false; |
2925 | 7 | if (stepType != syms.javafx_NumberType) { |
2926 | 1 | log.error(tree.getStepOrNull().pos(), MsgSym.MESSAGE_JAVAFX_RANGE_STEP_INT_OR_NUMBER); |
2927 | |
} |
2928 | |
} |
2929 | 212 | if (tree.getLower().getTag() == JCTree.LITERAL && tree.getUpper().getTag() == JCTree.LITERAL |
2930 | |
&& (tree.getStepOrNull() == null || tree.getStepOrNull().getTag() == JCTree.LITERAL)) { |
2931 | 133 | chk.warnEmptyRangeLiteral(tree.pos(), (JCLiteral)tree.getLower(), (JCLiteral)tree.getUpper(), (JCLiteral)tree.getStepOrNull(), tree.isExclusive()); |
2932 | |
} |
2933 | 209 | Type owntype = types.sequenceType(allInt? syms.javafx_IntegerType : syms.javafx_NumberType); |
2934 | 209 | result = check(tree, owntype, VAL, pkind, pt, pSequenceness); |
2935 | 209 | } |
2936 | |
|
2937 | |
@Override |
2938 | |
public void visitSequenceExplicit(JFXSequenceExplicit tree) { |
2939 | 398 | Type elemType = null; |
2940 | 398 | Type expected = pt; |
2941 | 398 | if (types.isSequence(expected)) |
2942 | 152 | expected = types.elementType(expected); |
2943 | 398 | for (JCExpression expr : tree.getItems()) { |
2944 | 1495 | Type itemType = attribTree(expr, env, VAL, |
2945 | |
expected, Sequenceness.PERMITTED); |
2946 | 1495 | if (itemType.tag == NONE || itemType.tag == ERROR) { |
2947 | 0 | continue; |
2948 | |
} |
2949 | 1495 | if (types.isSequence(itemType)) { |
2950 | 83 | itemType = types.elementType(itemType); |
2951 | |
} |
2952 | 1495 | if (elemType == null) |
2953 | 398 | elemType = itemType; |
2954 | |
else |
2955 | 1097 | elemType = unionType(tree, itemType, elemType); |
2956 | 1495 | } |
2957 | 398 | Type owntype = types.sequenceType(elemType); |
2958 | 398 | result = check(tree, owntype, VAL, pkind, pt, pSequenceness); |
2959 | 398 | if (owntype == result && pt.tag != NONE && pt != syms.javafx_UnspecifiedType) { |
2960 | 153 | expected = types.sequenceType(expected); |
2961 | 153 | result = tree.type = expected; |
2962 | |
} |
2963 | 398 | } |
2964 | |
|
2965 | |
@Override |
2966 | |
public void visitSequenceSlice(JFXSequenceSlice tree) { |
2967 | 31 | JCExpression seq = tree.getSequence(); |
2968 | 31 | Type seqType = attribExpr(seq, env); |
2969 | |
|
2970 | 31 | attribExpr(tree.getFirstIndex(), env, syms.javafx_IntegerType); |
2971 | 31 | if (tree.getLastIndex() != null) { |
2972 | 19 | attribExpr(tree.getLastIndex(), env, syms.javafx_IntegerType); |
2973 | |
} |
2974 | 31 | result = check(tree, seqType, VAR, pkind, pt, pSequenceness); |
2975 | 31 | } |
2976 | |
|
2977 | |
@Override |
2978 | |
public void visitSequenceIndexed(JFXSequenceIndexed tree) { |
2979 | 454 | JCExpression seq = tree.getSequence(); |
2980 | 454 | Type seqType = attribExpr(seq, env); |
2981 | |
|
2982 | 454 | attribExpr(tree.getIndex(), env, syms.javafx_IntegerType); |
2983 | |
Type owntype; |
2984 | 454 | if (seqType.tag == TypeTags.ARRAY) { |
2985 | 0 | owntype = ((ArrayType)seqType).elemtype; |
2986 | |
} |
2987 | |
else { |
2988 | 454 | owntype = chk.checkSequenceElementType(seq, seqType); |
2989 | |
} |
2990 | 454 | result = check(tree, owntype, VAR, pkind, pt, pSequenceness); |
2991 | 454 | } |
2992 | |
|
2993 | |
@Override |
2994 | |
public void visitSequenceInsert(JFXSequenceInsert tree) { |
2995 | 186 | JCExpression seq = tree.getSequence(); |
2996 | 186 | Type seqType = attribTree(seq, env, VAR, Type.noType, Sequenceness.REQUIRED); |
2997 | 186 | attribExpr(tree.getElement(), env, seqType); |
2998 | 186 | if (tree.getPosition() != null) { |
2999 | 87 | attribExpr(tree.getPosition(), env, syms.javafx_IntegerType); |
3000 | |
} |
3001 | 186 | result = null; |
3002 | 186 | } |
3003 | |
|
3004 | |
@Override |
3005 | |
public void visitSequenceDelete(JFXSequenceDelete tree) { |
3006 | 123 | JCExpression seq = tree.getSequence(); |
3007 | 123 | if (tree.getElement() == null) { |
3008 | 98 | if (seq instanceof JFXSequenceIndexed) { |
3009 | |
|
3010 | 38 | JFXSequenceIndexed si = (JFXSequenceIndexed)seq; |
3011 | 38 | JCExpression seqseq = si.getSequence(); |
3012 | 38 | JCExpression index = si.getIndex(); |
3013 | 38 | attribTree(seqseq, env, VAR, Type.noType, Sequenceness.REQUIRED); |
3014 | 38 | attribExpr(index, env, syms.javafx_IntegerType); |
3015 | 38 | } else if (seq instanceof JFXSequenceSlice) { |
3016 | |
|
3017 | 35 | JFXSequenceSlice slice = (JFXSequenceSlice)seq; |
3018 | 35 | JCExpression seqseq = slice.getSequence(); |
3019 | 35 | JCExpression first = slice.getFirstIndex(); |
3020 | 35 | JCExpression last = slice.getLastIndex(); |
3021 | 35 | attribTree(seqseq, env, VAR, Type.noType, Sequenceness.REQUIRED); |
3022 | 35 | attribExpr(first, env, syms.javafx_IntegerType); |
3023 | 35 | if (last != null) { |
3024 | 25 | attribExpr(last, env, syms.javafx_IntegerType); |
3025 | |
} |
3026 | 35 | } else { |
3027 | |
|
3028 | 25 | attribTree(seq, env, VAR, Type.noType, Sequenceness.REQUIRED); |
3029 | |
} |
3030 | |
} else { |
3031 | 25 | Type seqType = attribTree(seq, env, VAR, Type.noType, Sequenceness.REQUIRED); |
3032 | 25 | attribExpr(tree.getElement(), env, |
3033 | |
chk.checkSequenceElementType(seq.pos(), seqType)); |
3034 | |
} |
3035 | 123 | result = null; |
3036 | 123 | } |
3037 | |
|
3038 | |
@Override |
3039 | |
public void visitStringExpression(JFXStringExpression tree) { |
3040 | 741 | List<JCExpression> parts = tree.getParts(); |
3041 | 741 | attribExpr(parts.head, env, syms.javafx_StringType); |
3042 | 741 | parts = parts.tail; |
3043 | 1909 | while (parts.nonEmpty()) { |
3044 | |
|
3045 | 1168 | attribExpr(parts.head, env, syms.javafx_StringType); |
3046 | 1168 | parts = parts.tail; |
3047 | |
|
3048 | 1168 | chk.checkNonVoid(parts.head.pos(), attribExpr(parts.head, env, Type.noType)); |
3049 | 1168 | parts = parts.tail; |
3050 | |
|
3051 | 1168 | attribExpr(parts.head, env, syms.javafx_StringType); |
3052 | 1168 | parts = parts.tail; |
3053 | |
} |
3054 | 741 | result = check(tree, syms.javafx_StringType, VAL, pkind, pt, pSequenceness); |
3055 | 741 | } |
3056 | |
|
3057 | |
@Override |
3058 | |
public void visitSetAttributeToObjectBeingInitialized(JFXSetAttributeToObjectBeingInitialized that) { |
3059 | 0 | } |
3060 | |
|
3061 | |
@Override |
3062 | |
public void visitObjectLiteralPart(JFXObjectLiteralPart that) { |
3063 | 0 | assert false : "should not reach here"; |
3064 | 0 | result = syms.errType; |
3065 | 0 | } |
3066 | |
|
3067 | |
@Override |
3068 | |
public void visitTypeAny(JFXTypeAny tree) { |
3069 | 0 | assert false : "MUST IMPLEMENT"; |
3070 | 0 | } |
3071 | |
|
3072 | |
@Override |
3073 | |
public void visitTypeClass(JFXTypeClass tree) { |
3074 | 2795 | Type type = null; |
3075 | 2795 | JCExpression classNameExpr = ((JFXTypeClass) tree).getClassName(); |
3076 | 2795 | if (classNameExpr instanceof JCIdent) { |
3077 | 2321 | Name className = ((JCIdent) classNameExpr).getName(); |
3078 | 2321 | if (className == numberTypeName) { |
3079 | 149 | type = syms.javafx_NumberType; |
3080 | 2172 | } else if (className == integerTypeName) { |
3081 | 752 | type = syms.javafx_IntegerType; |
3082 | 1420 | } else if (className == booleanTypeName) { |
3083 | 201 | type = syms.javafx_BooleanType; |
3084 | 1219 | } else if (className == voidTypeName) { |
3085 | 84 | type = syms.javafx_VoidType; |
3086 | 1135 | } else if (className == stringTypeName) { |
3087 | 804 | type = syms.javafx_StringType; |
3088 | |
} |
3089 | |
} |
3090 | 2795 | if (type == null) { |
3091 | 805 | type = attribType(classNameExpr, env); |
3092 | |
} |
3093 | 2795 | type = sequenceType(type, tree.getCardinality()); |
3094 | 2795 | tree.type = type; |
3095 | 2795 | result = type; |
3096 | 2795 | } |
3097 | |
|
3098 | |
@Override |
3099 | |
public void visitTypeFunctional(JFXTypeFunctional tree) { |
3100 | 33 | Type restype = attribType(tree.restype, env); |
3101 | 33 | if (restype == syms.unknownType) |
3102 | 3 | restype = syms.voidType; |
3103 | 33 | Type rtype = restype == syms.voidType ? syms.javafx_java_lang_VoidType |
3104 | |
: new WildcardType(syms.boxIfNeeded(restype), BoundKind.EXTENDS, syms.boundClass); |
3105 | 33 | ListBuffer<Type> typarams = new ListBuffer<Type>(); |
3106 | 33 | ListBuffer<Type> argtypes = new ListBuffer<Type>(); |
3107 | 33 | typarams.append(rtype); |
3108 | 33 | int nargs = 0; |
3109 | 33 | for (JFXType param : (List<JFXType>)tree.params) { |
3110 | 28 | Type argtype = attribType(param, env); |
3111 | 28 | argtypes.append(argtype); |
3112 | 28 | Type ptype = syms.boxIfNeeded(argtype); |
3113 | 28 | ptype = new WildcardType(ptype, BoundKind.SUPER, syms.boundClass); |
3114 | 28 | typarams.append(ptype); |
3115 | 28 | nargs++; |
3116 | 28 | } |
3117 | 33 | MethodType mtype = new MethodType(argtypes.toList(), restype, null, syms.methodClass); |
3118 | 33 | FunctionType ftype = syms.makeFunctionType(typarams.toList(), mtype); |
3119 | 33 | Type type = sequenceType(ftype, tree.getCardinality()); |
3120 | 33 | tree.type = type; |
3121 | 33 | result = type; |
3122 | 33 | } |
3123 | |
|
3124 | |
@Override |
3125 | |
public void visitTypeUnknown(JFXTypeUnknown tree) { |
3126 | 1406 | result = tree.type = syms.javafx_UnspecifiedType; |
3127 | 1406 | } |
3128 | |
|
3129 | |
Type sequenceType(Type elemType, Cardinality cardinality) { |
3130 | 2828 | return cardinality == cardinality.ANY |
3131 | |
? types.sequenceType(elemType) |
3132 | |
: elemType; |
3133 | |
} |
3134 | |
|
3135 | |
|
3136 | |
|
3137 | |
|
3138 | |
|
3139 | |
|
3140 | |
|
3141 | |
|
3142 | |
|
3143 | |
|
3144 | |
|
3145 | |
|
3146 | |
|
3147 | |
|
3148 | |
|
3149 | |
|
3150 | |
|
3151 | |
|
3152 | |
|
3153 | |
|
3154 | |
|
3155 | |
|
3156 | |
|
3157 | |
|
3158 | |
|
3159 | |
Type checkId(JCTree tree, |
3160 | |
Type site, |
3161 | |
Symbol sym, |
3162 | |
JavafxEnv<JavafxAttrContext> env, |
3163 | |
int pkind, |
3164 | |
Type pt, |
3165 | |
Sequenceness pSequenceness, |
3166 | |
boolean useVarargs) { |
3167 | 20814 | if (pt.isErroneous()) return syms.errType; |
3168 | |
Type owntype; |
3169 | 20813 | switch (sym.kind) { |
3170 | |
case TYP: |
3171 | |
|
3172 | |
|
3173 | 4353 | owntype = sym.type; |
3174 | 4353 | if (owntype.tag == CLASS) { |
3175 | 4353 | Type ownOuter = owntype.getEnclosingType(); |
3176 | |
|
3177 | |
|
3178 | |
|
3179 | |
|
3180 | 4353 | if (owntype.tsym.type.getTypeArguments().nonEmpty()) { |
3181 | 41 | owntype = types.erasure(owntype); |
3182 | |
} |
3183 | |
|
3184 | |
|
3185 | |
|
3186 | |
|
3187 | |
|
3188 | |
|
3189 | |
|
3190 | |
|
3191 | |
|
3192 | |
|
3193 | |
|
3194 | 4312 | else if (ownOuter.tag == CLASS && site != ownOuter) { |
3195 | 0 | Type normOuter = site; |
3196 | 0 | if (normOuter.tag == CLASS) |
3197 | 0 | normOuter = types.asEnclosingSuper(site, ownOuter.tsym); |
3198 | 0 | if (normOuter == null) |
3199 | 0 | normOuter = types.erasure(ownOuter); |
3200 | 0 | if (normOuter != ownOuter) |
3201 | 0 | owntype = new ClassType( |
3202 | |
normOuter, List.<Type>nil(), owntype.tsym); |
3203 | |
} |
3204 | 4353 | } |
3205 | |
break; |
3206 | |
case VAR: |
3207 | 9265 | VarSymbol v = (VarSymbol)sym; |
3208 | |
|
3209 | |
|
3210 | |
|
3211 | 9265 | if (allowGenerics && |
3212 | |
pkind == VAR && |
3213 | |
v.owner.kind == TYP && |
3214 | |
(v.flags() & STATIC) == 0 && |
3215 | |
(site.tag == CLASS || site.tag == TYPEVAR)) { |
3216 | 484 | Type s = types.asOuterSuper(site, v.owner); |
3217 | 484 | if (s != null && |
3218 | |
s.isRaw() && |
3219 | |
!types.isSameType(v.type, v.erasure(types))) { |
3220 | 0 | chk.warnUnchecked(tree.pos(), |
3221 | |
MsgSym.MESSAGE_UNCHECKED_ASSIGN_TO_VAR, |
3222 | |
v, s); |
3223 | |
} |
3224 | |
} |
3225 | |
|
3226 | |
|
3227 | 9265 | owntype = (sym.owner.kind == TYP && |
3228 | |
sym.name != names._this && sym.name != names._super) |
3229 | |
? types.memberType(site, sym) |
3230 | |
: sym.type; |
3231 | |
|
3232 | 9265 | if (env.info.tvars.nonEmpty()) { |
3233 | 0 | Type owntype1 = new ForAll(env.info.tvars, owntype); |
3234 | 0 | for (List<Type> l = env.info.tvars; l.nonEmpty(); l = l.tail) |
3235 | 0 | if (!owntype.contains(l.head)) { |
3236 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_UNDETERMINDED_TYPE, owntype1); |
3237 | 0 | owntype1 = syms.errType; |
3238 | |
} |
3239 | 0 | owntype = owntype1; |
3240 | |
} |
3241 | |
|
3242 | |
|
3243 | |
|
3244 | |
|
3245 | |
|
3246 | |
|
3247 | 9265 | if (pkind == VAL) { |
3248 | 5212 | owntype = capture(owntype); |
3249 | |
} |
3250 | |
break; |
3251 | |
case MTH: { |
3252 | 3288 | owntype = sym.type; |
3253 | |
|
3254 | |
|
3255 | |
|
3256 | 3288 | if (pt instanceof MethodType || pt instanceof ForAll) { |
3257 | 3279 | JCMethodInvocation app = (JCMethodInvocation)env.tree; |
3258 | 3279 | owntype = checkMethod(site, sym, env, app.args, |
3259 | |
pt.getParameterTypes(), pt.getTypeArguments(), |
3260 | |
env.info.varArgs); |
3261 | 3279 | } |
3262 | |
break; |
3263 | |
} |
3264 | |
case PCK: case ERR: |
3265 | 3907 | owntype = sym.type; |
3266 | 3907 | break; |
3267 | |
default: |
3268 | 0 | throw new AssertionError("unexpected kind: " + sym.kind + |
3269 | |
" in tree " + tree); |
3270 | |
} |
3271 | |
|
3272 | |
|
3273 | |
|
3274 | |
|
3275 | 20813 | if (sym.name != names.init && |
3276 | |
(sym.flags() & DEPRECATED) != 0 && |
3277 | |
(env.info.scope.owner.flags() & DEPRECATED) == 0 && |
3278 | |
sym.outermostClass() != env.info.scope.owner.outermostClass()) |
3279 | 0 | chk.warnDeprecated(tree.pos(), sym); |
3280 | |
|
3281 | 20813 | if ((sym.flags() & PROPRIETARY) != 0) |
3282 | 0 | log.strictWarning(tree.pos(), MsgSym.MESSAGE_SUN_PROPRIETARY, sym); |
3283 | |
|
3284 | |
|
3285 | |
|
3286 | 20813 | return check(tree, owntype, sym.kind, pkind, pt, pSequenceness); |
3287 | |
} |
3288 | |
|
3289 | |
|
3290 | |
|
3291 | |
|
3292 | |
|
3293 | |
|
3294 | |
|
3295 | |
|
3296 | |
private void checkInit(JCTree tree, |
3297 | |
JavafxEnv<JavafxAttrContext> env, |
3298 | |
VarSymbol v, |
3299 | |
boolean onlyWarning) { |
3300 | |
|
3301 | |
|
3302 | |
|
3303 | |
|
3304 | |
|
3305 | |
|
3306 | |
|
3307 | |
|
3308 | |
|
3309 | |
|
3310 | |
|
3311 | 9265 | if (v.pos > tree.pos && |
3312 | |
v.owner.kind == TYP && |
3313 | |
canOwnInitializer(env.info.scope.owner) && |
3314 | |
v.owner == env.info.scope.owner.enclClass() && |
3315 | |
((v.flags() & STATIC) != 0) == JavafxResolve.isStatic(env) && |
3316 | |
(env.tree.getTag() != JCTree.ASSIGN || |
3317 | |
TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) { |
3318 | |
|
3319 | |
|
3320 | |
|
3321 | |
|
3322 | |
|
3323 | |
|
3324 | |
|
3325 | |
|
3326 | |
|
3327 | |
} |
3328 | |
|
3329 | 9265 | v.getConstValue(); |
3330 | |
|
3331 | 9265 | checkEnumInitializer(tree, env, v); |
3332 | 9265 | } |
3333 | |
|
3334 | |
|
3335 | |
|
3336 | |
|
3337 | |
|
3338 | |
|
3339 | |
boolean isAssignableAsBlankFinal(VarSymbol v, JavafxEnv<JavafxAttrContext> env) { |
3340 | 0 | Symbol owner = env.info.scope.owner; |
3341 | |
|
3342 | |
|
3343 | 0 | return |
3344 | |
v.owner == owner |
3345 | |
|| |
3346 | |
((owner.name == names.init || |
3347 | |
owner.kind == VAR || |
3348 | |
(owner.flags() & BLOCK) != 0) |
3349 | |
&& |
3350 | |
v.owner == owner.owner |
3351 | |
&& |
3352 | |
((v.flags() & STATIC) != 0) == JavafxResolve.isStatic(env)); |
3353 | |
} |
3354 | |
|
3355 | |
|
3356 | |
|
3357 | |
|
3358 | |
|
3359 | |
|
3360 | |
|
3361 | |
|
3362 | |
void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, JavafxEnv<JavafxAttrContext> env) { |
3363 | |
|
3364 | 1429 | if ((v.flags() & FINAL) != 0 && !types.isJFXClass(v.owner) && |
3365 | |
((v.flags() & HASINIT) != 0 |
3366 | |
|| |
3367 | |
!((base == null || |
3368 | |
(base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) && |
3369 | |
isAssignableAsBlankFinal(v, env)))) { |
3370 | 0 | log.error(pos, MsgSym.MESSAGE_CANNOT_ASSIGN_VAL_TO_FINAL_VAR, v); |
3371 | |
} |
3372 | 1429 | } |
3373 | |
|
3374 | |
|
3375 | |
|
3376 | |
|
3377 | |
|
3378 | |
|
3379 | |
|
3380 | |
|
3381 | |
|
3382 | |
|
3383 | |
|
3384 | |
private void checkEnumInitializer(JCTree tree, JavafxEnv<JavafxAttrContext> env, VarSymbol v) { |
3385 | |
|
3386 | |
|
3387 | |
|
3388 | |
|
3389 | |
|
3390 | |
|
3391 | |
|
3392 | |
|
3393 | |
|
3394 | |
|
3395 | |
|
3396 | 9265 | if (isNonStaticEnumField(v)) { |
3397 | 0 | ClassSymbol enclClass = env.info.scope.owner.enclClass(); |
3398 | |
|
3399 | 0 | if (enclClass == null || enclClass.owner == null) |
3400 | 0 | return; |
3401 | |
|
3402 | |
|
3403 | |
|
3404 | |
|
3405 | 0 | if (v.owner != enclClass && !types.isSubtype(enclClass.type, v.owner.type)) |
3406 | 0 | return; |
3407 | |
|
3408 | |
|
3409 | |
|
3410 | 0 | if (!JavafxResolve.isInitializer(env)) |
3411 | 0 | return; |
3412 | |
|
3413 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_ILLEGAL_ENUM_STATIC_REF); |
3414 | |
} |
3415 | 9265 | } |
3416 | |
|
3417 | |
private boolean isNonStaticEnumField(VarSymbol v) { |
3418 | 9265 | return Flags.isEnum(v.owner) && Flags.isStatic(v) && !Flags.isConstant(v); |
3419 | |
} |
3420 | |
|
3421 | |
|
3422 | |
|
3423 | |
|
3424 | |
|
3425 | |
|
3426 | |
private boolean canOwnInitializer(Symbol sym) { |
3427 | 1271 | return |
3428 | |
(sym.kind & (VAR | TYP)) != 0 || |
3429 | |
(sym.kind == MTH && (sym.flags() & BLOCK) != 0); |
3430 | |
} |
3431 | |
|
3432 | 399 | Warner noteWarner = new Warner(); |
3433 | |
|
3434 | |
|
3435 | |
|
3436 | |
|
3437 | |
public Type checkMethod(Type site, |
3438 | |
Symbol sym, |
3439 | |
JavafxEnv<JavafxAttrContext> env, |
3440 | |
final List<JCExpression> argtrees, |
3441 | |
List<Type> argtypes, |
3442 | |
List<Type> typeargtypes, |
3443 | |
boolean useVarargs) { |
3444 | |
|
3445 | |
|
3446 | 3279 | if (allowGenerics && |
3447 | |
(sym.flags() & STATIC) == 0 && |
3448 | |
(site.tag == CLASS || site.tag == TYPEVAR)) { |
3449 | 2469 | Type s = types.asOuterSuper(site, sym.owner); |
3450 | 2469 | if (s != null && s.isRaw() && |
3451 | |
!types.isSameTypes(sym.type.getParameterTypes(), |
3452 | |
sym.erasure(types).getParameterTypes())) { |
3453 | 8 | chk.warnUnchecked(env.tree.pos(), |
3454 | |
MsgSym.MESSAGE_UNCHECKED_CALL_MBR_OF_RAW_TYPE, |
3455 | |
sym, s); |
3456 | |
} |
3457 | |
} |
3458 | |
|
3459 | |
|
3460 | |
|
3461 | |
|
3462 | |
|
3463 | 3279 | noteWarner.warned = false; |
3464 | 3279 | Type owntype = rs.instantiate(env, |
3465 | |
site, |
3466 | |
sym, |
3467 | |
argtypes, |
3468 | |
typeargtypes, |
3469 | |
true, |
3470 | |
useVarargs, |
3471 | |
noteWarner); |
3472 | 3279 | boolean warned = noteWarner.warned; |
3473 | |
|
3474 | |
|
3475 | |
|
3476 | 3279 | if (owntype == null) { |
3477 | 0 | if (!pt.isErroneous()) |
3478 | 0 | log.error(env.tree.pos(), |
3479 | |
MsgSym.MESSAGE_INTERNAL_ERROR_CANNOT_INSTANTIATE, |
3480 | |
sym, site, |
3481 | |
Type.toString(pt.getParameterTypes())); |
3482 | 0 | owntype = syms.errType; |
3483 | |
} else { |
3484 | |
|
3485 | |
|
3486 | |
|
3487 | 3279 | List<Type> formals = owntype.getParameterTypes(); |
3488 | 3279 | Type last = useVarargs ? formals.last() : null; |
3489 | 3279 | if (sym.name==names.init && |
3490 | |
sym.owner == syms.enumSym) |
3491 | 0 | formals = formals.tail.tail; |
3492 | 3279 | List<JCExpression> args = argtrees; |
3493 | 6844 | while (formals.head != last) { |
3494 | 3565 | JCTree arg = args.head; |
3495 | 3565 | Warner warn = chk.convertWarner(arg.pos(), arg.type, formals.head); |
3496 | 3565 | assertConvertible(arg, arg.type, formals.head, warn); |
3497 | 3565 | warned |= warn.warned; |
3498 | 3565 | args = args.tail; |
3499 | 3565 | formals = formals.tail; |
3500 | 3565 | } |
3501 | 3279 | if (useVarargs) { |
3502 | 1 | Type varArg = types.elemtype(last); |
3503 | 5 | while (args.tail != null) { |
3504 | 4 | JCTree arg = args.head; |
3505 | 4 | Warner warn = chk.convertWarner(arg.pos(), arg.type, varArg); |
3506 | 4 | assertConvertible(arg, arg.type, varArg, warn); |
3507 | 4 | warned |= warn.warned; |
3508 | 4 | args = args.tail; |
3509 | 4 | } |
3510 | 1 | } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) { |
3511 | |
|
3512 | 0 | Type varParam = owntype.getParameterTypes().last(); |
3513 | 0 | Type lastArg = argtypes.last(); |
3514 | 0 | if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) && |
3515 | |
!types.isSameType(types.erasure(varParam), types.erasure(lastArg))) |
3516 | 0 | log.warning(argtrees.last().pos(), MsgSym.MESSAGE_INEXACT_NON_VARARGS_CALL, |
3517 | |
types.elemtype(varParam), |
3518 | |
varParam); |
3519 | |
} |
3520 | |
|
3521 | 3279 | if (warned && sym.type.tag == FORALL) { |
3522 | 0 | String typeargs = ""; |
3523 | 0 | if (typeargtypes != null && typeargtypes.nonEmpty()) { |
3524 | 0 | typeargs = "<" + Type.toString(typeargtypes) + ">"; |
3525 | |
} |
3526 | 0 | chk.warnUnchecked(env.tree.pos(), |
3527 | |
MsgSym.MESSAGE_UNCHECKED_METH_INVOCATION_APPLIED, |
3528 | |
sym, |
3529 | |
sym.location(), |
3530 | |
typeargs, |
3531 | |
Type.toString(argtypes)); |
3532 | 0 | owntype = new MethodType(owntype.getParameterTypes(), |
3533 | |
types.erasure(owntype.getReturnType()), |
3534 | |
owntype.getThrownTypes(), |
3535 | |
syms.methodClass); |
3536 | |
} |
3537 | 3279 | if (useVarargs) { |
3538 | 1 | JCTree tree = env.tree; |
3539 | 1 | Type argtype = owntype.getParameterTypes().last(); |
3540 | 1 | if (!types.isReifiable(argtype)) |
3541 | 0 | chk.warnUnchecked(env.tree.pos(), |
3542 | |
MsgSym.MESSAGE_UNCHECKED_GENERIC_ARRAY_CREATION, |
3543 | |
argtype); |
3544 | 1 | Type elemtype = types.elemtype(argtype); |
3545 | 1 | switch (tree.getTag()) { |
3546 | |
case JCTree.APPLY: |
3547 | 1 | ((JCMethodInvocation) tree).varargsElement = elemtype; |
3548 | 1 | break; |
3549 | |
case JCTree.NEWCLASS: |
3550 | 0 | ((JCNewClass) tree).varargsElement = elemtype; |
3551 | 0 | break; |
3552 | |
default: |
3553 | 0 | throw new AssertionError(""+tree); |
3554 | |
} |
3555 | |
} |
3556 | |
} |
3557 | 3279 | return owntype; |
3558 | |
} |
3559 | |
|
3560 | |
private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) { |
3561 | 3569 | if (types.isConvertible(actual, formal, warn)) |
3562 | 3569 | return; |
3563 | |
|
3564 | 0 | if (formal.isCompound() |
3565 | |
&& types.isSubtype(actual, types.supertype(formal)) |
3566 | |
&& types.isSubtypeUnchecked(actual, types.interfaces(formal), warn)) |
3567 | 0 | return; |
3568 | |
|
3569 | |
if (false) { |
3570 | |
|
3571 | |
chk.typeError(tree.pos(), JCDiagnostic.fragment(MsgSym.MESSAGE_INCOMPATIBLE_TYPES), actual, formal); |
3572 | |
throw new AssertionError("Tree: " + tree |
3573 | |
+ " actual:" + actual |
3574 | |
+ " formal: " + formal); |
3575 | |
} |
3576 | 0 | } |
3577 | |
|
3578 | |
@Override |
3579 | |
public void visitImport(JCImport tree) { |
3580 | |
|
3581 | 0 | } |
3582 | |
|
3583 | |
|
3584 | |
public void attribClassBody(JavafxEnv<JavafxAttrContext> env, ClassSymbol c) { |
3585 | 670 | JFXClassDeclaration tree = (JFXClassDeclaration)env.tree; |
3586 | 670 | assert c == tree.sym; |
3587 | |
|
3588 | |
|
3589 | 670 | chk.validateAnnotations(tree.mods.annotations, c); |
3590 | |
|
3591 | |
|
3592 | 670 | attribBounds(tree.getEmptyTypeParameters()); |
3593 | 670 | chk.validateTypeParams(tree.getEmptyTypeParameters()); |
3594 | 670 | chk.validate(tree.getSupertypes()); |
3595 | |
|
3596 | |
|
3597 | |
|
3598 | 670 | chk.checkClassBounds(tree.pos(), c.type); |
3599 | |
|
3600 | 670 | tree.type = c.type; |
3601 | |
|
3602 | 670 | boolean assertsEnabled = false; |
3603 | 670 | assert assertsEnabled = true; |
3604 | 670 | if (assertsEnabled) { |
3605 | 631 | for (List<JCTypeParameter> l = tree.getEmptyTypeParameters(); |
3606 | 631 | l.nonEmpty(); l = l.tail) |
3607 | 0 | assert env.info.scope.lookup(l.head.name).scope != null; |
3608 | |
} |
3609 | |
|
3610 | |
|
3611 | 670 | if (!c.type.allparams().isEmpty() && types.isSubtype(c.type, syms.throwableType)) |
3612 | 0 | log.error(tree.getExtending().head.pos(), MsgSym.MESSAGE_GENERIC_THROWABLE); |
3613 | |
|
3614 | 2580 | for (List<JCTree> l = tree.getMembers(); l.nonEmpty(); l = l.tail) { |
3615 | |
|
3616 | 1913 | attribStat(l.head, env); |
3617 | |
|
3618 | |
|
3619 | |
|
3620 | |
|
3621 | |
|
3622 | |
|
3623 | |
|
3624 | |
|
3625 | |
|
3626 | |
|
3627 | |
|
3628 | |
|
3629 | |
|
3630 | |
} |
3631 | |
|
3632 | |
|
3633 | |
|
3634 | 667 | if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) { |
3635 | 650 | if (!relax) |
3636 | 650 | chk.checkAllDefined(tree.pos(), c); |
3637 | |
} |
3638 | |
|
3639 | 667 | if ((c.flags() & ANNOTATION) != 0) { |
3640 | 0 | if (tree.getImplementing().nonEmpty()) |
3641 | 0 | log.error(tree.getImplementing().head.pos(), |
3642 | |
MsgSym.MESSAGE_CANNOT_EXTEND_INTERFACE_ANNOTATION); |
3643 | 0 | if (tree.getEmptyTypeParameters().nonEmpty()) |
3644 | 0 | log.error(tree.getEmptyTypeParameters().head.pos(), |
3645 | |
MsgSym.MESSAGE_INTF_ANNOTATION_CANNOT_HAVE_TYPE_PARAMS); |
3646 | |
} else { |
3647 | |
|
3648 | |
|
3649 | |
|
3650 | 667 | chk.checkCompatibleSupertypes(tree.pos(), c.type); |
3651 | |
} |
3652 | |
|
3653 | |
|
3654 | |
|
3655 | 667 | chk.checkImplementations(tree); |
3656 | |
|
3657 | 667 | Scope enclScope = JavafxEnter.enterScope(env); |
3658 | 2577 | for (List<JCTree> l = tree.getMembers(); l.nonEmpty(); l = l.tail) { |
3659 | 1910 | if (l.head instanceof JFXFunctionDefinition) |
3660 | 1063 | chk.checkUnique(l.head.pos(), ((JFXFunctionDefinition) l.head).sym, enclScope); |
3661 | |
} |
3662 | |
|
3663 | |
|
3664 | 667 | chk.checkCyclicConstructors(tree); |
3665 | |
|
3666 | |
|
3667 | 667 | chk.checkNonCyclicElements(tree); |
3668 | |
|
3669 | |
|
3670 | 667 | if (env.info.lint.isEnabled(Lint.LintCategory.SERIAL) && |
3671 | |
isSerializable(c) && |
3672 | |
(c.flags() & Flags.ENUM) == 0 && |
3673 | |
(c.flags() & ABSTRACT) == 0) { |
3674 | 0 | checkSerialVersionUID(tree, c); |
3675 | |
} |
3676 | 667 | } |
3677 | |
|
3678 | |
|
3679 | |
private boolean isSerializable(ClassSymbol c) { |
3680 | |
try { |
3681 | 0 | syms.serializableType.complete(); |
3682 | |
} |
3683 | 0 | catch (CompletionFailure e) { |
3684 | 0 | return false; |
3685 | 0 | } |
3686 | 0 | return types.isSubtype(c.type, syms.serializableType); |
3687 | |
} |
3688 | |
|
3689 | |
|
3690 | |
private void checkSerialVersionUID(JFXClassDeclaration tree, ClassSymbol c) { |
3691 | |
|
3692 | |
|
3693 | 0 | Scope.Entry e = c.members().lookup(names.serialVersionUID); |
3694 | 0 | while (e.scope != null && e.sym.kind != VAR) e = e.next(); |
3695 | 0 | if (e.scope == null) { |
3696 | 0 | log.warning(tree.pos(), MsgSym.MESSAGE_MISSING_SVUID, c); |
3697 | 0 | return; |
3698 | |
} |
3699 | |
|
3700 | |
|
3701 | 0 | VarSymbol svuid = (VarSymbol)e.sym; |
3702 | 0 | if ((svuid.flags() & (STATIC | FINAL)) != |
3703 | |
(STATIC | FINAL)) |
3704 | 0 | log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), MsgSym.MESSAGE_IMPROPER_SVUID, c); |
3705 | |
|
3706 | |
|
3707 | 0 | else if (svuid.type.tag != TypeTags.LONG) |
3708 | 0 | log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), MsgSym.MESSAGE_LONG_SVUID, c); |
3709 | |
|
3710 | |
|
3711 | 0 | else if (svuid.getConstValue() == null) |
3712 | 0 | log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), MsgSym.MESSAGE_CONSTANT_SVUID, c); |
3713 | 0 | } |
3714 | |
|
3715 | |
protected Type capture(Type type) { |
3716 | 14793 | Type ctype = types.capture(type); |
3717 | 14793 | if (type instanceof FunctionType) |
3718 | 70 | ctype = new FunctionType((FunctionType) type); |
3719 | 14793 | return ctype; |
3720 | |
} |
3721 | |
|
3722 | |
public void clearCaches() { |
3723 | 377 | varSymToTree = null; |
3724 | 377 | } |
3725 | |
|
3726 | |
void fixOverride(JFXFunctionDefinition tree, MethodSymbol m) { |
3727 | 1237 | ClassSymbol origin = (ClassSymbol)m.owner; |
3728 | 1237 | if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name)) |
3729 | 0 | if (m.overrides(syms.enumFinalFinalize, origin, types, false)) { |
3730 | 0 | log.error(tree.pos(), MsgSym.MESSAGE_ENUM_NO_FINALIZE); |
3731 | 0 | return; |
3732 | |
} |
3733 | |
|
3734 | 1237 | ListBuffer<Type> supertypes = ListBuffer.<Type>lb(); |
3735 | 1237 | Set superSet = new HashSet<Type>(); |
3736 | 1237 | types.getSupertypes(origin, supertypes, superSet); |
3737 | |
|
3738 | 1237 | for (Type t : supertypes) { |
3739 | 1673 | if (t.tag == CLASS) { |
3740 | 1673 | TypeSymbol c = t.tsym; |
3741 | 1673 | Scope.Entry e = c.members().lookup(m.name); |
3742 | 1678 | while (e.scope != null) { |
3743 | 126 | e.sym.complete(); |
3744 | 126 | if (m.overrides(e.sym, origin, types, false)) |
3745 | 121 | if (fixOverride(tree, m, (MethodSymbol)e.sym, origin)) |
3746 | 121 | break; |
3747 | 5 | e = e.next(); |
3748 | |
} |
3749 | 1673 | } |
3750 | |
} |
3751 | 1237 | } |
3752 | |
|
3753 | |
|
3754 | |
public |
3755 | |
|
3756 | |
boolean fixOverride(JFXFunctionDefinition tree, |
3757 | |
MethodSymbol m, |
3758 | |
MethodSymbol other, |
3759 | |
ClassSymbol origin) { |
3760 | |
|
3761 | 121 | Type mt = types.memberType(origin.type, m); |
3762 | 121 | Type ot = types.memberType(origin.type, other); |
3763 | |
|
3764 | |
|
3765 | |
|
3766 | |
|
3767 | 121 | List<Type> mtvars = mt.getTypeArguments(); |
3768 | 121 | List<Type> otvars = ot.getTypeArguments(); |
3769 | 121 | Type mtres = mt.getReturnType(); |
3770 | 121 | Type otres = types.subst(ot.getReturnType(), otvars, mtvars); |
3771 | |
|
3772 | 121 | boolean resultTypesOK = |
3773 | |
types.returnTypeSubstitutable(mt, ot, otres, null); |
3774 | 121 | if (!resultTypesOK) { |
3775 | 2 | if (!source.allowCovariantReturns() && |
3776 | |
m.owner != origin && |
3777 | |
m.owner.isSubClass(other.owner, types)) { |
3778 | |
|
3779 | |
} |
3780 | |
else { |
3781 | 2 | Type setReturnType = null; |
3782 | 2 | int typeTag = -1; |
3783 | 2 | if (mtres == syms.javafx_NumberType && otres == syms.floatType) { |
3784 | 2 | setReturnType = syms.floatType; |
3785 | 2 | typeTag = TypeTags.FLOAT; |
3786 | |
} |
3787 | 0 | else if ((mtres == syms.javafx_IntegerType || mtres == syms.javafx_NumberType) && otres == syms.byteType) { |
3788 | 0 | setReturnType = syms.byteType; |
3789 | 0 | typeTag = TypeTags.BYTE; |
3790 | |
} |
3791 | 0 | else if ((mtres == syms.javafx_IntegerType || mtres == syms.javafx_NumberType) && otres == syms.charType) { |
3792 | 0 | setReturnType = syms.charType; |
3793 | 0 | typeTag = TypeTags.CHAR; |
3794 | |
} |
3795 | 0 | else if ((mtres == syms.javafx_IntegerType || mtres == syms.javafx_NumberType) && otres == syms.shortType) { |
3796 | 0 | setReturnType = syms.shortType; |
3797 | 0 | typeTag = TypeTags.SHORT; |
3798 | |
} |
3799 | 0 | else if ((mtres == syms.javafx_IntegerType || mtres == syms.javafx_NumberType) && otres == syms.longType) { |
3800 | 0 | setReturnType = syms.longType; |
3801 | 0 | typeTag = TypeTags.LONG; |
3802 | |
} |
3803 | |
|
3804 | 2 | if (setReturnType != null) { |
3805 | 2 | JFXType oldType = tree.operation.getJFXReturnType(); |
3806 | 2 | tree.operation.rettype = make.TypeClass(make.TypeIdent(typeTag), oldType.getCardinality()); |
3807 | 2 | if (mt instanceof MethodType) { |
3808 | 2 | ((MethodType)mt).restype = setReturnType; |
3809 | |
} |
3810 | |
|
3811 | 2 | if (tree.type != null && tree.type instanceof MethodType) { |
3812 | 2 | ((MethodType)tree.type).restype = setReturnType; |
3813 | |
} |
3814 | |
} |
3815 | |
} |
3816 | |
} |
3817 | |
|
3818 | 121 | return true; |
3819 | |
} |
3820 | |
|
3821 | |
public void visitTimeLiteral(JFXTimeLiteral tree) { |
3822 | 22 | result = check(tree, syms.javafx_DurationType, VAL, pkind, pt, pSequenceness); |
3823 | 22 | } |
3824 | |
|
3825 | |
public void visitInterpolate(JFXInterpolate tree) { |
3826 | 0 | throw new Error(); |
3827 | |
|
3828 | |
|
3829 | |
|
3830 | |
|
3831 | |
|
3832 | |
|
3833 | |
|
3834 | |
|
3835 | |
} |
3836 | |
|
3837 | |
public void visitInterpolateValue(JFXInterpolateValue tree) { |
3838 | 5 | attribExpr(tree.attribute, env); |
3839 | 5 | attribExpr(tree.value, env, tree.attribute.type); |
3840 | 5 | if (tree.interpolation != null) |
3841 | 1 | attribExpr(tree.interpolation, env); |
3842 | 5 | result = check(tree, syms.javafx_KeyValueType, VAL, pkind, pt, pSequenceness); |
3843 | 5 | } |
3844 | |
|
3845 | |
|
3846 | |
|
3847 | |
|
3848 | |
|
3849 | |
|
3850 | |
|
3851 | |
|
3852 | |
|
3853 | |
|
3854 | |
|
3855 | |
|
3856 | |
|
3857 | |
|
3858 | |
|
3859 | |
|
3860 | |
|
3861 | |
|
3862 | |
|
3863 | |
|
3864 | |
|
3865 | |
|
3866 | |
|
3867 | |
|
3868 | |
|
3869 | |
|
3870 | |
|
3871 | |
|
3872 | |
|
3873 | |
|
3874 | |
|
3875 | |
|
3876 | |
|
3877 | |
public void visitKeyFrameLiteral(JFXKeyFrameLiteral tree) { |
3878 | 0 | throw new UnsupportedOperationException("Not supported yet."); |
3879 | |
} |
3880 | |
} |