1 /*
  2  * Copyright (c) 1999, 2023, 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     @SuppressWarnings("this-escape")
120     protected Enter(Context context) {
121         context.put(enterKey, this);
122 
123         log = Log.instance(context);
124         make = TreeMaker.instance(context);
125         syms = Symtab.instance(context);
126         chk = Check.instance(context);
127         typeEnter = TypeEnter.instance(context);
128         types = Types.instance(context);
129         annotate = Annotate.instance(context);
130         lint = Lint.instance(context);
131         names = Names.instance(context);
132         modules = Modules.instance(context);
133         diags = JCDiagnostic.Factory.instance(context);
134 
135         predefClassDef = make.ClassDef(
136             make.Modifiers(PUBLIC),
137             syms.predefClass.name,
138             List.nil(),
139             null,
140             List.nil(),
141             List.nil());
142         predefClassDef.sym = syms.predefClass;
143         todo = Todo.instance(context);
144         fileManager = context.get(JavaFileManager.class);
145 
146         Options options = Options.instance(context);
147         pkginfoOpt = PkgInfo.get(options);
148         typeEnvs = TypeEnvs.instance(context);
149         Source source = Source.instance(context);
150         allowPrimitiveClasses = Source.Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
151     }
152 
153     /** Accessor for typeEnvs
154      */
155     public Env<AttrContext> getEnv(TypeSymbol sym) {
156         return typeEnvs.get(sym);
157     }
158 
159     public Iterable<Env<AttrContext>> getEnvs() {
160         return typeEnvs.values();
161     }
162 
163     public Env<AttrContext> getClassEnv(TypeSymbol sym) {
164         Env<AttrContext> localEnv = getEnv(sym);
165         if (localEnv == null) return null;
166         Env<AttrContext> lintEnv = localEnv;
167         while (lintEnv.info.lint == null)
168             lintEnv = lintEnv.next;
169         localEnv.info.lint = lintEnv.info.lint.augment(sym);
170         return localEnv;
171     }
172 
173     /** The queue of all classes that might still need to be completed;
174      *  saved and initialized by main().
175      */
176     ListBuffer<ClassSymbol> uncompleted;
177 
178     /** The queue of modules whose imports still need to be checked. */
179     ListBuffer<JCCompilationUnit> unfinishedModules = new ListBuffer<>();
180 
181     /** A dummy class to serve as enclClass for toplevel environments.
182      */
183     private JCClassDecl predefClassDef;
184 
185 /* ************************************************************************
186  * environment construction
187  *************************************************************************/
188 
189 
190     /** Create a fresh environment for class bodies.
191      *  This will create a fresh scope for local symbols of a class, referred
192      *  to by the environments info.scope field.
193      *  This scope will contain
194      *    - symbols for this and super
195      *    - symbols for any type parameters
196      *  In addition, it serves as an anchor for scopes of methods and initializers
197      *  which are nested in this scope via Scope.dup().
198      *  This scope should not be confused with the members scope of a class.
199      *
200      *  @param tree     The class definition.
201      *  @param env      The environment current outside of the class definition.
202      */
203     public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) {
204         Env<AttrContext> localEnv =
205             env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
206         localEnv.enclClass = tree;
207         localEnv.outer = env;
208         localEnv.info.isSelfCall = false;
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         return localEnv;
213     }
214 
215     /** Create a fresh environment for toplevels.
216      *  @param tree     The toplevel tree.
217      */
218     Env<AttrContext> topLevelEnv(JCCompilationUnit tree) {
219         Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
220         localEnv.toplevel = tree;
221         localEnv.enclClass = predefClassDef;
222         tree.toplevelScope = WriteableScope.create(tree.packge);
223         tree.namedImportScope = new NamedImportScope(tree.packge);
224         tree.starImportScope = new StarImportScope(tree.packge);
225         localEnv.info.scope = tree.toplevelScope;
226         localEnv.info.lint = lint;
227         return localEnv;
228     }
229 
230     public Env<AttrContext> getTopLevelEnv(JCCompilationUnit tree) {
231         Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
232         localEnv.toplevel = tree;
233         localEnv.enclClass = predefClassDef;
234         localEnv.info.scope = tree.toplevelScope;
235         localEnv.info.lint = lint;
236         return localEnv;
237     }
238 
239     /** The scope in which a member definition in environment env is to be entered
240      *  This is usually the environment's scope, except for class environments,
241      *  where the local scope is for type variables, and the this and super symbol
242      *  only, and members go into the class member scope.
243      */
244     WriteableScope enterScope(Env<AttrContext> env) {
245         return (env.tree.hasTag(JCTree.Tag.CLASSDEF))
246             ? ((JCClassDecl) env.tree).sym.members_field
247             : env.info.scope;
248     }
249 
250     /** Create a fresh environment for modules.
251      *
252      *  @param tree     The module definition.
253      *  @param env      The environment current outside of the module definition.
254      */
255     public Env<AttrContext> moduleEnv(JCModuleDecl tree, Env<AttrContext> env) {
256         Assert.checkNonNull(tree.sym);
257         Env<AttrContext> localEnv =
258             env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
259         localEnv.enclClass = predefClassDef;
260         localEnv.outer = env;
261         localEnv.info.isSelfCall = false;
262         localEnv.info.lint = null; // leave this to be filled in by Attr,
263                                    // when annotations have been processed
264         return localEnv;
265     }
266 
267 
268 /* ************************************************************************
269  * Visitor methods for phase 1: class enter
270  *************************************************************************/
271 
272     /** Visitor argument: the current environment.
273      */
274     protected Env<AttrContext> env;
275 
276     /** Visitor result: the computed type.
277      */
278     Type result;
279 
280     /** Visitor method: enter all classes in given tree, catching any
281      *  completion failure exceptions. Return the tree's type.
282      *
283      *  @param tree    The tree to be visited.
284      *  @param env     The environment visitor argument.
285      */
286     Type classEnter(JCTree tree, Env<AttrContext> env) {
287         Env<AttrContext> prevEnv = this.env;
288         try {
289             this.env = env;
290             annotate.blockAnnotations();
291             tree.accept(this);
292             return result;
293         }  catch (CompletionFailure ex) {
294             return chk.completionError(tree.pos(), ex);
295         } finally {
296             annotate.unblockAnnotations();
297             this.env = prevEnv;
298         }
299     }
300 
301     /** Visitor method: enter classes of a list of trees, returning a list of types.
302      */
303     <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) {
304         ListBuffer<Type> ts = new ListBuffer<>();
305         for (List<T> l = trees; l.nonEmpty(); l = l.tail) {
306             Type t = classEnter(l.head, env);
307             if (t != null)
308                 ts.append(t);
309         }
310         return ts.toList();
311     }
312 
313     @Override
314     public void visitTopLevel(JCCompilationUnit tree) {
315         JavaFileObject prev = log.useSource(tree.sourcefile);
316         boolean addEnv = false;
317         boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info",
318                                                              JavaFileObject.Kind.SOURCE);
319         if (TreeInfo.isModuleInfo(tree)) {
320             JCPackageDecl pd = tree.getPackage();
321             if (pd != null) {
322                 log.error(pd.pos(), Errors.NoPkgInModuleInfoJava);
323             }
324             tree.packge = syms.rootPackage;
325             Env<AttrContext> topEnv = topLevelEnv(tree);
326             classEnter(tree.defs, topEnv);
327             tree.modle.usesProvidesCompleter = modules.getUsesProvidesCompleter();
328         } else {
329             JCPackageDecl pd = tree.getPackage();
330             if (pd != null) {
331                 tree.packge = pd.packge = syms.enterPackage(tree.modle, TreeInfo.fullName(pd.pid));
332                 setPackageSymbols.scan(pd);
333                 if (   pd.annotations.nonEmpty()
334                     || pkginfoOpt == PkgInfo.ALWAYS
335                     || tree.docComments != null) {
336                     if (isPkgInfo) {
337                         addEnv = true;
338                     } else if (pd.annotations.nonEmpty()) {
339                         log.error(pd.annotations.head.pos(),
340                                   Errors.PkgAnnotationsSbInPackageInfoJava);
341                     }
342                 }
343             } else {
344                 tree.packge = tree.modle.unnamedPackage;
345             }
346 
347             Map<Name, PackageSymbol> visiblePackages = tree.modle.visiblePackages;
348             Optional<ModuleSymbol> dependencyWithPackage =
349                 syms.listPackageModules(tree.packge.fullname)
350                     .stream()
351                     .filter(m -> m != tree.modle)
352                     .filter(cand -> visiblePackages.get(tree.packge.fullname) == syms.getPackage(cand, tree.packge.fullname))
353                     .findAny();
354 
355             if (dependencyWithPackage.isPresent()) {
356                 log.error(pd, Errors.PackageInOtherModule(dependencyWithPackage.get()));
357             }
358 
359             tree.packge.complete(); // Find all classes in package.
360 
361             Env<AttrContext> topEnv = topLevelEnv(tree);
362             Env<AttrContext> packageEnv = null;
363 
364             // Save environment of package-info.java file.
365             if (isPkgInfo) {
366                 packageEnv = topEnv.dup(pd != null ? pd : tree);
367 
368                 Env<AttrContext> env0 = typeEnvs.get(tree.packge);
369                 if (env0 != null) {
370                     JCCompilationUnit tree0 = env0.toplevel;
371                     if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
372                         log.warning(pd != null ? pd.pid.pos() : null,
373                                     Warnings.PkgInfoAlreadySeen(tree.packge));
374                     }
375                 }
376                 typeEnvs.put(tree.packge, packageEnv);
377 
378                 for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner)
379                     q.flags_field |= EXISTS;
380 
381                 Name name = names.package_info;
382                 ClassSymbol c = syms.enterClass(tree.modle, name, tree.packge);
383                 c.flatname = names.fromString(tree.packge + "." + name);
384                 c.classfile = c.sourcefile = tree.sourcefile;
385                 c.completer = Completer.NULL_COMPLETER;
386                 c.members_field = WriteableScope.create(c);
387                 tree.packge.package_info = c;
388                 tree.packge.sourcefile = tree.sourcefile;
389             }
390             classEnter(tree.defs, topEnv);
391             if (addEnv) {
392                 todo.append(packageEnv);
393             }
394         }
395         log.useSource(prev);
396         result = null;
397     }
398         //where:
399         //set package Symbols to the package expression:
400         private final TreeScanner setPackageSymbols = new TreeScanner() {
401             Symbol currentPackage;
402 
403             @Override
404             public void visitIdent(JCIdent tree) {
405                 tree.sym = currentPackage;
406                 tree.type = currentPackage.type;
407             }
408 
409             @Override
410             public void visitSelect(JCFieldAccess tree) {
411                 tree.sym = currentPackage;
412                 tree.type = currentPackage.type;
413                 currentPackage = currentPackage.owner;
414                 super.visitSelect(tree);
415             }
416 
417             @Override
418             public void visitPackageDef(JCPackageDecl tree) {
419                 currentPackage = tree.packge;
420                 scan(tree.pid);
421             }
422         };
423 
424     @Override
425     public void visitClassDef(JCClassDecl tree) {
426         Symbol owner = env.info.scope.owner;
427         WriteableScope enclScope = enterScope(env);
428         ClassSymbol c;
429         if (owner.kind == PCK) {
430             // We are seeing a toplevel class.
431             PackageSymbol packge = (PackageSymbol)owner;
432             for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner)
433                 q.flags_field |= EXISTS;
434             c = syms.enterClass(env.toplevel.modle, tree.name, packge);
435             packge.members().enterIfAbsent(c);
436             if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {
437                 KindName topElement = KindName.CLASS;
438                 if ((tree.mods.flags & ENUM) != 0) {
439                     topElement = KindName.ENUM;
440                 } else if ((tree.mods.flags & INTERFACE) != 0) {
441                     topElement = KindName.INTERFACE;
442                 }
443                 log.error(tree.pos(),
444                           Errors.ClassPublicShouldBeInFile(topElement, tree.name));
445             }
446             if ((tree.mods.flags & UNNAMED_CLASS) != 0) {
447                 syms.removeClass(env.toplevel.modle, tree.name);
448             }
449         } else {
450             if (!tree.name.isEmpty() &&
451                 !chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {
452                 result = null;
453                 return;
454             }
455             if (owner.kind == TYP) {
456                 // We are seeing a member class.
457                 c = syms.enterClass(env.toplevel.modle, tree.name, (TypeSymbol)owner);
458                 if (c.owner != owner) {
459                     if (c.name != tree.name) {
460                         log.error(tree.pos(), Errors.SameBinaryName(c.name, tree.name));
461                         result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType);
462                         tree.sym = (ClassSymbol)result.tsym;
463                         return;
464                     }
465                     //anonymous class loaded from a classfile may be recreated from source (see below)
466                     //if this class is a member of such an anonymous class, fix the owner:
467                     Assert.check(owner.owner.kind != TYP, owner::toString);
468                     Assert.check(c.owner.kind == TYP, () -> c.owner.toString());
469                     ClassSymbol cowner = (ClassSymbol) c.owner;
470                     if (cowner.members_field != null) {
471                         cowner.members_field.remove(c);
472                     }
473                     c.owner = owner;
474                 }
475                 if ((owner.flags_field & INTERFACE) != 0) {
476                     tree.mods.flags |= PUBLIC | STATIC;
477                 }
478             } else {
479                 // We are seeing a local class.
480                 c = syms.defineClass(tree.name, owner);
481                 c.flatname = chk.localClassName(c);
482                 if (!c.name.isEmpty())
483                     chk.checkTransparentClass(tree.pos(), c, env.info.scope);
484             }
485         }
486         tree.sym = c;
487 
488         // Enter class into `compiled' table and enclosing scope.
489         if (chk.getCompiled(c) != null) {
490             duplicateClass(tree.pos(), c);
491             result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType);
492             tree.sym = (ClassSymbol)result.tsym;
493             return;
494         }
495         chk.putCompiled(c);
496         enclScope.enter(c);
497 
498         // Set up an environment for class block and store in `typeEnvs'
499         // table, to be retrieved later in memberEnter and attribution.
500         Env<AttrContext> localEnv = classEnv(tree, env);
501         typeEnvs.put(c, localEnv);
502 
503         // Fill out class fields.
504         c.completer = Completer.NULL_COMPLETER; // do not allow the initial completer linger on.
505         c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree) | FROM_SOURCE;
506         c.classfile = c.sourcefile = env.toplevel.sourcefile;
507         c.members_field = WriteableScope.create(c);
508         c.isPermittedExplicit = tree.permitting.nonEmpty();
509         c.clearAnnotationMetadata();
510 
511         ClassType ct = (ClassType)c.type;
512         if (allowPrimitiveClasses) {
513             ct.flavor = ct.flavor.metamorphose((c.flags_field & PRIMITIVE_CLASS) != 0);
514         }
515 
516         if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
517             // We are seeing a local or inner class.
518             // Set outer_field of this class to closest enclosing class
519             // which contains this class in a non-static context
520             // (its "enclosing instance class"), provided such a class exists.
521             Symbol owner1 = owner;
522             while (owner1.kind.matches(KindSelector.VAL_MTH) &&
523                    (owner1.flags_field & STATIC) == 0) {
524                 owner1 = owner1.owner;
525             }
526             if (owner1.kind == TYP) {
527                 ct.setEnclosingType(owner1.type);
528             }
529         }
530 
531         // Enter type parameters.
532         ct.typarams_field = classEnter(tree.typarams, localEnv);
533         ct.allparams_field = null;
534         if (allowPrimitiveClasses && ct.isPrimitiveClass()) {
535             if (ct.projection != null) {
536                 ct.projection.typarams_field = ct.typarams_field;
537                 ct.projection.allparams_field = ct.allparams_field;
538             }
539         }
540 
541         // install further completer for this type.
542         c.completer = typeEnter;
543 
544         // Add non-local class to uncompleted, to make sure it will be
545         // completed later.
546         if (!c.isDirectlyOrIndirectlyLocal() && uncompleted != null) uncompleted.append(c);
547 //      System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG
548 
549         // Recursively enter all member classes.
550         classEnter(tree.defs, localEnv);
551 
552 //        Assert.checkNonNull(c.modle, c.sourcefile.toString());
553 
554         result = c.type;
555     }
556     //where
557         /** Does class have the same name as the file it appears in?
558          */
559         private static boolean classNameMatchesFileName(ClassSymbol c,
560                                                         Env<AttrContext> env) {
561             return env.toplevel.sourcefile.isNameCompatible(c.name.toString(),
562                                                             JavaFileObject.Kind.SOURCE);
563         }
564 
565     /** Complain about a duplicate class. */
566     protected void duplicateClass(DiagnosticPosition pos, ClassSymbol c) {
567         log.error(pos, Errors.DuplicateClass(c.fullname));
568     }
569 
570     /** Class enter visitor method for type parameters.
571      *  Enter a symbol for type parameter in local scope, after checking that it
572      *  is unique.
573      */
574     @Override
575     public void visitTypeParameter(JCTypeParameter tree) {
576         TypeVar a = (tree.type != null)
577             ? (TypeVar)tree.type
578             : new TypeVar(tree.name, env.info.scope.owner, syms.botType);
579         tree.type = a;
580         if (chk.checkUnique(tree.pos(), a.tsym, env.info.scope)) {
581             env.info.scope.enter(a.tsym);
582         }
583         result = a;
584     }
585 
586     @Override
587     public void visitModuleDef(JCModuleDecl tree) {
588         Env<AttrContext> moduleEnv = moduleEnv(tree, env);
589         typeEnvs.put(tree.sym, moduleEnv);
590         if (modules.isInModuleGraph(tree.sym)) {
591             todo.append(moduleEnv);
592         }
593     }
594 
595     /** Default class enter visitor method: do nothing.
596      */
597     @Override
598     public void visitTree(JCTree tree) {
599         result = null;
600     }
601 
602     /** Main method: enter all classes in a list of toplevel trees.
603      *  @param trees      The list of trees to be processed.
604      */
605     public void main(List<JCCompilationUnit> trees) {
606         complete(trees, null);
607     }
608 
609     /** Main method: enter classes from the list of toplevel trees, possibly
610      *  skipping TypeEnter for all but 'c' by placing them on the uncompleted
611      *  list.
612      *  @param trees      The list of trees to be processed.
613      *  @param c          The class symbol to be processed or null to process all.
614      */
615     public void complete(List<JCCompilationUnit> trees, ClassSymbol c) {
616         annotate.blockAnnotations();
617         ListBuffer<ClassSymbol> prevUncompleted = uncompleted;
618         if (typeEnter.completionEnabled) uncompleted = new ListBuffer<>();
619 
620         try {
621             // enter all classes, and construct uncompleted list
622             classEnter(trees, null);
623 
624             // complete all uncompleted classes in memberEnter
625             if (typeEnter.completionEnabled) {
626                 while (uncompleted.nonEmpty()) {
627                     ClassSymbol clazz = uncompleted.next();
628                     if (c == null || c == clazz || prevUncompleted == null)
629                         clazz.complete();
630                     else
631                         // defer
632                         prevUncompleted.append(clazz);
633                 }
634 
635                 if (!modules.modulesInitialized()) {
636                     for (JCCompilationUnit cut : trees) {
637                         if (cut.getModuleDecl() != null) {
638                             unfinishedModules.append(cut);
639                         } else {
640                             typeEnter.ensureImportsChecked(List.of(cut));
641                         }
642                     }
643                 } else {
644                     typeEnter.ensureImportsChecked(unfinishedModules.toList());
645                     unfinishedModules.clear();
646                     typeEnter.ensureImportsChecked(trees);
647                 }
648             }
649         } finally {
650             uncompleted = prevUncompleted;
651             annotate.unblockAnnotations();
652         }
653     }
654 
655     public void newRound() {
656         typeEnvs.clear();
657     }
658 
659     public void unenter(JCCompilationUnit topLevel, JCTree tree) {
660         new UnenterScanner(topLevel.modle).scan(tree);
661     }
662         class UnenterScanner extends TreeScanner {
663             private final ModuleSymbol msym;
664 
665             public UnenterScanner(ModuleSymbol msym) {
666                 this.msym = msym;
667             }
668 
669             @Override
670             public void visitClassDef(JCClassDecl tree) {
671                 ClassSymbol csym = tree.sym;
672                 //if something went wrong during method applicability check
673                 //it is possible that nested expressions inside argument expression
674                 //are left unchecked - in such cases there's nothing to clean up.
675                 if (csym == null) return;
676                 typeEnvs.remove(csym);
677                 chk.removeCompiled(csym);
678                 chk.clearLocalClassNameIndexes(csym);
679                 syms.removeClass(msym, csym.flatname);
680                 super.visitClassDef(tree);
681             }
682         }
683 }