1 /*
  2  * Copyright (c) 1999, 2022, 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.code.Type.ClassType.Flavor;
 41 import com.sun.tools.javac.main.Option.PkgInfo;
 42 import com.sun.tools.javac.resources.CompilerProperties.Errors;
 43 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
 44 import com.sun.tools.javac.tree.*;
 45 import com.sun.tools.javac.tree.JCTree.*;
 46 import com.sun.tools.javac.util.*;
 47 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 48 import com.sun.tools.javac.util.List;
 49 
 50 import static com.sun.tools.javac.code.Flags.*;
 51 import static com.sun.tools.javac.code.Kinds.Kind.*;
 52 
 53 /** This class enters symbols for all encountered definitions into
 54  *  the symbol table. The pass consists of high-level two phases,
 55  *  organized as follows:
 56  *
 57  *  <p>In the first phase, all class symbols are entered into their
 58  *  enclosing scope, descending recursively down the tree for classes
 59  *  which are members of other classes. The class symbols are given a
 60  *  TypeEnter object as completer.
 61  *
 62  *  <p>In the second phase classes are completed using
 63  *  TypeEnter.complete(). Completion might occur on demand, but
 64  *  any classes that are not completed that way will be eventually
 65  *  completed by processing the `uncompleted' queue. Completion
 66  *  entails determination of a class's parameters, supertype and
 67  *  interfaces, as well as entering all symbols defined in the
 68  *  class into its scope, with the exception of class symbols which
 69  *  have been entered in phase 1.
 70  *
 71  *  <p>Whereas the first phase is organized as a sweep through all
 72  *  compiled syntax trees, the second phase is on-demand. Members of a
 73  *  class are entered when the contents of a class are first
 74  *  accessed. This is accomplished by installing completer objects in
 75  *  class symbols for compiled classes which invoke the type-enter
 76  *  phase for the corresponding class tree.
 77  *
 78  *  <p>Classes migrate from one phase to the next via queues:
 79  *
 80  *  <pre>{@literal
 81  *  class enter -> (Enter.uncompleted)         --> type enter
 82  *              -> (Todo)                      --> attribute
 83  *                                              (only for toplevel classes)
 84  *  }</pre>
 85  *
 86  *  <p><b>This is NOT part of any supported API.
 87  *  If you write code that depends on this, you do so at your own risk.
 88  *  This code and its internal interfaces are subject to change or
 89  *  deletion without notice.</b>
 90  */
 91 public class Enter extends JCTree.Visitor {
 92     protected static final Context.Key<Enter> enterKey = new Context.Key<>();
 93 
 94     Annotate annotate;
 95     Log log;
 96     Symtab syms;
 97     Check chk;
 98     TreeMaker make;
 99     TypeEnter typeEnter;
100     Types types;
101     Lint lint;
102     Names names;
103     JavaFileManager fileManager;
104     PkgInfo pkginfoOpt;
105     TypeEnvs typeEnvs;
106     Modules modules;
107     JCDiagnostic.Factory diags;
108     boolean allowPrimitiveClasses;
109 
110     private final Todo todo;
111 
112     public static Enter instance(Context context) {
113         Enter instance = context.get(enterKey);
114         if (instance == null)
115             instance = new Enter(context);
116         return instance;
117     }
118 
119     protected Enter(Context context) {
120         context.put(enterKey, this);
121 
122         log = Log.instance(context);
123         make = TreeMaker.instance(context);
124         syms = Symtab.instance(context);
125         chk = Check.instance(context);
126         typeEnter = TypeEnter.instance(context);
127         types = Types.instance(context);
128         annotate = Annotate.instance(context);
129         lint = Lint.instance(context);
130         names = Names.instance(context);
131         modules = Modules.instance(context);
132         diags = JCDiagnostic.Factory.instance(context);
133 
134         predefClassDef = make.ClassDef(
135             make.Modifiers(PUBLIC),
136             syms.predefClass.name,
137             List.nil(),
138             null,
139             List.nil(),
140             List.nil());
141         predefClassDef.sym = syms.predefClass;
142         todo = Todo.instance(context);
143         fileManager = context.get(JavaFileManager.class);
144 
145         Options options = Options.instance(context);
146         pkginfoOpt = PkgInfo.get(options);
147         typeEnvs = TypeEnvs.instance(context);
148         Source source = Source.instance(context);
149         allowPrimitiveClasses = Source.Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
150     }
151 
152     /** Accessor for typeEnvs
153      */
154     public Env<AttrContext> getEnv(TypeSymbol sym) {
155         return typeEnvs.get(sym);
156     }
157 
158     public Iterable<Env<AttrContext>> getEnvs() {
159         return typeEnvs.values();
160     }
161 
162     public Env<AttrContext> getClassEnv(TypeSymbol sym) {
163         Env<AttrContext> localEnv = getEnv(sym);
164         if (localEnv == null) return null;
165         Env<AttrContext> lintEnv = localEnv;
166         while (lintEnv.info.lint == null)
167             lintEnv = lintEnv.next;
168         localEnv.info.lint = lintEnv.info.lint.augment(sym);
169         return localEnv;
170     }
171 
172     /** The queue of all classes that might still need to be completed;
173      *  saved and initialized by main().
174      */
175     ListBuffer<ClassSymbol> uncompleted;
176 
177     /** The queue of modules whose imports still need to be checked. */
178     ListBuffer<JCCompilationUnit> unfinishedModules = new ListBuffer<>();
179 
180     /** A dummy class to serve as enclClass for toplevel environments.
181      */
182     private JCClassDecl predefClassDef;
183 
184 /* ************************************************************************
185  * environment construction
186  *************************************************************************/
187 
188 
189     /** Create a fresh environment for class bodies.
190      *  This will create a fresh scope for local symbols of a class, referred
191      *  to by the environments info.scope field.
192      *  This scope will contain
193      *    - symbols for this and super
194      *    - symbols for any type parameters
195      *  In addition, it serves as an anchor for scopes of methods and initializers
196      *  which are nested in this scope via Scope.dup().
197      *  This scope should not be confused with the members scope of a class.
198      *
199      *  @param tree     The class definition.
200      *  @param env      The environment current outside of the class definition.
201      */
202     public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) {
203         Env<AttrContext> localEnv =
204             env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
205         localEnv.enclClass = tree;
206         localEnv.outer = env;
207         localEnv.info.isSelfCall = false;
208         localEnv.info.lint = null; // leave this to be filled in by Attr,
209                                    // when annotations have been processed
210         localEnv.info.isAnonymousDiamond = TreeInfo.isDiamond(env.tree);
211         return localEnv;
212     }
213 
214     /** Create a fresh environment for toplevels.
215      *  @param tree     The toplevel tree.
216      */
217     Env<AttrContext> topLevelEnv(JCCompilationUnit tree) {
218         Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
219         localEnv.toplevel = tree;
220         localEnv.enclClass = predefClassDef;
221         tree.toplevelScope = WriteableScope.create(tree.packge);
222         tree.namedImportScope = new NamedImportScope(tree.packge);
223         tree.starImportScope = new StarImportScope(tree.packge);
224         localEnv.info.scope = tree.toplevelScope;
225         localEnv.info.lint = lint;
226         return localEnv;
227     }
228 
229     public Env<AttrContext> getTopLevelEnv(JCCompilationUnit tree) {
230         Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
231         localEnv.toplevel = tree;
232         localEnv.enclClass = predefClassDef;
233         localEnv.info.scope = tree.toplevelScope;
234         localEnv.info.lint = lint;
235         return localEnv;
236     }
237 
238     /** The scope in which a member definition in environment env is to be entered
239      *  This is usually the environment's scope, except for class environments,
240      *  where the local scope is for type variables, and the this and super symbol
241      *  only, and members go into the class member scope.
242      */
243     WriteableScope enterScope(Env<AttrContext> env) {
244         return (env.tree.hasTag(JCTree.Tag.CLASSDEF))
245             ? ((JCClassDecl) env.tree).sym.members_field
246             : env.info.scope;
247     }
248 
249     /** Create a fresh environment for modules.
250      *
251      *  @param tree     The module definition.
252      *  @param env      The environment current outside of the module definition.
253      */
254     public Env<AttrContext> moduleEnv(JCModuleDecl tree, Env<AttrContext> env) {
255         Assert.checkNonNull(tree.sym);
256         Env<AttrContext> localEnv =
257             env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
258         localEnv.enclClass = predefClassDef;
259         localEnv.outer = env;
260         localEnv.info.isSelfCall = false;
261         localEnv.info.lint = null; // leave this to be filled in by Attr,
262                                    // when annotations have been processed
263         return localEnv;
264     }
265 
266 
267 /* ************************************************************************
268  * Visitor methods for phase 1: class enter
269  *************************************************************************/
270 
271     /** Visitor argument: the current environment.
272      */
273     protected Env<AttrContext> env;
274 
275     /** Visitor result: the computed type.
276      */
277     Type result;
278 
279     /** Visitor method: enter all classes in given tree, catching any
280      *  completion failure exceptions. Return the tree's type.
281      *
282      *  @param tree    The tree to be visited.
283      *  @param env     The environment visitor argument.
284      */
285     Type classEnter(JCTree tree, Env<AttrContext> env) {
286         Env<AttrContext> prevEnv = this.env;
287         try {
288             this.env = env;
289             annotate.blockAnnotations();
290             tree.accept(this);
291             return result;
292         }  catch (CompletionFailure ex) {
293             return chk.completionError(tree.pos(), ex);
294         } finally {
295             annotate.unblockAnnotations();
296             this.env = prevEnv;
297         }
298     }
299 
300     /** Visitor method: enter classes of a list of trees, returning a list of types.
301      */
302     <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) {
303         ListBuffer<Type> ts = new ListBuffer<>();
304         for (List<T> l = trees; l.nonEmpty(); l = l.tail) {
305             Type t = classEnter(l.head, env);
306             if (t != null)
307                 ts.append(t);
308         }
309         return ts.toList();
310     }
311 
312     @Override
313     public void visitTopLevel(JCCompilationUnit tree) {
314 //        Assert.checkNonNull(tree.modle, tree.sourcefile.toString());
315 
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         } else {
448             if (!tree.name.isEmpty() &&
449                 !chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {
450                 result = null;
451                 return;
452             }
453             if (owner.kind == TYP) {
454                 // We are seeing a member class.
455                 c = syms.enterClass(env.toplevel.modle, tree.name, (TypeSymbol)owner);
456                 if (c.owner != owner) {
457                     if (c.name != tree.name) {
458                         log.error(tree.pos(), Errors.SameBinaryName(c.name, tree.name));
459                         result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType);
460                         tree.sym = (ClassSymbol)result.tsym;
461                         return;
462                     }
463                     //anonymous class loaded from a classfile may be recreated from source (see below)
464                     //if this class is a member of such an anonymous class, fix the owner:
465                     Assert.check(owner.owner.kind != TYP, owner::toString);
466                     Assert.check(c.owner.kind == TYP, () -> c.owner.toString());
467                     ClassSymbol cowner = (ClassSymbol) c.owner;
468                     if (cowner.members_field != null) {
469                         cowner.members_field.remove(c);
470                     }
471                     c.owner = owner;
472                 }
473                 if ((owner.flags_field & INTERFACE) != 0) {
474                     tree.mods.flags |= PUBLIC | STATIC;
475                 }
476             } else {
477                 // We are seeing a local class.
478                 c = syms.defineClass(tree.name, owner);
479                 c.flatname = chk.localClassName(c);
480                 if (!c.name.isEmpty())
481                     chk.checkTransparentClass(tree.pos(), c, env.info.scope);
482             }
483         }
484         tree.sym = c;
485 
486         // Enter class into `compiled' table and enclosing scope.
487         if (chk.getCompiled(c) != null) {
488             duplicateClass(tree.pos(), c);
489             result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType);
490             tree.sym = (ClassSymbol)result.tsym;
491             return;
492         }
493         chk.putCompiled(c);
494         enclScope.enter(c);
495 
496         // Set up an environment for class block and store in `typeEnvs'
497         // table, to be retrieved later in memberEnter and attribution.
498         Env<AttrContext> localEnv = classEnv(tree, env);
499         typeEnvs.put(c, localEnv);
500 
501         // Fill out class fields.
502         c.completer = Completer.NULL_COMPLETER; // do not allow the initial completer linger on.
503         c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree) | FROM_SOURCE;
504         c.classfile = c.sourcefile = env.toplevel.sourcefile;
505         c.members_field = WriteableScope.create(c);
506         c.isPermittedExplicit = tree.permitting.nonEmpty();
507         c.clearAnnotationMetadata();
508 
509         ClassType ct = (ClassType)c.type;
510         if (allowPrimitiveClasses) {
511             ct.flavor = ct.flavor.metamorphose((c.flags_field & PRIMITIVE_CLASS) != 0);
512         }
513 
514         if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
515             // We are seeing a local or inner class.
516             // Set outer_field of this class to closest enclosing class
517             // which contains this class in a non-static context
518             // (its "enclosing instance class"), provided such a class exists.
519             Symbol owner1 = owner;
520             while (owner1.kind.matches(KindSelector.VAL_MTH) &&
521                    (owner1.flags_field & STATIC) == 0) {
522                 owner1 = owner1.owner;
523             }
524             if (owner1.kind == TYP) {
525                 ct.setEnclosingType(owner1.type);
526             }
527         }
528 
529         // Enter type parameters.
530         ct.typarams_field = classEnter(tree.typarams, localEnv);
531         ct.allparams_field = null;
532         if (allowPrimitiveClasses && ct.isPrimitiveClass()) {
533             if (ct.projection != null) {
534                 ct.projection.typarams_field = ct.typarams_field;
535                 ct.projection.allparams_field = ct.allparams_field;
536             }
537         }
538 
539         // install further completer for this type.
540         c.completer = typeEnter;
541 
542         // Add non-local class to uncompleted, to make sure it will be
543         // completed later.
544         if (!c.isDirectlyOrIndirectlyLocal() && uncompleted != null) uncompleted.append(c);
545 //      System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG
546 
547         // Recursively enter all member classes.
548         classEnter(tree.defs, localEnv);
549 
550 //        Assert.checkNonNull(c.modle, c.sourcefile.toString());
551 
552         result = c.type;
553     }
554     //where
555         /** Does class have the same name as the file it appears in?
556          */
557         private static boolean classNameMatchesFileName(ClassSymbol c,
558                                                         Env<AttrContext> env) {
559             return env.toplevel.sourcefile.isNameCompatible(c.name.toString(),
560                                                             JavaFileObject.Kind.SOURCE);
561         }
562 
563     /** Complain about a duplicate class. */
564     protected void duplicateClass(DiagnosticPosition pos, ClassSymbol c) {
565         log.error(pos, Errors.DuplicateClass(c.fullname));
566     }
567 
568     /** Class enter visitor method for type parameters.
569      *  Enter a symbol for type parameter in local scope, after checking that it
570      *  is unique.
571      */
572     @Override
573     public void visitTypeParameter(JCTypeParameter tree) {
574         TypeVar a = (tree.type != null)
575             ? (TypeVar)tree.type
576             : new TypeVar(tree.name, env.info.scope.owner, syms.botType);
577         tree.type = a;
578         if (chk.checkUnique(tree.pos(), a.tsym, env.info.scope)) {
579             env.info.scope.enter(a.tsym);
580         }
581         result = a;
582     }
583 
584     @Override
585     public void visitModuleDef(JCModuleDecl tree) {
586         Env<AttrContext> moduleEnv = moduleEnv(tree, env);
587         typeEnvs.put(tree.sym, moduleEnv);
588         if (modules.isInModuleGraph(tree.sym)) {
589             todo.append(moduleEnv);
590         }
591     }
592 
593     /** Default class enter visitor method: do nothing.
594      */
595     @Override
596     public void visitTree(JCTree tree) {
597         result = null;
598     }
599 
600     /** Main method: enter all classes in a list of toplevel trees.
601      *  @param trees      The list of trees to be processed.
602      */
603     public void main(List<JCCompilationUnit> trees) {
604         complete(trees, null);
605     }
606 
607     /** Main method: enter classes from the list of toplevel trees, possibly
608      *  skipping TypeEnter for all but 'c' by placing them on the uncompleted
609      *  list.
610      *  @param trees      The list of trees to be processed.
611      *  @param c          The class symbol to be processed or null to process all.
612      */
613     public void complete(List<JCCompilationUnit> trees, ClassSymbol c) {
614         annotate.blockAnnotations();
615         ListBuffer<ClassSymbol> prevUncompleted = uncompleted;
616         if (typeEnter.completionEnabled) uncompleted = new ListBuffer<>();
617 
618         try {
619             // enter all classes, and construct uncompleted list
620             classEnter(trees, null);
621 
622             // complete all uncompleted classes in memberEnter
623             if (typeEnter.completionEnabled) {
624                 while (uncompleted.nonEmpty()) {
625                     ClassSymbol clazz = uncompleted.next();
626                     if (c == null || c == clazz || prevUncompleted == null)
627                         clazz.complete();
628                     else
629                         // defer
630                         prevUncompleted.append(clazz);
631                 }
632 
633                 if (!modules.modulesInitialized()) {
634                     for (JCCompilationUnit cut : trees) {
635                         if (cut.getModuleDecl() != null) {
636                             unfinishedModules.append(cut);
637                         } else {
638                             typeEnter.ensureImportsChecked(List.of(cut));
639                         }
640                     }
641                 } else {
642                     typeEnter.ensureImportsChecked(unfinishedModules.toList());
643                     unfinishedModules.clear();
644                     typeEnter.ensureImportsChecked(trees);
645                 }
646             }
647         } finally {
648             uncompleted = prevUncompleted;
649             annotate.unblockAnnotations();
650         }
651     }
652 
653     public void newRound() {
654         typeEnvs.clear();
655     }
656 
657     public void unenter(JCCompilationUnit topLevel, JCTree tree) {
658         new UnenterScanner(topLevel.modle).scan(tree);
659     }
660         class UnenterScanner extends TreeScanner {
661             private final ModuleSymbol msym;
662 
663             public UnenterScanner(ModuleSymbol msym) {
664                 this.msym = msym;
665             }
666 
667             @Override
668             public void visitClassDef(JCClassDecl tree) {
669                 ClassSymbol csym = tree.sym;
670                 //if something went wrong during method applicability check
671                 //it is possible that nested expressions inside argument expression
672                 //are left unchecked - in such cases there's nothing to clean up.
673                 if (csym == null) return;
674                 typeEnvs.remove(csym);
675                 chk.removeCompiled(csym);
676                 chk.clearLocalClassNameIndexes(csym);
677                 syms.removeClass(msym, csym.flatname);
678                 super.visitClassDef(tree);
679             }
680         }
681 }