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 static com.sun.tools.javac.code.Flags.*; |
29 | |
import static com.sun.tools.javac.code.Kinds.*; |
30 | |
import com.sun.tools.javac.code.*; |
31 | |
import com.sun.tools.javac.code.Type.*; |
32 | |
import com.sun.tools.javac.code.Symbol.*; |
33 | |
import com.sun.tools.javac.code.Type.ClassType; |
34 | |
import com.sun.tools.javac.code.Type.ErrorType; |
35 | |
import com.sun.tools.javac.tree.JCTree; |
36 | |
import com.sun.tools.javac.tree.JCTree.*; |
37 | |
import com.sun.tools.javac.jvm.*; |
38 | |
import com.sun.tools.javac.util.*; |
39 | |
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
40 | |
|
41 | |
import com.sun.tools.javafx.tree.*; |
42 | |
import com.sun.tools.javafx.code.*; |
43 | |
import com.sun.tools.javafx.util.MsgSym; |
44 | |
|
45 | |
import java.util.Map; |
46 | |
import java.util.HashMap; |
47 | |
import javax.tools.JavaFileObject; |
48 | |
import javax.tools.JavaFileManager; |
49 | |
|
50 | |
public class JavafxEnter extends JavafxTreeScanner { |
51 | 12 | protected static final Context.Key<JavafxEnter> javafxEnterKey = |
52 | |
new Context.Key<JavafxEnter>(); |
53 | |
|
54 | |
private final Log log; |
55 | |
private final JavafxSymtab syms; |
56 | |
private final JavafxCheck chk; |
57 | |
private final JavafxTreeMaker make; |
58 | |
private final ClassReader reader; |
59 | |
private final JavafxAnnotate annotate; |
60 | |
private final JavafxMemberEnter memberEnter; |
61 | |
private final Lint lint; |
62 | |
private final JavaFileManager fileManager; |
63 | |
private final JavafxTodo todo; |
64 | |
private final JavafxTypes types; |
65 | |
private JavafxModuleBuilder javafxModuleBuilder; |
66 | |
|
67 | |
public static JavafxEnter instance(Context context) { |
68 | 1197 | JavafxEnter instance = context.get(javafxEnterKey); |
69 | 1197 | if (instance == null) |
70 | 399 | instance = new JavafxEnter(context); |
71 | 1197 | return instance; |
72 | |
} |
73 | |
|
74 | 399 | protected JavafxEnter(Context context) { |
75 | 399 | context.put(javafxEnterKey, this); |
76 | |
|
77 | 399 | log = Log.instance(context); |
78 | 399 | reader = ClassReader.instance(context); |
79 | 399 | make = (JavafxTreeMaker)JavafxTreeMaker.instance(context); |
80 | 399 | syms = (JavafxSymtab)JavafxSymtab.instance(context); |
81 | 399 | chk = JavafxCheck.instance(context); |
82 | 399 | memberEnter = JavafxMemberEnter.instance(context); |
83 | 399 | annotate = JavafxAnnotate.instance(context); |
84 | 399 | lint = Lint.instance(context); |
85 | 399 | javafxModuleBuilder = JavafxModuleBuilder.instance(context); |
86 | |
|
87 | 399 | predefClassDef = make.ClassDeclaration( |
88 | |
make.Modifiers(PUBLIC), |
89 | |
syms.predefClass.name, List.<JCExpression>nil(), null); |
90 | 399 | predefClassDef.sym = syms.predefClass; |
91 | 399 | todo = JavafxTodo.instance(context); |
92 | 399 | fileManager = context.get(JavaFileManager.class); |
93 | 399 | types = JavafxTypes.instance(context); |
94 | 399 | } |
95 | |
|
96 | |
|
97 | |
|
98 | |
|
99 | 399 | Map<TypeSymbol,JavafxEnv<JavafxAttrContext>> typeEnvs = |
100 | |
new HashMap<TypeSymbol,JavafxEnv<JavafxAttrContext>>(); |
101 | |
|
102 | |
|
103 | |
|
104 | |
@Override |
105 | |
public void scan(JCTree tree) { |
106 | 57915 | if(tree!=null) tree.accept(this); |
107 | 57915 | } |
108 | |
|
109 | |
|
110 | |
|
111 | |
@Override |
112 | |
public void scan(List<? extends JCTree> trees) { |
113 | 12375 | if (trees != null) |
114 | 23310 | for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) |
115 | 10935 | scan(l.head); |
116 | 12375 | } |
117 | |
|
118 | |
|
119 | |
|
120 | |
public JavafxEnv<JavafxAttrContext> getEnv(TypeSymbol sym) { |
121 | 0 | return typeEnvs.get(sym); |
122 | |
} |
123 | |
|
124 | |
|
125 | |
|
126 | |
|
127 | |
|
128 | |
protected |
129 | |
|
130 | |
ListBuffer<ClassSymbol> uncompleted; |
131 | |
|
132 | |
|
133 | |
|
134 | |
private JFXClassDeclaration predefClassDef; |
135 | |
|
136 | |
|
137 | |
|
138 | |
|
139 | |
|
140 | |
|
141 | |
|
142 | |
|
143 | |
|
144 | |
|
145 | |
|
146 | |
|
147 | |
|
148 | |
|
149 | |
|
150 | |
|
151 | |
|
152 | |
|
153 | |
|
154 | |
public static JavafxEnv<JavafxAttrContext> classEnv(JFXClassDeclaration tree, JavafxEnv<JavafxAttrContext> env) { |
155 | 702 | JavafxEnv<JavafxAttrContext> localEnv = |
156 | |
env.dup(tree, env.info.dup(new Scope(tree.sym))); |
157 | 702 | localEnv.enclClass = tree; |
158 | 702 | localEnv.outer = env; |
159 | 702 | localEnv.info.isSelfCall = false; |
160 | 702 | localEnv.info.lint = null; |
161 | |
|
162 | 702 | return localEnv; |
163 | |
} |
164 | |
|
165 | |
|
166 | |
|
167 | |
|
168 | |
JavafxEnv<JavafxAttrContext> topLevelEnv(JCCompilationUnit tree) { |
169 | 690 | JavafxEnv<JavafxAttrContext> localEnv = new JavafxEnv<JavafxAttrContext>(tree, new JavafxAttrContext()); |
170 | 690 | localEnv.toplevel = tree; |
171 | 690 | localEnv.enclClass = predefClassDef; |
172 | 690 | tree.namedImportScope = new Scope.ImportScope(tree.packge); |
173 | 690 | tree.starImportScope = new Scope.ImportScope(tree.packge); |
174 | 690 | localEnv.info.scope = tree.namedImportScope; |
175 | 690 | localEnv.info.lint = lint; |
176 | 690 | return localEnv; |
177 | |
} |
178 | |
|
179 | |
|
180 | |
|
181 | |
|
182 | |
|
183 | |
|
184 | |
public static Scope enterScope(JavafxEnv<JavafxAttrContext> env) { |
185 | 5940 | return (env.tree.getTag() == JavafxTag.CLASS_DEF) |
186 | |
? ((JFXClassDeclaration) env.tree).sym.members_field |
187 | |
: env.info.scope; |
188 | |
} |
189 | |
|
190 | |
|
191 | |
|
192 | |
|
193 | |
|
194 | |
|
195 | |
|
196 | |
protected JavafxEnv<JavafxAttrContext> env; |
197 | |
|
198 | |
|
199 | |
|
200 | |
|
201 | |
protected |
202 | |
|
203 | |
Type result; |
204 | |
|
205 | |
|
206 | |
|
207 | |
|
208 | |
|
209 | |
|
210 | |
|
211 | |
Type classEnter(JCTree tree, JavafxEnv<JavafxAttrContext> env) { |
212 | 3176 | JavafxEnv<JavafxAttrContext> prevEnv = this.env; |
213 | |
try { |
214 | 3176 | this.env = env; |
215 | 3176 | tree.accept(this); |
216 | 3176 | return result; |
217 | 0 | } catch (CompletionFailure ex) { |
218 | 0 | return chk.completionError(tree.pos(), ex); |
219 | |
} finally { |
220 | 3176 | this.env = prevEnv; |
221 | |
} |
222 | |
} |
223 | |
|
224 | |
|
225 | |
|
226 | |
|
227 | |
protected |
228 | |
|
229 | |
<T extends JCTree> List<Type> classEnter(List<T> trees, JavafxEnv<JavafxAttrContext> env) { |
230 | 2172 | ListBuffer<Type> ts = new ListBuffer<Type>(); |
231 | 5322 | for (List<T> l = trees; l.nonEmpty(); l = l.tail) |
232 | 3150 | ts.append(classEnter(l.head, env)); |
233 | 2172 | return ts.toList(); |
234 | |
} |
235 | |
|
236 | |
@Override |
237 | |
public void visitTopLevel(JCCompilationUnit tree) { |
238 | 385 | JavaFileObject prev = log.useSource(tree.sourcefile); |
239 | 385 | boolean addEnv = false; |
240 | 385 | boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info", |
241 | |
JavaFileObject.Kind.SOURCE); |
242 | 385 | if (tree.pid != null) { |
243 | 9 | tree.packge = reader.enterPackage(JavafxTreeInfo.fullName(tree.pid)); |
244 | 9 | if (tree.packageAnnotations.nonEmpty()) { |
245 | 0 | if (isPkgInfo) { |
246 | 0 | addEnv = true; |
247 | |
} else { |
248 | 0 | log.error(tree.packageAnnotations.head.pos(), |
249 | |
MsgSym.MESSAGE_PKG_ANNOTATIONS_SB_IN_PACKAGE_INFO_JAVA); |
250 | |
} |
251 | |
} |
252 | |
} else { |
253 | 376 | tree.packge = syms.unnamedPackage; |
254 | |
} |
255 | 385 | tree.packge.complete(); |
256 | 385 | JavafxEnv<JavafxAttrContext> localEnv = topLevelEnv(tree); |
257 | |
|
258 | 385 | javafxModuleBuilder.preProcessJfxTopLevel(tree); |
259 | |
|
260 | |
|
261 | 385 | if (isPkgInfo) { |
262 | 0 | JavafxEnv<JavafxAttrContext> env0 = typeEnvs.get(tree.packge); |
263 | 0 | if (env0 == null) { |
264 | 0 | typeEnvs.put(tree.packge, localEnv); |
265 | |
} else { |
266 | 0 | JCCompilationUnit tree0 = env0.toplevel; |
267 | 0 | if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) { |
268 | 0 | log.warning(tree.pid != null ? tree.pid.pos() |
269 | |
: null, |
270 | |
MsgSym.MESSAGE_PKG_INFO_ALREADY_SEEN, |
271 | |
tree.packge); |
272 | 0 | if (addEnv || (tree0.packageAnnotations.isEmpty() && |
273 | |
tree.docComments != null && |
274 | |
tree.docComments.get(tree) != null)) { |
275 | 0 | typeEnvs.put(tree.packge, localEnv); |
276 | |
} |
277 | |
} |
278 | |
} |
279 | |
} |
280 | 385 | classEnter(tree.defs, localEnv); |
281 | 385 | if (addEnv) { |
282 | 0 | todo.append(localEnv); |
283 | |
} |
284 | 385 | log.useSource(prev); |
285 | 385 | result = null; |
286 | 385 | } |
287 | |
|
288 | |
@Override |
289 | |
public void visitClassDeclaration(JFXClassDeclaration tree) { |
290 | 702 | Symbol owner = env.info.scope.owner; |
291 | 702 | Scope enclScope = enterScope(env); |
292 | |
ClassSymbol c; |
293 | 702 | if (owner.kind == PCK) { |
294 | |
|
295 | 385 | PackageSymbol packge = (PackageSymbol) owner; |
296 | 1171 | for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner) |
297 | 786 | q.flags_field |= EXISTS; |
298 | 385 | c = reader.enterClass(tree.getName(), packge); |
299 | 385 | packge.members().enterIfAbsent(c); |
300 | 385 | } else { |
301 | 317 | if (tree.getName().len != 0 && |
302 | |
!chk.checkUniqueClassName(tree.pos(), tree.getName(), enclScope)) { |
303 | 0 | result = null; |
304 | 0 | return; |
305 | |
} |
306 | 317 | if (owner.kind == TYP) { |
307 | |
|
308 | 291 | c = reader.enterClass(tree.getName(), (TypeSymbol) owner); |
309 | 291 | if ((owner.flags_field & INTERFACE) != 0) { |
310 | 0 | tree.mods.flags |= PUBLIC | STATIC; |
311 | |
} |
312 | |
} else { |
313 | |
|
314 | 26 | c = reader.defineClass(tree.getName(), owner); |
315 | 26 | c.flatname = chk.localClassName(c); |
316 | 26 | if (c.name.len != 0) |
317 | 26 | chk.checkTransparentClass(tree.pos(), c, env.info.scope); |
318 | |
} |
319 | |
} |
320 | 702 | tree.sym = c; |
321 | |
|
322 | |
|
323 | 702 | if (chk.compiled.get(c.flatname) != null) { |
324 | 0 | duplicateClass(tree.pos(), c); |
325 | 0 | result = new ErrorType(tree.getName(), (TypeSymbol) owner); |
326 | 0 | tree.sym = (ClassSymbol) result.tsym; |
327 | 0 | return; |
328 | |
} |
329 | 702 | chk.compiled.put(c.flatname, c); |
330 | 702 | enclScope.enter(c); |
331 | |
|
332 | |
|
333 | |
|
334 | 702 | JavafxEnv<JavafxAttrContext> localEnv = classEnv(tree, env); |
335 | 702 | typeEnvs.put(c, localEnv); |
336 | |
|
337 | |
|
338 | 702 | c.completer = memberEnter; |
339 | 702 | c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree); |
340 | 702 | c.sourcefile = env.toplevel.sourcefile; |
341 | 702 | c.members_field = new Scope(c); |
342 | |
|
343 | 702 | ClassType ct = (ClassType) c.type; |
344 | 702 | if (owner.kind != PCK && (c.flags_field & STATIC) == 0) { |
345 | |
|
346 | |
|
347 | |
|
348 | |
|
349 | 26 | Symbol owner1 = owner; |
350 | |
while ((owner1.kind & (VAR | MTH)) != 0 && |
351 | 26 | (owner1.flags_field & STATIC) == 0) { |
352 | 0 | owner1 = owner1.owner; |
353 | |
} |
354 | 26 | if (owner1.kind == TYP) { |
355 | 26 | ct.setEnclosingType(owner1.type); |
356 | |
} |
357 | |
} |
358 | |
|
359 | |
|
360 | 702 | ct.typarams_field = classEnter(tree.getEmptyTypeParameters(), localEnv); |
361 | |
|
362 | |
|
363 | |
|
364 | 702 | if (!c.isLocal() && uncompleted != null) uncompleted.append(c); |
365 | |
|
366 | 702 | classEnter(tree.getMembers(), localEnv); |
367 | |
|
368 | 702 | types.addFxClass(c, tree); |
369 | 702 | result = c.type; |
370 | 702 | } |
371 | |
|
372 | |
|
373 | |
protected void duplicateClass(DiagnosticPosition pos, ClassSymbol c) { |
374 | 0 | log.error(pos, MsgSym.MESSAGE_DUPLICATE_CLASS, c.fullname); |
375 | 0 | } |
376 | |
|
377 | |
|
378 | |
|
379 | |
|
380 | |
|
381 | |
@Override |
382 | |
public void visitTypeParameter(JCTypeParameter tree) { |
383 | 0 | TypeVar a = (tree.type != null) |
384 | |
? (TypeVar)tree.type |
385 | |
: new TypeVar(tree.name, env.info.scope.owner, syms.botType); |
386 | 0 | tree.type = a; |
387 | 0 | if (chk.checkUnique(tree.pos(), a.tsym, env.info.scope)) { |
388 | 0 | env.info.scope.enter(a.tsym); |
389 | |
} |
390 | 0 | result = a; |
391 | 0 | } |
392 | |
|
393 | |
|
394 | |
|
395 | |
@Override |
396 | |
public void visitTree(JCTree tree) { |
397 | 0 | result = null; |
398 | 0 | } |
399 | |
|
400 | |
|
401 | |
|
402 | |
|
403 | |
public void main(List<JCCompilationUnit> trees) { |
404 | 383 | complete(trees, null); |
405 | 383 | } |
406 | |
|
407 | |
|
408 | |
|
409 | |
|
410 | |
|
411 | |
|
412 | |
public void complete(List<JCCompilationUnit> trees, ClassSymbol c) { |
413 | 383 | annotate.enterStart(); |
414 | 383 | ListBuffer<ClassSymbol> prevUncompleted = uncompleted; |
415 | 383 | if (memberEnter.completionEnabled) uncompleted = new ListBuffer<ClassSymbol>(); |
416 | |
|
417 | |
try { |
418 | |
|
419 | 383 | classEnter(trees, null); |
420 | |
|
421 | |
|
422 | 383 | if (memberEnter.completionEnabled) { |
423 | 1059 | while (uncompleted.nonEmpty()) { |
424 | 676 | ClassSymbol clazz = uncompleted.next(); |
425 | 676 | if (c == null || c == clazz || prevUncompleted == null) |
426 | 676 | clazz.complete(); |
427 | |
else |
428 | |
|
429 | 0 | prevUncompleted.append(clazz); |
430 | 676 | } |
431 | |
|
432 | |
|
433 | |
|
434 | 383 | for (JCCompilationUnit tree : trees) { |
435 | 385 | if (tree.starImportScope.elems == null) { |
436 | 305 | JavaFileObject prev = log.useSource(tree.sourcefile); |
437 | 305 | JavafxEnv<JavafxAttrContext> localEnv = typeEnvs.get(tree.packge); |
438 | 305 | if (localEnv == null) |
439 | 305 | localEnv = topLevelEnv(tree); |
440 | 305 | memberEnter.memberEnter(tree, localEnv); |
441 | 305 | log.useSource(prev); |
442 | 385 | } |
443 | |
} |
444 | |
} |
445 | |
} finally { |
446 | 383 | uncompleted = prevUncompleted; |
447 | 383 | annotate.enterDone(); |
448 | 383 | } |
449 | 383 | } |
450 | |
|
451 | |
} |