1 /*
2 * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.tools.javac.comp;
27
28 import java.util.Map;
29 import java.util.Optional;
30
31 import javax.tools.JavaFileObject;
32 import javax.tools.JavaFileManager;
33
34 import com.sun.tools.javac.code.*;
35 import com.sun.tools.javac.code.Kinds.KindName;
36 import com.sun.tools.javac.code.Kinds.KindSelector;
37 import com.sun.tools.javac.code.Scope.*;
38 import com.sun.tools.javac.code.Symbol.*;
39 import com.sun.tools.javac.code.Type.*;
40 import com.sun.tools.javac.main.Option.PkgInfo;
41 import com.sun.tools.javac.resources.CompilerProperties.Errors;
42 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
43 import com.sun.tools.javac.tree.*;
44 import com.sun.tools.javac.tree.JCTree.*;
45 import com.sun.tools.javac.util.*;
46 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
47 import com.sun.tools.javac.util.List;
48
49 import static com.sun.tools.javac.code.Flags.*;
50 import static com.sun.tools.javac.code.Kinds.Kind.*;
51
52 /** This class enters symbols for all encountered definitions into
53 * the symbol table. The pass consists of high-level two phases,
54 * organized as follows:
55 *
56 * <p>In the first phase, all class symbols are entered into their
57 * enclosing scope, descending recursively down the tree for classes
58 * which are members of other classes. The class symbols are given a
59 * TypeEnter object as completer.
60 *
61 * <p>In the second phase classes are completed using
62 * TypeEnter.complete(). Completion might occur on demand, but
63 * any classes that are not completed that way will be eventually
64 * completed by processing the `uncompleted' queue. Completion
65 * entails determination of a class's parameters, supertype and
66 * interfaces, as well as entering all symbols defined in the
67 * class into its scope, with the exception of class symbols which
68 * have been entered in phase 1.
69 *
70 * <p>Whereas the first phase is organized as a sweep through all
71 * compiled syntax trees, the second phase is on-demand. Members of a
72 * class are entered when the contents of a class are first
73 * accessed. This is accomplished by installing completer objects in
74 * class symbols for compiled classes which invoke the type-enter
75 * phase for the corresponding class tree.
76 *
77 * <p>Classes migrate from one phase to the next via queues:
78 *
79 * <pre>{@literal
80 * class enter -> (Enter.uncompleted) --> type enter
81 * -> (Todo) --> attribute
82 * (only for toplevel classes)
83 * }</pre>
84 *
85 * <p><b>This is NOT part of any supported API.
86 * If you write code that depends on this, you do so at your own risk.
87 * This code and its internal interfaces are subject to change or
88 * deletion without notice.</b>
89 */
90 public class Enter extends JCTree.Visitor {
91 protected static final Context.Key<Enter> enterKey = new Context.Key<>();
92
93 Annotate annotate;
94 Log log;
95 Symtab syms;
96 Check chk;
97 TreeMaker make;
98 TypeEnter typeEnter;
99 Types types;
100 Lint lint;
101 Names names;
102 JavaFileManager fileManager;
103 PkgInfo pkginfoOpt;
104 TypeEnvs typeEnvs;
105 Modules modules;
106 JCDiagnostic.Factory diags;
107
108 private final Todo todo;
109
110 public static Enter instance(Context context) {
111 Enter instance = context.get(enterKey);
112 if (instance == null)
113 instance = new Enter(context);
114 return instance;
115 }
116
117 @SuppressWarnings("this-escape")
118 protected Enter(Context context) {
119 context.put(enterKey, this);
120
121 log = Log.instance(context);
122 make = TreeMaker.instance(context);
123 syms = Symtab.instance(context);
124 chk = Check.instance(context);
125 typeEnter = TypeEnter.instance(context);
126 types = Types.instance(context);
127 annotate = Annotate.instance(context);
128 lint = Lint.instance(context);
129 names = Names.instance(context);
130 modules = Modules.instance(context);
131 diags = JCDiagnostic.Factory.instance(context);
132
133 predefClassDef = make.ClassDef(
134 make.Modifiers(PUBLIC),
135 syms.predefClass.name,
136 List.nil(),
137 null,
138 List.nil(),
139 List.nil());
140 predefClassDef.sym = syms.predefClass;
141 todo = Todo.instance(context);
142 fileManager = context.get(JavaFileManager.class);
143
144 Options options = Options.instance(context);
145 pkginfoOpt = PkgInfo.get(options);
146 typeEnvs = TypeEnvs.instance(context);
147 }
148
149 /** Accessor for typeEnvs
150 */
151 public Env<AttrContext> getEnv(TypeSymbol sym) {
152 return typeEnvs.get(sym);
153 }
154
155 public Iterable<Env<AttrContext>> getEnvs() {
156 return typeEnvs.values();
157 }
158
159 public Env<AttrContext> getClassEnv(TypeSymbol sym) {
160 Env<AttrContext> localEnv = getEnv(sym);
161 if (localEnv == null) return null;
162 Env<AttrContext> lintEnv = localEnv;
163 while (lintEnv.info.lint == null)
164 lintEnv = lintEnv.next;
165 localEnv.info.lint = lintEnv.info.lint.augment(sym);
166 return localEnv;
167 }
168
169 /** The queue of all classes that might still need to be completed;
170 * saved and initialized by main().
171 */
172 ListBuffer<ClassSymbol> uncompleted;
173
174 /** The queue of classes that should have typeEnter completer installed after
175 * all the classes are discovered.
176 */
177 List<ClassSymbol> pendingCompleter = null;
178
179 /** The queue of modules whose imports still need to be checked. */
180 ListBuffer<JCCompilationUnit> unfinishedModules = new ListBuffer<>();
181
182 /** A dummy class to serve as enclClass for toplevel environments.
183 */
184 private JCClassDecl predefClassDef;
185
186 /* ************************************************************************
187 * environment construction
188 *************************************************************************/
189
190
191 /** Create a fresh environment for class bodies.
192 * This will create a fresh scope for local symbols of a class, referred
193 * to by the environments info.scope field.
194 * This scope will contain
195 * - symbols for this and super
196 * - symbols for any type parameters
197 * In addition, it serves as an anchor for scopes of methods and initializers
198 * which are nested in this scope via Scope.dup().
199 * This scope should not be confused with the members scope of a class.
200 *
201 * @param tree The class definition.
202 * @param env The environment current outside of the class definition.
203 */
204 public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) {
205 Env<AttrContext> localEnv =
206 env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
207 localEnv.enclClass = tree;
208 localEnv.outer = env;
209 localEnv.info.lint = null; // leave this to be filled in by Attr,
210 // when annotations have been processed
211 localEnv.info.isAnonymousDiamond = TreeInfo.isDiamond(env.tree);
212 localEnv.info.ctorPrologue = false;
213 return localEnv;
214 }
215
216 /** Create a fresh environment for toplevels.
217 * @param tree The toplevel tree.
218 */
219 Env<AttrContext> topLevelEnv(JCCompilationUnit tree) {
220 Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
221 localEnv.toplevel = tree;
222 localEnv.enclClass = predefClassDef;
223 tree.toplevelScope = WriteableScope.create(tree.packge);
224 tree.namedImportScope = new NamedImportScope(tree.packge);
225 tree.starImportScope = new StarImportScope(tree.packge);
226 tree.moduleImportScope = new StarImportScope(tree.packge);
227 localEnv.info.scope = tree.toplevelScope;
228 localEnv.info.lint = lint;
229 return localEnv;
230 }
231
232 public Env<AttrContext> getTopLevelEnv(JCCompilationUnit tree) {
233 Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
234 localEnv.toplevel = tree;
235 localEnv.enclClass = predefClassDef;
236 localEnv.info.scope = tree.toplevelScope;
237 localEnv.info.lint = lint;
238 return localEnv;
239 }
240
241 /** The scope in which a member definition in environment env is to be entered
242 * This is usually the environment's scope, except for class environments,
243 * where the local scope is for type variables, and the this and super symbol
244 * only, and members go into the class member scope.
245 */
246 WriteableScope enterScope(Env<AttrContext> env) {
247 return (env.tree.hasTag(JCTree.Tag.CLASSDEF))
248 ? ((JCClassDecl) env.tree).sym.members_field
249 : env.info.scope;
250 }
251
252 /** Create a fresh environment for modules.
253 *
254 * @param tree The module definition.
255 * @param env The environment current outside of the module definition.
256 */
257 public Env<AttrContext> moduleEnv(JCModuleDecl tree, Env<AttrContext> env) {
258 Assert.checkNonNull(tree.sym);
259 Env<AttrContext> localEnv =
260 env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
261 localEnv.enclClass = predefClassDef;
262 localEnv.outer = env;
263 localEnv.info.lint = null; // leave this to be filled in by Attr,
264 // when annotations have been processed
265 return localEnv;
266 }
267
268
269 /* ************************************************************************
270 * Visitor methods for phase 1: class enter
271 *************************************************************************/
272
273 /** Visitor argument: the current environment.
274 */
275 protected Env<AttrContext> env;
276
277 /** Visitor result: the computed type.
278 */
279 Type result;
280
281 /** Visitor method: enter all classes in given tree, catching any
282 * completion failure exceptions. Return the tree's type.
283 *
284 * @param tree The tree to be visited.
285 * @param env The environment visitor argument.
286 */
287 Type classEnter(JCTree tree, Env<AttrContext> env) {
288 Env<AttrContext> prevEnv = this.env;
289 try {
290 this.env = env;
291 annotate.blockAnnotations();
292 tree.accept(this);
293 return result;
294 } catch (CompletionFailure ex) {
295 return chk.completionError(tree.pos(), ex);
296 } finally {
297 annotate.unblockAnnotations();
298 this.env = prevEnv;
299 }
300 }
301
302 /** Visitor method: enter classes of a list of trees, returning a list of types.
303 */
304 <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) {
305 ListBuffer<Type> ts = new ListBuffer<>();
306 for (List<T> l = trees; l.nonEmpty(); l = l.tail) {
307 Type t = classEnter(l.head, env);
308 if (t != null)
309 ts.append(t);
310 }
311 return ts.toList();
312 }
313
314 @Override
315 public void visitTopLevel(JCCompilationUnit tree) {
316 JavaFileObject prev = log.useSource(tree.sourcefile);
317 boolean addEnv = false;
318 boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info",
319 JavaFileObject.Kind.SOURCE);
320 if (TreeInfo.isModuleInfo(tree)) {
321 JCPackageDecl pd = tree.getPackage();
322 if (pd != null) {
323 log.error(pd.pos(), Errors.NoPkgInModuleInfoJava);
324 }
325 tree.packge = syms.rootPackage;
326 Env<AttrContext> topEnv = topLevelEnv(tree);
327 classEnter(tree.defs, topEnv);
328 tree.modle.usesProvidesCompleter = modules.getUsesProvidesCompleter();
329 } else {
330 JCPackageDecl pd = tree.getPackage();
331 if (pd != null) {
332 tree.packge = pd.packge = syms.enterPackage(tree.modle, TreeInfo.fullName(pd.pid));
333 setPackageSymbols.scan(pd);
334 if ( pd.annotations.nonEmpty()
335 || pkginfoOpt == PkgInfo.ALWAYS
336 || tree.docComments != null) {
337 if (isPkgInfo) {
338 addEnv = true;
339 } else if (pd.annotations.nonEmpty()) {
340 log.error(pd.annotations.head.pos(),
341 Errors.PkgAnnotationsSbInPackageInfoJava);
342 }
343 }
344 } else {
345 tree.packge = tree.modle.unnamedPackage;
346 }
347
348 Map<Name, PackageSymbol> visiblePackages = tree.modle.visiblePackages;
349 Optional<ModuleSymbol> dependencyWithPackage =
350 syms.listPackageModules(tree.packge.fullname)
351 .stream()
352 .filter(m -> m != tree.modle)
353 .filter(cand -> visiblePackages.get(tree.packge.fullname) == syms.getPackage(cand, tree.packge.fullname))
354 .findAny();
355
356 if (dependencyWithPackage.isPresent()) {
357 log.error(pd, Errors.PackageInOtherModule(dependencyWithPackage.get()));
358 }
359
360 tree.packge.complete(); // Find all classes in package.
361
362 Env<AttrContext> topEnv = topLevelEnv(tree);
363 Env<AttrContext> packageEnv = null;
364
365 // Save environment of package-info.java file.
366 if (isPkgInfo) {
367 packageEnv = topEnv.dup(pd != null ? pd : tree);
368
369 Env<AttrContext> env0 = typeEnvs.get(tree.packge);
370 if (env0 != null) {
371 JCCompilationUnit tree0 = env0.toplevel;
372 if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
373 log.warning(pd != null ? pd.pid.pos() : null,
374 Warnings.PkgInfoAlreadySeen(tree.packge));
375 }
376 }
377 typeEnvs.put(tree.packge, packageEnv);
378
379 for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner)
380 q.flags_field |= EXISTS;
381
382 Name name = names.package_info;
383 ClassSymbol c = syms.enterClass(tree.modle, name, tree.packge);
384 c.flatname = names.fromString(tree.packge + "." + name);
385 c.classfile = c.sourcefile = tree.sourcefile;
386 c.completer = Completer.NULL_COMPLETER;
387 c.members_field = WriteableScope.create(c);
388 tree.packge.package_info = c;
389 tree.packge.sourcefile = tree.sourcefile;
390 }
391 classEnter(tree.defs, topEnv);
392 if (addEnv) {
393 todo.append(packageEnv);
394 }
395 }
396 log.useSource(prev);
397 result = null;
398 }
399 //where:
400 //set package Symbols to the package expression:
401 private final TreeScanner setPackageSymbols = new TreeScanner() {
402 Symbol currentPackage;
403
404 @Override
405 public void visitIdent(JCIdent tree) {
406 tree.sym = currentPackage;
407 tree.type = currentPackage.type;
408 }
409
410 @Override
411 public void visitSelect(JCFieldAccess tree) {
412 tree.sym = currentPackage;
413 tree.type = currentPackage.type;
414 currentPackage = currentPackage.owner;
415 super.visitSelect(tree);
416 }
417
418 @Override
419 public void visitPackageDef(JCPackageDecl tree) {
420 currentPackage = tree.packge;
421 scan(tree.pid);
422 }
423 };
424
425 @Override
426 public void visitClassDef(JCClassDecl tree) {
427 Symbol owner = env.info.scope.owner;
428 WriteableScope enclScope = enterScope(env);
429 ClassSymbol c;
430 if (owner.kind == PCK) {
431 // We are seeing a toplevel class.
432 PackageSymbol packge = (PackageSymbol)owner;
433 for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner)
434 q.flags_field |= EXISTS;
435 c = syms.enterClass(env.toplevel.modle, tree.name, packge);
436 packge.members().enterIfAbsent(c);
437 if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {
438 KindName topElement = KindName.CLASS;
439 if ((tree.mods.flags & ENUM) != 0) {
440 topElement = KindName.ENUM;
441 } else if ((tree.mods.flags & INTERFACE) != 0) {
442 topElement = KindName.INTERFACE;
443 }
444 log.error(tree.pos(),
445 Errors.ClassPublicShouldBeInFile(topElement, tree.name));
446 }
447 if ((tree.mods.flags & IMPLICIT_CLASS) != 0) {
448 syms.removeClass(env.toplevel.modle, tree.name);
449 }
450 } else {
451 if (!tree.name.isEmpty() &&
452 !chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {
453 result = null;
454 return;
455 }
456 if (owner.kind == TYP) {
457 // We are seeing a member class.
458 c = syms.enterClass(env.toplevel.modle, tree.name, (TypeSymbol)owner);
459 if (c.owner != owner) {
460 if (c.name != tree.name) {
461 log.error(tree.pos(), Errors.SameBinaryName(c.name, tree.name));
462 result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType);
463 tree.sym = (ClassSymbol)result.tsym;
464 return;
465 }
466 //anonymous class loaded from a classfile may be recreated from source (see below)
467 //if this class is a member of such an anonymous class, fix the owner:
468 Assert.check(owner.owner.kind != TYP, owner::toString);
469 Assert.check(c.owner.kind == TYP, () -> c.owner.toString());
470 ClassSymbol cowner = (ClassSymbol) c.owner;
471 if (cowner.members_field != null) {
472 cowner.members_field.remove(c);
473 }
474 c.owner = owner;
475 }
476 if ((owner.flags_field & INTERFACE) != 0) {
477 tree.mods.flags |= PUBLIC | STATIC;
478 }
479 } else {
480 // We are seeing a local class.
481 c = syms.defineClass(tree.name, owner);
482 c.flatname = chk.localClassName(c);
483 if (!c.name.isEmpty())
484 chk.checkTransparentClass(tree.pos(), c, env.info.scope);
485 }
486 }
487 tree.sym = c;
488
489 // Enter class into `compiled' table and enclosing scope.
490 if (chk.getCompiled(c) != null) {
491 duplicateClass(tree.pos(), c);
492 result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType);
493 tree.sym = (ClassSymbol)result.tsym;
494 return;
495 }
496 chk.putCompiled(c);
497 enclScope.enter(c);
498
499 // Set up an environment for class block and store in `typeEnvs'
500 // table, to be retrieved later in memberEnter and attribution.
501 Env<AttrContext> localEnv = classEnv(tree, env);
502 typeEnvs.put(c, localEnv);
503
504 // Fill out class fields.
505 c.completer = Completer.NULL_COMPLETER; // do not allow the initial completer linger on.
506 c.flags_field = chk.checkFlags(tree.mods.flags, c, tree) | FROM_SOURCE;
507 c.classfile = c.sourcefile = env.toplevel.sourcefile;
508 c.members_field = WriteableScope.create(c);
509 c.isPermittedExplicit = tree.permitting.nonEmpty();
510 c.clearAnnotationMetadata();
511
512 ClassType ct = (ClassType)c.type;
513 if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
514 // We are seeing a local or inner class.
515 // Set outer_field of this class to closest enclosing class
516 // which contains this class in a non-static context
517 // (its "enclosing instance class"), provided such a class exists.
518 Symbol owner1 = owner;
519 while (owner1.kind.matches(KindSelector.VAL_MTH) &&
520 (owner1.flags_field & STATIC) == 0) {
521 owner1 = owner1.owner;
522 }
523 if (owner1.kind == TYP) {
524 ct.setEnclosingType(owner1.type);
525 }
526 }
527
528 // Enter type parameters.
529 ct.typarams_field = classEnter(tree.typarams, localEnv);
530 ct.allparams_field = null;
531
532 // schedule installation of further completer for this type.
533 if (pendingCompleter != null) {
534 pendingCompleter = pendingCompleter.prepend(c);
535 } else {
536 c.completer = typeEnter;
537 }
538
539 // Add non-local class to uncompleted, to make sure it will be
540 // completed later.
541 if (!c.isDirectlyOrIndirectlyLocal() && uncompleted != null) uncompleted.append(c);
542 // System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG
543
544 // Recursively enter all member classes.
545 classEnter(tree.defs, localEnv);
546
547 // Assert.checkNonNull(c.modle, c.sourcefile.toString());
548
549 result = tree.type = c.type;
550 }
551 //where
552 /** Does class have the same name as the file it appears in?
553 */
554 private static boolean classNameMatchesFileName(ClassSymbol c,
555 Env<AttrContext> env) {
556 return env.toplevel.sourcefile.isNameCompatible(c.name.toString(),
557 JavaFileObject.Kind.SOURCE);
558 }
559
560 /** Complain about a duplicate class. */
561 protected void duplicateClass(DiagnosticPosition pos, ClassSymbol c) {
562 log.error(pos, Errors.DuplicateClass(c.fullname));
563 }
564
565 /** Class enter visitor method for type parameters.
566 * Enter a symbol for type parameter in local scope, after checking that it
567 * is unique.
568 */
569 @Override
570 public void visitTypeParameter(JCTypeParameter tree) {
571 TypeVar a = (tree.type != null)
572 ? (TypeVar)tree.type
573 : new TypeVar(tree.name, env.info.scope.owner, syms.botType);
574 tree.type = a;
575 if (chk.checkUnique(tree.pos(), a.tsym, env.info.scope)) {
576 env.info.scope.enter(a.tsym);
577 }
578 result = a;
579 }
580
581 @Override
582 public void visitModuleDef(JCModuleDecl tree) {
583 Env<AttrContext> moduleEnv = moduleEnv(tree, env);
584 typeEnvs.put(tree.sym, moduleEnv);
585 if (modules.isInModuleGraph(tree.sym)) {
586 todo.append(moduleEnv);
587 }
588 }
589
590 /** Default class enter visitor method: do nothing.
591 */
592 @Override
593 public void visitTree(JCTree tree) {
594 result = null;
595 }
596
597 /** Main method: enter all classes in a list of toplevel trees.
598 * @param trees The list of trees to be processed.
599 */
600 public void main(List<JCCompilationUnit> trees) {
601 complete(trees, null);
602 }
603
604 /** Main method: enter classes from the list of toplevel trees, possibly
605 * skipping TypeEnter for all but 'c' by placing them on the uncompleted
606 * list.
607 * @param trees The list of trees to be processed.
608 * @param c The class symbol to be processed or null to process all.
609 */
610 public void complete(List<JCCompilationUnit> trees, ClassSymbol c) {
611 annotate.blockAnnotations();
612 ListBuffer<ClassSymbol> prevUncompleted = uncompleted;
613 if (typeEnter.completionEnabled) uncompleted = new ListBuffer<>();
614
615 try {
616 List<ClassSymbol> prevPendingCompleter = pendingCompleter;
617 try {
618 pendingCompleter = List.nil();
619 // enter all classes, and construct uncompleted list
620 classEnter(trees, null);
621 // install further completer for classes recognized by the above task:
622 for (ClassSymbol sym : pendingCompleter) {
623 sym.completer = typeEnter;
624 }
625 } finally {
626 pendingCompleter = prevPendingCompleter;
627 }
628
629 // complete all uncompleted classes in memberEnter
630 if (typeEnter.completionEnabled) {
631 while (uncompleted.nonEmpty()) {
632 ClassSymbol clazz = uncompleted.next();
633 if (c == null || c == clazz || prevUncompleted == null)
634 clazz.complete();
635 else
636 // defer
637 prevUncompleted.append(clazz);
638 }
639
640 if (!modules.modulesInitialized()) {
641 for (JCCompilationUnit cut : trees) {
642 if (cut.getModuleDecl() != null) {
643 unfinishedModules.append(cut);
644 } else {
645 typeEnter.ensureImportsChecked(List.of(cut));
646 }
647 }
648 } else {
649 typeEnter.ensureImportsChecked(unfinishedModules.toList());
650 unfinishedModules.clear();
651 typeEnter.ensureImportsChecked(trees);
652 }
653 }
654 } finally {
655 uncompleted = prevUncompleted;
656 annotate.unblockAnnotations();
657 }
658 }
659
660 public void newRound() {
661 typeEnvs.clear();
662 }
663
664 public void unenter(JCCompilationUnit topLevel, JCTree tree) {
665 new UnenterScanner(topLevel.modle).scan(tree);
666 }
667 class UnenterScanner extends TreeScanner {
668 private final ModuleSymbol msym;
669
670 public UnenterScanner(ModuleSymbol msym) {
671 this.msym = msym;
672 }
673
674 @Override
675 public void visitClassDef(JCClassDecl tree) {
676 ClassSymbol csym = tree.sym;
677 //if something went wrong during method applicability check
678 //it is possible that nested expressions inside argument expression
679 //are left unchecked - in such cases there's nothing to clean up.
680 if (csym == null) return;
681 typeEnvs.remove(csym);
682 chk.removeCompiled(csym);
683 chk.clearLocalClassNameIndexes(csym);
684 syms.removeClass(msym, csym.flatname);
685 super.visitClassDef(tree);
686 }
687 }
688 }