Enter.java revision 3792:d516975e8110
110015Speter/*
212496Speter * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
310015Speter * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
410015Speter *
510015Speter * This code is free software; you can redistribute it and/or modify it
610015Speter * under the terms of the GNU General Public License version 2 only, as
710015Speter * published by the Free Software Foundation.  Oracle designates this
810015Speter * particular file as subject to the "Classpath" exception as provided
910015Speter * by Oracle in the LICENSE file that accompanied this code.
1010015Speter *
1110015Speter * This code is distributed in the hope that it will be useful, but WITHOUT
1210015Speter * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1310015Speter * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1410015Speter * version 2 for more details (a copy is included in the LICENSE file that
1510015Speter * accompanied this code).
1610015Speter *
1710015Speter * You should have received a copy of the GNU General Public License version
1810015Speter * 2 along with this work; if not, write to the Free Software Foundation,
1910015Speter * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2010015Speter *
2110015Speter * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2210015Speter * or visit www.oracle.com if you need additional information or have any
2310015Speter * questions.
2410015Speter */
2510015Speter
2610015Speterpackage com.sun.tools.javac.comp;
2710015Speter
2810015Speterimport java.util.Map;
2910015Speterimport java.util.Optional;
3010015Speter
3110015Speterimport javax.tools.JavaFileObject;
3210015Speterimport javax.tools.JavaFileManager;
3333395Speter
3410015Speterimport com.sun.tools.javac.code.*;
3510015Speterimport com.sun.tools.javac.code.Kinds.KindSelector;
3610015Speterimport com.sun.tools.javac.code.Scope.*;
3716322Sgpalmerimport com.sun.tools.javac.code.Symbol.*;
3816322Sgpalmerimport com.sun.tools.javac.code.Type.*;
3916322Sgpalmerimport com.sun.tools.javac.main.Option.PkgInfo;
4010015Speterimport com.sun.tools.javac.resources.CompilerProperties.Errors;
4110015Speterimport com.sun.tools.javac.tree.*;
4231778Seivindimport com.sun.tools.javac.tree.JCTree.*;
4332929Seivindimport com.sun.tools.javac.util.*;
4432726Seivindimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
4531778Seivindimport com.sun.tools.javac.util.List;
4610015Speter
4710015Speterimport static com.sun.tools.javac.code.Flags.*;
4824207Sbdeimport static com.sun.tools.javac.code.Kinds.Kind.*;
4924207Sbde
5024207Sbde/** This class enters symbols for all encountered definitions into
5110015Speter *  the symbol table. The pass consists of high-level two phases,
5210015Speter *  organized as follows:
5310015Speter *
5424131Sbde *  <p>In the first phase, all class symbols are entered into their
5510015Speter *  enclosing scope, descending recursively down the tree for classes
5610015Speter *  which are members of other classes. The class symbols are given a
5710015Speter *  TypeEnter object as completer.
5815683Speter *
5912675Sjulian *  <p>In the second phase classes are completed using
6012675Sjulian *  TypeEnter.complete(). Completion might occur on demand, but
6112675Sjulian *  any classes that are not completed that way will be eventually
6210015Speter *  completed by processing the `uncompleted' queue. Completion
6310015Speter *  entails determination of a class's parameters, supertype and
6410015Speter *  interfaces, as well as entering all symbols defined in the
6512659Sbde *  class into its scope, with the exception of class symbols which
6612662Sdg *  have been entered in phase 1.
6712659Sbde *
6810015Speter *  <p>Whereas the first phase is organized as a sweep through all
6910015Speter *  compiled syntax trees, the second phase is on-demand. Members of a
7010015Speter *  class are entered when the contents of a class are first
7110015Speter *  accessed. This is accomplished by installing completer objects in
7210015Speter *  class symbols for compiled classes which invoke the type-enter
7310015Speter *  phase for the corresponding class tree.
7413353Speter *
7510015Speter *  <p>Classes migrate from one phase to the next via queues:
7633395Speter *
7733395Speter *  <pre>{@literal
7833395Speter *  class enter -> (Enter.uncompleted)         --> type enter
7933395Speter *              -> (Todo)                      --> attribute
8033395Speter *                                              (only for toplevel classes)
8133395Speter *  }</pre>
8210015Speter *
8310015Speter *  <p><b>This is NOT part of any supported API.
8410015Speter *  If you write code that depends on this, you do so at your own risk.
8510015Speter *  This code and its internal interfaces are subject to change or
8612496Speter *  deletion without notice.</b>
8710015Speter */
8833395Speterpublic class Enter extends JCTree.Visitor {
8933395Speter    protected static final Context.Key<Enter> enterKey = new Context.Key<>();
9010015Speter
9110015Speter    Annotate annotate;
9210015Speter    Log log;
9310015Speter    Symtab syms;
9417547Speter    Check chk;
9517547Speter    TreeMaker make;
9617547Speter    TypeEnter typeEnter;
9710047Speter    Types types;
9812496Speter    Lint lint;
9915639Speter    Names names;
10015639Speter    JavaFileManager fileManager;
10110015Speter    PkgInfo pkginfoOpt;
10210015Speter    TypeEnvs typeEnvs;
10310015Speter    Modules modules;
10410015Speter    JCDiagnostic.Factory diags;
10510015Speter
10610015Speter    private final Todo todo;
10710015Speter
10810015Speter    public static Enter instance(Context context) {
10925047Sbde        Enter instance = context.get(enterKey);
11010015Speter        if (instance == null)
11110015Speter            instance = new Enter(context);
11210015Speter        return instance;
11310015Speter    }
11410015Speter
11512724Sphk    protected Enter(Context context) {
11610015Speter        context.put(enterKey, this);
11712724Sphk
11812724Sphk        log = Log.instance(context);
11910708Speter        make = TreeMaker.instance(context);
12010708Speter        syms = Symtab.instance(context);
12112675Sjulian        chk = Check.instance(context);
12212675Sjulian        typeEnter = TypeEnter.instance(context);
12312675Sjulian        types = Types.instance(context);
12433395Speter        annotate = Annotate.instance(context);
12512675Sjulian        lint = Lint.instance(context);
12633395Speter        names = Names.instance(context);
12733395Speter        modules = Modules.instance(context);
12833395Speter        diags = JCDiagnostic.Factory.instance(context);
12933395Speter
13033395Speter        predefClassDef = make.ClassDef(
13133395Speter            make.Modifiers(PUBLIC),
13233395Speter            syms.predefClass.name,
13333395Speter            List.<JCTypeParameter>nil(),
13433395Speter            null,
13533395Speter            List.<JCExpression>nil(),
13633395Speter            List.<JCTree>nil());
13733395Speter        predefClassDef.sym = syms.predefClass;
13833395Speter        todo = Todo.instance(context);
13933395Speter        fileManager = context.get(JavaFileManager.class);
14033395Speter
14133395Speter        Options options = Options.instance(context);
14233395Speter        pkginfoOpt = PkgInfo.get(options);
14333395Speter        typeEnvs = TypeEnvs.instance(context);
14433395Speter    }
14533395Speter
14633395Speter    /** Accessor for typeEnvs
14733395Speter     */
14833395Speter    public Env<AttrContext> getEnv(TypeSymbol sym) {
14912675Sjulian        return typeEnvs.get(sym);
15012675Sjulian    }
15112675Sjulian
15212675Sjulian    public Iterable<Env<AttrContext>> getEnvs() {
15312675Sjulian        return typeEnvs.values();
15412675Sjulian    }
15512731Sbde
15612675Sjulian    public Env<AttrContext> getClassEnv(TypeSymbol sym) {
15712675Sjulian        Env<AttrContext> localEnv = getEnv(sym);
15812678Sphk        Env<AttrContext> lintEnv = localEnv;
15912675Sjulian        while (lintEnv.info.lint == null)
16012743Sbde            lintEnv = lintEnv.next;
16129368Speter        localEnv.info.lint = lintEnv.info.lint.augment(sym);
16212675Sjulian        return localEnv;
16312675Sjulian    }
16412174Speter
16513353Speter    /** The queue of all classes that might still need to be completed;
16613353Speter     *  saved and initialized by main().
16713353Speter     */
16810708Speter    ListBuffer<ClassSymbol> uncompleted;
16913353Speter
17010708Speter    /** The queue of modules whose imports still need to be checked. */
17113353Speter    ListBuffer<JCCompilationUnit> unfinishedModules = new ListBuffer<>();
17210708Speter
17310708Speter    /** A dummy class to serve as enclClass for toplevel environments.
17410708Speter     */
17510708Speter    private JCClassDecl predefClassDef;
17610962Speter
17710962Speter/* ************************************************************************
17810962Speter * environment construction
17910015Speter *************************************************************************/
18010962Speter
18110962Speter
18233395Speter    /** Create a fresh environment for class bodies.
18333395Speter     *  This will create a fresh scope for local symbols of a class, referred
18410015Speter     *  to by the environments info.scope field.
18510015Speter     *  This scope will contain
18633395Speter     *    - symbols for this and super
18733395Speter     *    - symbols for any type parameters
18833395Speter     *  In addition, it serves as an anchor for scopes of methods and initializers
18933395Speter     *  which are nested in this scope via Scope.dup().
19033395Speter     *  This scope should not be confused with the members scope of a class.
19133395Speter     *
19210015Speter     *  @param tree     The class definition.
19333395Speter     *  @param env      The environment current outside of the class definition.
19410044Speter     */
19510044Speter    public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) {
19610044Speter        Env<AttrContext> localEnv =
19710044Speter            env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
19810044Speter        localEnv.enclClass = tree;
19910044Speter        localEnv.outer = env;
20010044Speter        localEnv.info.isSelfCall = false;
20110044Speter        localEnv.info.lint = null; // leave this to be filled in by Attr,
20210044Speter                                   // when annotations have been processed
20310044Speter        localEnv.info.isAnonymousDiamond = TreeInfo.isDiamond(env.tree);
20410044Speter        return localEnv;
20510044Speter    }
20612675Sjulian
20712675Sjulian    /** Create a fresh environment for toplevels.
20812675Sjulian     *  @param tree     The toplevel tree.
20912826Speter     */
21012675Sjulian    Env<AttrContext> topLevelEnv(JCCompilationUnit tree) {
21112675Sjulian        Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
21212675Sjulian        localEnv.toplevel = tree;
21313165Speter        localEnv.enclClass = predefClassDef;
21412675Sjulian        tree.toplevelScope = WriteableScope.create(tree.packge);
21510044Speter        tree.namedImportScope = new NamedImportScope(tree.packge, tree.toplevelScope);
21612724Sphk        tree.starImportScope = new StarImportScope(tree.packge);
21710044Speter        localEnv.info.scope = tree.toplevelScope;
21812174Speter        localEnv.info.lint = lint;
21910015Speter        return localEnv;
22010015Speter    }
22110015Speter
22210015Speter    public Env<AttrContext> getTopLevelEnv(JCCompilationUnit tree) {
22310015Speter        Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
22410015Speter        localEnv.toplevel = tree;
22510015Speter        localEnv.enclClass = predefClassDef;
22610015Speter        localEnv.info.scope = tree.toplevelScope;
22710015Speter        localEnv.info.lint = lint;
22810015Speter        return localEnv;
22910015Speter    }
23010015Speter
23110015Speter    /** The scope in which a member definition in environment env is to be entered
23210015Speter     *  This is usually the environment's scope, except for class environments,
23310015Speter     *  where the local scope is for type variables, and the this and super symbol
23410015Speter     *  only, and members go into the class member scope.
23510015Speter     */
23610015Speter    WriteableScope enterScope(Env<AttrContext> env) {
23710015Speter        return (env.tree.hasTag(JCTree.Tag.CLASSDEF))
23810015Speter            ? ((JCClassDecl) env.tree).sym.members_field
23910015Speter            : env.info.scope;
24010015Speter    }
24110015Speter
24210015Speter    /** Create a fresh environment for modules.
24310015Speter     *
24410015Speter     *  @param tree     The module definition.
24510015Speter     *  @param env      The environment current outside of the module definition.
24610015Speter     */
24710015Speter    public Env<AttrContext> moduleEnv(JCModuleDecl tree, Env<AttrContext> env) {
24810015Speter        Assert.checkNonNull(tree.sym);
24910015Speter        Env<AttrContext> localEnv =
25010015Speter            env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
25110015Speter        localEnv.enclClass = predefClassDef;
25210015Speter        localEnv.outer = env;
25310015Speter        localEnv.info.isSelfCall = false;
25410015Speter        localEnv.info.lint = null; // leave this to be filled in by Attr,
25510015Speter                                   // when annotations have been processed
25610015Speter        return localEnv;
25710015Speter    }
25810015Speter
25910015Speter
26010015Speter/* ************************************************************************
26110015Speter * Visitor methods for phase 1: class enter
26210047Speter *************************************************************************/
26310047Speter
26410047Speter    /** Visitor argument: the current environment.
26510047Speter     */
26610047Speter    protected Env<AttrContext> env;
26710047Speter
26810047Speter    /** Visitor result: the computed type.
26910047Speter     */
27010047Speter    Type result;
27110047Speter
27210015Speter    /** Visitor method: enter all classes in given tree, catching any
27315683Speter     *  completion failure exceptions. Return the tree's type.
27417547Speter     *
27515639Speter     *  @param tree    The tree to be visited.
27616403Speter     *  @param env     The environment visitor argument.
27717547Speter     */
27815639Speter    Type classEnter(JCTree tree, Env<AttrContext> env) {
27910015Speter        Env<AttrContext> prevEnv = this.env;
28010015Speter        try {
28110015Speter            this.env = env;
28210015Speter            annotate.blockAnnotations();
28310015Speter            tree.accept(this);
28410015Speter            return result;
28510015Speter        }  catch (CompletionFailure ex) {
28610015Speter            return chk.completionError(tree.pos(), ex);
28710015Speter        } finally {
28810015Speter            annotate.unblockAnnotations();
28910015Speter            this.env = prevEnv;
29010015Speter        }
29110015Speter    }
29210015Speter
29333395Speter    /** Visitor method: enter classes of a list of trees, returning a list of types.
29433395Speter     */
29533395Speter    <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) {
29610015Speter        ListBuffer<Type> ts = new ListBuffer<>();
29710015Speter        for (List<T> l = trees; l.nonEmpty(); l = l.tail) {
29833395Speter            Type t = classEnter(l.head, env);
29933395Speter            if (t != null)
30033395Speter                ts.append(t);
30133395Speter        }
30233395Speter        return ts.toList();
30333395Speter    }
30433395Speter
30533395Speter    @Override
30633395Speter    public void visitTopLevel(JCCompilationUnit tree) {
30733395Speter//        Assert.checkNonNull(tree.modle, tree.sourcefile.toString());
30833395Speter
30933395Speter        JavaFileObject prev = log.useSource(tree.sourcefile);
31033395Speter        boolean addEnv = false;
31133395Speter        boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info",
31233395Speter                                                             JavaFileObject.Kind.SOURCE);
31333395Speter        if (TreeInfo.isModuleInfo(tree)) {
31433395Speter            JCPackageDecl pd = tree.getPackage();
31533395Speter            if (pd != null) {
31633395Speter                log.error(pd.pos(), Errors.NoPkgInModuleInfoJava);
31733395Speter            }
31833395Speter            tree.packge = syms.rootPackage;
31933395Speter            Env<AttrContext> topEnv = topLevelEnv(tree);
32033395Speter            classEnter(tree.defs, topEnv);
32133395Speter            tree.modle.usesProvidesCompleter = modules.getUsesProvidesCompleter();
32233395Speter        } else {
32333395Speter            JCPackageDecl pd = tree.getPackage();
32433395Speter            if (pd != null) {
32533395Speter                tree.packge = pd.packge = syms.enterPackage(tree.modle, TreeInfo.fullName(pd.pid));
32633395Speter                if (   pd.annotations.nonEmpty()
32733395Speter                    || pkginfoOpt == PkgInfo.ALWAYS
32833395Speter                    || tree.docComments != null) {
32933395Speter                    if (isPkgInfo) {
33033395Speter                        addEnv = true;
33133395Speter                    } else if (pd.annotations.nonEmpty()) {
33233395Speter                        log.error(pd.annotations.head.pos(),
33333395Speter                                  "pkg.annotations.sb.in.package-info.java");
33433395Speter                    }
33533395Speter                }
33633395Speter            } else {
33733395Speter                tree.packge = tree.modle.unnamedPackage;
33833395Speter            }
33933395Speter
34033395Speter            Map<Name, PackageSymbol> visiblePackages = tree.modle.visiblePackages;
34133395Speter            Optional<ModuleSymbol> dependencyWithPackage =
34233395Speter                syms.listPackageModules(tree.packge.fullname)
34333395Speter                    .stream()
34433395Speter                    .filter(m -> m != tree.modle)
34533395Speter                    .filter(cand -> visiblePackages.get(tree.packge.fullname) == syms.getPackage(cand, tree.packge.fullname))
34633395Speter                    .findAny();
34733395Speter
34833395Speter            if (dependencyWithPackage.isPresent()) {
34933395Speter                log.error(pd, Errors.PackageInOtherModule(dependencyWithPackage.get()));
35033395Speter            }
35133395Speter
35233395Speter            tree.packge.complete(); // Find all classes in package.
35333395Speter
35433395Speter            Env<AttrContext> topEnv = topLevelEnv(tree);
35533395Speter            Env<AttrContext> packageEnv = isPkgInfo ? topEnv.dup(pd) : null;
35633395Speter
35733395Speter            // Save environment of package-info.java file.
35833395Speter            if (isPkgInfo) {
35933395Speter                Env<AttrContext> env0 = typeEnvs.get(tree.packge);
36033395Speter                if (env0 != null) {
36133395Speter                    JCCompilationUnit tree0 = env0.toplevel;
36233395Speter                    if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
36333395Speter                        log.warning(pd != null ? pd.pid.pos() : null,
36433395Speter                                    "pkg-info.already.seen",
36533395Speter                                    tree.packge);
36633395Speter                    }
36733395Speter                }
36833395Speter                typeEnvs.put(tree.packge, packageEnv);
36933395Speter
37033395Speter                for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner)
37110015Speter                    q.flags_field |= EXISTS;
37212724Sphk
37310015Speter                Name name = names.package_info;
37410015Speter                ClassSymbol c = syms.enterClass(tree.modle, name, tree.packge);
37510015Speter                c.flatname = names.fromString(tree.packge + "." + name);
37610015Speter                c.sourcefile = tree.sourcefile;
37710015Speter            c.completer = Completer.NULL_COMPLETER;
37810015Speter                c.members_field = WriteableScope.create(c);
37910015Speter                tree.packge.package_info = c;
38010015Speter            }
38110015Speter            classEnter(tree.defs, topEnv);
38210015Speter            if (addEnv) {
38317547Speter                todo.append(packageEnv);
38417547Speter            }
38517547Speter        }
38617547Speter        log.useSource(prev);
38715683Speter        result = null;
38810015Speter    }
38910015Speter
39010015Speter    @Override
39112496Speter    public void visitClassDef(JCClassDecl tree) {
39212496Speter        Symbol owner = env.info.scope.owner;
39310015Speter        WriteableScope enclScope = enterScope(env);
39410015Speter        ClassSymbol c;
39510015Speter        if (owner.kind == PCK) {
39610015Speter            // We are seeing a toplevel class.
39710015Speter            PackageSymbol packge = (PackageSymbol)owner;
39810015Speter            for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner)
39910015Speter                q.flags_field |= EXISTS;
40012174Speter            c = syms.enterClass(env.toplevel.modle, tree.name, packge);
40112174Speter            packge.members().enterIfAbsent(c);
40210015Speter            if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {
40310015Speter                log.error(tree.pos(),
40410015Speter                          "class.public.should.be.in.file", tree.name);
40510015Speter            }
40610015Speter        } else {
40710015Speter            if (!tree.name.isEmpty() &&
40810015Speter                !chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {
40910015Speter                result = null;
41010015Speter                return;
41110015Speter            }
41210015Speter            if (owner.kind == TYP) {
41310015Speter                // We are seeing a member class.
41410015Speter                c = syms.enterClass(env.toplevel.modle, tree.name, (TypeSymbol)owner);
41510015Speter                if ((owner.flags_field & INTERFACE) != 0) {
41610015Speter                    tree.mods.flags |= PUBLIC | STATIC;
41710015Speter                }
41810015Speter            } else {
41910015Speter                // We are seeing a local class.
42010015Speter                c = syms.defineClass(tree.name, owner);
42110015Speter                c.flatname = chk.localClassName(c);
42210015Speter                if (!c.name.isEmpty())
42310015Speter                    chk.checkTransparentClass(tree.pos(), c, env.info.scope);
42410015Speter            }
42510015Speter        }
42610015Speter        tree.sym = c;
42710015Speter
42810015Speter        // Enter class into `compiled' table and enclosing scope.
42910015Speter        if (chk.getCompiled(c) != null) {
43010015Speter            duplicateClass(tree.pos(), c);
43110015Speter            result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType);
43210015Speter            tree.sym = (ClassSymbol)result.tsym;
43310015Speter            return;
43410015Speter        }
43510015Speter        chk.putCompiled(c);
43610015Speter        enclScope.enter(c);
43710015Speter
43810015Speter        // Set up an environment for class block and store in `typeEnvs'
43910015Speter        // table, to be retrieved later in memberEnter and attribution.
44010015Speter        Env<AttrContext> localEnv = classEnv(tree, env);
44110015Speter        typeEnvs.put(c, localEnv);
44210015Speter
44312496Speter        // Fill out class fields.
44410015Speter        c.completer = Completer.NULL_COMPLETER; // do not allow the initial completer linger on.
44510015Speter        c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
44610015Speter        c.sourcefile = env.toplevel.sourcefile;
44710015Speter        c.members_field = WriteableScope.create(c);
44810015Speter        c.clearAnnotationMetadata();
44910015Speter
45010015Speter        ClassType ct = (ClassType)c.type;
45110015Speter        if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
45210015Speter            // We are seeing a local or inner class.
45310015Speter            // Set outer_field of this class to closest enclosing class
45410015Speter            // which contains this class in a non-static context
45510015Speter            // (its "enclosing instance class"), provided such a class exists.
45610015Speter            Symbol owner1 = owner;
45710015Speter            while (owner1.kind.matches(KindSelector.VAL_MTH) &&
45810015Speter                   (owner1.flags_field & STATIC) == 0) {
45910015Speter                owner1 = owner1.owner;
46010015Speter            }
46110015Speter            if (owner1.kind == TYP) {
46210015Speter                ct.setEnclosingType(owner1.type);
46310015Speter            }
46410015Speter        }
46510015Speter
46610015Speter        // Enter type parameters.
46710015Speter        ct.typarams_field = classEnter(tree.typarams, localEnv);
46810015Speter        ct.allparams_field = null;
46910015Speter
47010015Speter        // install further completer for this type.
47110015Speter        c.completer = typeEnter;
47233395Speter
47333395Speter        // Add non-local class to uncompleted, to make sure it will be
47433395Speter        // completed later.
47533395Speter        if (!c.isLocal() && uncompleted != null) uncompleted.append(c);
47633395Speter//      System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG
47733395Speter
47833395Speter        // Recursively enter all member classes.
47933395Speter        classEnter(tree.defs, localEnv);
48033395Speter
48133395Speter//        Assert.checkNonNull(c.modle, c.sourcefile.toString());
48233395Speter
48333395Speter        result = c.type;
48433395Speter    }
48533395Speter    //where
48633395Speter        /** Does class have the same name as the file it appears in?
48733395Speter         */
48833395Speter        private static boolean classNameMatchesFileName(ClassSymbol c,
48933395Speter                                                        Env<AttrContext> env) {
49033395Speter            return env.toplevel.sourcefile.isNameCompatible(c.name.toString(),
49133395Speter                                                            JavaFileObject.Kind.SOURCE);
49233395Speter        }
49333395Speter
49433395Speter    /** Complain about a duplicate class. */
49533395Speter    protected void duplicateClass(DiagnosticPosition pos, ClassSymbol c) {
49610015Speter        log.error(pos, "duplicate.class", c.fullname);
49733395Speter    }
49810015Speter
49933395Speter    /** Class enter visitor method for type parameters.
50010015Speter     *  Enter a symbol for type parameter in local scope, after checking that it
50110015Speter     *  is unique.
50210015Speter     */
50310015Speter    @Override
50410015Speter    public void visitTypeParameter(JCTypeParameter tree) {
50510015Speter        TypeVar a = (tree.type != null)
50610015Speter            ? (TypeVar)tree.type
50710015Speter            : new TypeVar(tree.name, env.info.scope.owner, syms.botType);
50810015Speter        tree.type = a;
50910015Speter        if (chk.checkUnique(tree.pos(), a.tsym, env.info.scope)) {
51010015Speter            env.info.scope.enter(a.tsym);
51110015Speter        }
51210015Speter        result = a;
51310015Speter    }
51410015Speter
51510015Speter    @Override
51610015Speter    public void visitModuleDef(JCModuleDecl tree) {
51710015Speter        Env<AttrContext> moduleEnv = moduleEnv(tree, env);
51810015Speter        typeEnvs.put(tree.sym, moduleEnv);
51910015Speter        if (modules.isInModuleGraph(tree.sym)) {
52010015Speter            todo.append(moduleEnv);
52110015Speter        }
52210015Speter    }
52310015Speter
52410015Speter    /** Default class enter visitor method: do nothing.
52510015Speter     */
52610015Speter    @Override
52710015Speter    public void visitTree(JCTree tree) {
52810015Speter        result = null;
52910015Speter    }
53010015Speter
53110015Speter    /** Main method: enter all classes in a list of toplevel trees.
53210015Speter     *  @param trees      The list of trees to be processed.
53310015Speter     */
53412496Speter    public void main(List<JCCompilationUnit> trees) {
53512496Speter        complete(trees, null);
53610015Speter    }
53718515Speter
53810015Speter    /** Main method: enter classes from the list of toplevel trees, possibly
53910015Speter     *  skipping TypeEnter for all but 'c' by placing them on the uncompleted
54018515Speter     *  list.
54110015Speter     *  @param trees      The list of trees to be processed.
54210015Speter     *  @param c          The class symbol to be processed or null to process all.
54310015Speter     */
54412174Speter    public void complete(List<JCCompilationUnit> trees, ClassSymbol c) {
54510015Speter        annotate.blockAnnotations();
54610015Speter        ListBuffer<ClassSymbol> prevUncompleted = uncompleted;
54710015Speter        if (typeEnter.completionEnabled) uncompleted = new ListBuffer<>();
54810015Speter
54910015Speter        try {
55010015Speter            // enter all classes, and construct uncompleted list
55118515Speter            classEnter(trees, null);
55210015Speter
55310015Speter            // complete all uncompleted classes in memberEnter
55418515Speter            if (typeEnter.completionEnabled) {
55510015Speter                while (uncompleted.nonEmpty()) {
55610015Speter                    ClassSymbol clazz = uncompleted.next();
55710015Speter                    if (c == null || c == clazz || prevUncompleted == null)
55812174Speter                        clazz.complete();
55910015Speter                    else
56010015Speter                        // defer
56110015Speter                        prevUncompleted.append(clazz);
56210015Speter                }
56310015Speter
56410015Speter                if (!modules.modulesInitialized()) {
56510015Speter                    for (JCCompilationUnit cut : trees) {
56610015Speter                        if (cut.getModuleDecl() != null) {
56710015Speter                            unfinishedModules.append(cut);
56810015Speter                        } else {
56910015Speter                            typeEnter.ensureImportsChecked(List.of(cut));
57010015Speter                        }
57110015Speter                    }
57210015Speter                } else {
57310015Speter                    typeEnter.ensureImportsChecked(unfinishedModules.toList());
57410015Speter                    unfinishedModules.clear();
57510015Speter                    typeEnter.ensureImportsChecked(trees);
57610015Speter                }
57710015Speter            }
57810015Speter        } finally {
57910015Speter            uncompleted = prevUncompleted;
58010015Speter            annotate.unblockAnnotations();
58110015Speter        }
58210015Speter    }
58310015Speter
58410015Speter    public void newRound() {
58533395Speter        typeEnvs.clear();
58633395Speter    }
58733395Speter}
58833395Speter