src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java
author Dusan Balek <dbalek@netbeans.org>
Fri, 04 Aug 2017 13:32:32 +0200
changeset 5956 15c0d1682895
parent 5758 132a238fb298
permissions -rw-r--r--
Issue #271211 - NullPointerException at com.sun.tools.javac.comp.Enter.lambda$visitTopLevel$1 - fixed.
duke@0
     1
/*
vromero@5735
     2
 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
duke@0
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0
     4
 *
duke@0
     5
 * This code is free software; you can redistribute it and/or modify it
duke@0
     6
 * under the terms of the GNU General Public License version 2 only, as
ohair@961
     7
 * published by the Free Software Foundation.  Oracle designates this
duke@0
     8
 * particular file as subject to the "Classpath" exception as provided
ohair@961
     9
 * by Oracle in the LICENSE file that accompanied this code.
duke@0
    10
 *
duke@0
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
duke@0
    14
 * version 2 for more details (a copy is included in the LICENSE file that
duke@0
    15
 * accompanied this code).
duke@0
    16
 *
duke@0
    17
 * You should have received a copy of the GNU General Public License version
duke@0
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0
    20
 *
ohair@961
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@961
    22
 * or visit www.oracle.com if you need additional information or have any
ohair@961
    23
 * questions.
duke@0
    24
 */
duke@0
    25
duke@0
    26
package com.sun.tools.javac.comp;
duke@0
    27
jlahoda@5
    28
import java.net.URI;
dbalek@5244
    29
import java.util.HashMap;
alanb@5016
    30
import java.util.Map;
alanb@5016
    31
import java.util.Optional;
alanb@5016
    32
dbalek@749
    33
import javax.lang.model.element.ExecutableElement;
dbalek@749
    34
import javax.lang.model.element.TypeElement;
dbalek@749
    35
import javax.lang.model.element.VariableElement;
dbalek@1220
    36
import javax.lang.model.util.ElementScanner6;
duke@0
    37
import javax.tools.JavaFileObject;
duke@0
    38
import javax.tools.JavaFileManager;
duke@0
    39
dbalek@1220
    40
import com.sun.tools.javac.api.DuplicateClassChecker;
duke@0
    41
import com.sun.tools.javac.code.*;
vromero@5735
    42
import com.sun.tools.javac.code.Kinds.KindName;
emc@4248
    43
import com.sun.tools.javac.code.Kinds.KindSelector;
jjg@1205
    44
import com.sun.tools.javac.code.Scope.*;
jjg@1205
    45
import com.sun.tools.javac.code.Symbol.*;
jjg@1205
    46
import com.sun.tools.javac.code.Type.*;
jjg@1996
    47
import com.sun.tools.javac.main.Option.PkgInfo;
dbalek@1220
    48
import com.sun.tools.javac.model.LazyTreeLoader;
alanb@5016
    49
import com.sun.tools.javac.resources.CompilerProperties.Errors;
duke@0
    50
import com.sun.tools.javac.tree.*;
jjg@1205
    51
import com.sun.tools.javac.tree.JCTree.*;
duke@0
    52
import com.sun.tools.javac.util.*;
duke@0
    53
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
duke@0
    54
import com.sun.tools.javac.util.List;
duke@0
    55
duke@0
    56
import static com.sun.tools.javac.code.Flags.*;
emc@4248
    57
import static com.sun.tools.javac.code.Kinds.Kind.*;
duke@0
    58
duke@0
    59
/** This class enters symbols for all encountered definitions into
jlahoda@4314
    60
 *  the symbol table. The pass consists of high-level two phases,
jlahoda@4314
    61
 *  organized as follows:
duke@0
    62
 *
jjg@2213
    63
 *  <p>In the first phase, all class symbols are entered into their
duke@0
    64
 *  enclosing scope, descending recursively down the tree for classes
duke@0
    65
 *  which are members of other classes. The class symbols are given a
jlahoda@4314
    66
 *  TypeEnter object as completer.
duke@0
    67
 *
duke@0
    68
 *  <p>In the second phase classes are completed using
jlahoda@4314
    69
 *  TypeEnter.complete(). Completion might occur on demand, but
duke@0
    70
 *  any classes that are not completed that way will be eventually
jlahoda@4314
    71
 *  completed by processing the `uncompleted' queue. Completion
jlahoda@4314
    72
 *  entails determination of a class's parameters, supertype and
jlahoda@4314
    73
 *  interfaces, as well as entering all symbols defined in the
duke@0
    74
 *  class into its scope, with the exception of class symbols which
jlahoda@4314
    75
 *  have been entered in phase 1.
duke@0
    76
 *
duke@0
    77
 *  <p>Whereas the first phase is organized as a sweep through all
jlahoda@4314
    78
 *  compiled syntax trees, the second phase is on-demand. Members of a
duke@0
    79
 *  class are entered when the contents of a class are first
duke@0
    80
 *  accessed. This is accomplished by installing completer objects in
jlahoda@4314
    81
 *  class symbols for compiled classes which invoke the type-enter
duke@0
    82
 *  phase for the corresponding class tree.
duke@0
    83
 *
duke@0
    84
 *  <p>Classes migrate from one phase to the next via queues:
duke@0
    85
 *
jjg@2167
    86
 *  <pre>{@literal
jlahoda@4314
    87
 *  class enter -> (Enter.uncompleted)         --> type enter
duke@0
    88
 *              -> (Todo)                      --> attribute
duke@0
    89
 *                                              (only for toplevel classes)
jjg@2167
    90
 *  }</pre>
duke@0
    91
 *
jjg@971
    92
 *  <p><b>This is NOT part of any supported API.
jjg@971
    93
 *  If you write code that depends on this, you do so at your own risk.
duke@0
    94
 *  This code and its internal interfaces are subject to change or
duke@0
    95
 *  deletion without notice.</b>
duke@0
    96
 */
duke@0
    97
public class Enter extends JCTree.Visitor {
briangoetz@3808
    98
    protected static final Context.Key<Enter> enterKey = new Context.Key<>();
duke@0
    99
jjg@4454
   100
    Annotate annotate;
duke@0
   101
    Log log;
duke@0
   102
    Symtab syms;
duke@0
   103
    Check chk;
duke@0
   104
    TreeMaker make;
jlahoda@4314
   105
    TypeEnter typeEnter;
jjg@289
   106
    Types types;
duke@0
   107
    Lint lint;
jjg@876
   108
    Names names;
duke@0
   109
    JavaFileManager fileManager;
jjg@1053
   110
    PkgInfo pkginfoOpt;
pgovereau@4044
   111
    TypeEnvs typeEnvs;
alanb@5016
   112
    Modules modules;
alanb@5016
   113
    JCDiagnostic.Factory diags;
jlahoda@1073
   114
    
jlahoda@5
   115
    private final LazyTreeLoader treeLoader;
dbalek@814
   116
    private final DuplicateClassChecker duplicateClassChecker;
jlahoda@5
   117
    private final Source source;
duke@0
   118
duke@0
   119
    private final Todo todo;
duke@0
   120
duke@0
   121
    public static Enter instance(Context context) {
duke@0
   122
        Enter instance = context.get(enterKey);
duke@0
   123
        if (instance == null)
duke@0
   124
            instance = new Enter(context);
duke@0
   125
        return instance;
duke@0
   126
    }
duke@0
   127
duke@0
   128
    protected Enter(Context context) {
duke@0
   129
        context.put(enterKey, this);
duke@0
   130
duke@0
   131
        log = Log.instance(context);
duke@0
   132
        make = TreeMaker.instance(context);
duke@0
   133
        syms = Symtab.instance(context);
duke@0
   134
        chk = Check.instance(context);
jlahoda@4314
   135
        typeEnter = TypeEnter.instance(context);
jjg@289
   136
        types = Types.instance(context);
duke@0
   137
        annotate = Annotate.instance(context);
duke@0
   138
        lint = Lint.instance(context);
jjg@876
   139
        names = Names.instance(context);
alanb@5016
   140
        modules = Modules.instance(context);
alanb@5016
   141
        diags = JCDiagnostic.Factory.instance(context);
jlahoda@5
   142
        treeLoader = LazyTreeLoader.instance(context);
dbalek@814
   143
        duplicateClassChecker = context.get(DuplicateClassChecker.class);
duke@0
   144
duke@0
   145
        predefClassDef = make.ClassDef(
duke@0
   146
            make.Modifiers(PUBLIC),
jjg@2337
   147
            syms.predefClass.name,
mcimadamore@5586
   148
            List.nil(),
jjg@2337
   149
            null,
mcimadamore@5586
   150
            List.nil(),
mcimadamore@5586
   151
            List.nil());
duke@0
   152
        predefClassDef.sym = syms.predefClass;
duke@0
   153
        todo = Todo.instance(context);
duke@0
   154
        fileManager = context.get(JavaFileManager.class);
jjg@1053
   155
jjg@1053
   156
        Options options = Options.instance(context);
jjg@1053
   157
        pkginfoOpt = PkgInfo.get(options);
pgovereau@4044
   158
        typeEnvs = TypeEnvs.instance(context);
jlahoda@5
   159
        source = Source.instance(context);
duke@0
   160
    }
duke@0
   161
jlahoda@5
   162
    Map<TypeSymbol,Env<AttrContext>> typeEnvsShadow = null;
jlahoda@5
   163
jlahoda@5
   164
    private final Map<URI, JCCompilationUnit> compilationUnits =
jlahoda@5
   165
            new HashMap<URI, JCCompilationUnit> ();
jlahoda@5
   166
dbalek@4426
   167
    public JCCompilationUnit getCompilationUnit (JavaFileObject fobj) {
dbalek@4426
   168
        return this.compilationUnits.get(fobj.toUri());
duke@0
   169
    }
duke@0
   170
duke@0
   171
    /** Accessor for typeEnvs
duke@0
   172
     */
duke@0
   173
    public Env<AttrContext> getEnv(TypeSymbol sym) {
duke@0
   174
        return typeEnvs.get(sym);
duke@0
   175
    }
duke@0
   176
jlahoda@3928
   177
    public Iterable<Env<AttrContext>> getEnvs() {
jlahoda@3928
   178
        return typeEnvs.values();
jlahoda@3928
   179
    }
jlahoda@3928
   180
duke@0
   181
    public Env<AttrContext> getClassEnv(TypeSymbol sym) {
duke@0
   182
        Env<AttrContext> localEnv = getEnv(sym);
vromero@5739
   183
        if (localEnv == null) return null;
duke@0
   184
        Env<AttrContext> lintEnv = localEnv;
duke@0
   185
        while (lintEnv.info.lint == null)
duke@0
   186
            lintEnv = lintEnv.next;
jjg@2786
   187
        localEnv.info.lint = lintEnv.info.lint.augment(sym);
duke@0
   188
        return localEnv;
duke@0
   189
    }
duke@0
   190
duke@0
   191
    /** The queue of all classes that might still need to be completed;
duke@0
   192
     *  saved and initialized by main().
duke@0
   193
     */
duke@0
   194
    ListBuffer<ClassSymbol> uncompleted;
duke@0
   195
alanb@5550
   196
    /** The queue of modules whose imports still need to be checked. */
alanb@5550
   197
    ListBuffer<JCCompilationUnit> unfinishedModules = new ListBuffer<>();
alanb@5550
   198
duke@0
   199
    /** A dummy class to serve as enclClass for toplevel environments.
duke@0
   200
     */
duke@0
   201
    private JCClassDecl predefClassDef;
duke@0
   202
duke@0
   203
/* ************************************************************************
duke@0
   204
 * environment construction
duke@0
   205
 *************************************************************************/
duke@0
   206
duke@0
   207
duke@0
   208
    /** Create a fresh environment for class bodies.
duke@0
   209
     *  This will create a fresh scope for local symbols of a class, referred
duke@0
   210
     *  to by the environments info.scope field.
duke@0
   211
     *  This scope will contain
duke@0
   212
     *    - symbols for this and super
duke@0
   213
     *    - symbols for any type parameters
duke@0
   214
     *  In addition, it serves as an anchor for scopes of methods and initializers
duke@0
   215
     *  which are nested in this scope via Scope.dup().
duke@0
   216
     *  This scope should not be confused with the members scope of a class.
duke@0
   217
     *
duke@0
   218
     *  @param tree     The class definition.
duke@0
   219
     *  @param env      The environment current outside of the class definition.
duke@0
   220
     */
duke@0
   221
    public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) {
duke@0
   222
        Env<AttrContext> localEnv =
jlahoda@4103
   223
            env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
duke@0
   224
        localEnv.enclClass = tree;
duke@0
   225
        localEnv.outer = env;
duke@0
   226
        localEnv.info.isSelfCall = false;
duke@0
   227
        localEnv.info.lint = null; // leave this to be filled in by Attr,
duke@0
   228
                                   // when annotations have been processed
sadayapalam@4445
   229
        localEnv.info.isAnonymousDiamond = TreeInfo.isDiamond(env.tree);
duke@0
   230
        return localEnv;
duke@0
   231
    }
duke@0
   232
duke@0
   233
    /** Create a fresh environment for toplevels.
duke@0
   234
     *  @param tree     The toplevel tree.
duke@0
   235
     */
duke@0
   236
    Env<AttrContext> topLevelEnv(JCCompilationUnit tree) {
briangoetz@3808
   237
        Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
duke@0
   238
        localEnv.toplevel = tree;
duke@0
   239
        localEnv.enclClass = predefClassDef;
jlahoda@4103
   240
        tree.toplevelScope = WriteableScope.create(tree.packge);
jlahoda@4103
   241
        tree.namedImportScope = new NamedImportScope(tree.packge, tree.toplevelScope);
jjg@1205
   242
        tree.starImportScope = new StarImportScope(tree.packge);
jlahoda@4103
   243
        localEnv.info.scope = tree.toplevelScope;
duke@0
   244
        localEnv.info.lint = lint;
duke@0
   245
        return localEnv;
duke@0
   246
    }
duke@0
   247
duke@0
   248
    public Env<AttrContext> getTopLevelEnv(JCCompilationUnit tree) {
briangoetz@3808
   249
        Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
duke@0
   250
        localEnv.toplevel = tree;
duke@0
   251
        localEnv.enclClass = predefClassDef;
jlahoda@4103
   252
        localEnv.info.scope = tree.toplevelScope;
duke@0
   253
        localEnv.info.lint = lint;
duke@0
   254
        return localEnv;
duke@0
   255
    }
duke@0
   256
duke@0
   257
    /** The scope in which a member definition in environment env is to be entered
duke@0
   258
     *  This is usually the environment's scope, except for class environments,
duke@0
   259
     *  where the local scope is for type variables, and the this and super symbol
duke@0
   260
     *  only, and members go into the class member scope.
duke@0
   261
     */
jlahoda@4103
   262
    WriteableScope enterScope(Env<AttrContext> env) {
jjg@1972
   263
        return (env.tree.hasTag(JCTree.Tag.CLASSDEF))
duke@0
   264
            ? ((JCClassDecl) env.tree).sym.members_field
duke@0
   265
            : env.info.scope;
duke@0
   266
    }
duke@0
   267
alanb@5016
   268
    /** Create a fresh environment for modules.
alanb@5016
   269
     *
alanb@5016
   270
     *  @param tree     The module definition.
alanb@5016
   271
     *  @param env      The environment current outside of the module definition.
alanb@5016
   272
     */
alanb@5016
   273
    public Env<AttrContext> moduleEnv(JCModuleDecl tree, Env<AttrContext> env) {
alanb@5016
   274
        Assert.checkNonNull(tree.sym);
alanb@5016
   275
        Env<AttrContext> localEnv =
alanb@5016
   276
            env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
alanb@5016
   277
        localEnv.enclClass = predefClassDef;
alanb@5016
   278
        localEnv.outer = env;
alanb@5016
   279
        localEnv.info.isSelfCall = false;
alanb@5016
   280
        localEnv.info.lint = null; // leave this to be filled in by Attr,
alanb@5016
   281
                                   // when annotations have been processed
alanb@5016
   282
        return localEnv;
alanb@5016
   283
    }
alanb@5016
   284
jlahoda@5
   285
    public void shadowTypeEnvs(boolean b) {
jlahoda@5
   286
        if (b) {
jlahoda@5
   287
            assert typeEnvsShadow == null;
jlahoda@5
   288
            typeEnvsShadow = new HashMap<TypeSymbol,Env<AttrContext>>();
jlahoda@5
   289
        } else {
dbalek@1606
   290
            for (Map.Entry<TypeSymbol, Env<AttrContext>> entry : typeEnvsShadow.entrySet()) {
dbalek@1606
   291
                if (entry.getValue() == null)
dbalek@1606
   292
                    typeEnvs.remove(entry.getKey());
dbalek@1606
   293
                else
dbalek@1606
   294
                    typeEnvs.put(entry.getKey(), entry.getValue());
dbalek@1606
   295
            }
jlahoda@5
   296
            typeEnvsShadow = null;
jlahoda@5
   297
        }
jlahoda@5
   298
    }
dbalek@3530
   299
    
dbalek@3530
   300
    public boolean isShadowed() {
dbalek@3530
   301
        return typeEnvsShadow != null;
dbalek@3530
   302
    }
jlahoda@5
   303
duke@0
   304
/* ************************************************************************
duke@0
   305
 * Visitor methods for phase 1: class enter
duke@0
   306
 *************************************************************************/
duke@0
   307
duke@0
   308
    /** Visitor argument: the current environment.
duke@0
   309
     */
duke@0
   310
    protected Env<AttrContext> env;
duke@0
   311
duke@0
   312
    /** Visitor result: the computed type.
duke@0
   313
     */
duke@0
   314
    Type result;
duke@0
   315
duke@0
   316
    /** Visitor method: enter all classes in given tree, catching any
duke@0
   317
     *  completion failure exceptions. Return the tree's type.
duke@0
   318
     *
duke@0
   319
     *  @param tree    The tree to be visited.
duke@0
   320
     *  @param env     The environment visitor argument.
duke@0
   321
     */
duke@0
   322
    Type classEnter(JCTree tree, Env<AttrContext> env) {
duke@0
   323
        Env<AttrContext> prevEnv = this.env;
duke@0
   324
        try {
duke@0
   325
            this.env = env;
jjg@4454
   326
            annotate.blockAnnotations();
duke@0
   327
            tree.accept(this);
duke@0
   328
            return result;
duke@0
   329
        }  catch (CompletionFailure ex) {
duke@0
   330
            return chk.completionError(tree.pos(), ex);
duke@0
   331
        } finally {
jjg@4454
   332
            annotate.unblockAnnotations();
duke@0
   333
            this.env = prevEnv;
duke@0
   334
        }
duke@0
   335
    }
duke@0
   336
duke@0
   337
    /** Visitor method: enter classes of a list of trees, returning a list of types.
duke@0
   338
     */
duke@0
   339
    <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) {
briangoetz@3808
   340
        ListBuffer<Type> ts = new ListBuffer<>();
jjg@251
   341
        for (List<T> l = trees; l.nonEmpty(); l = l.tail) {
jjg@251
   342
            Type t = classEnter(l.head, env);
jjg@251
   343
            if (t != null)
jjg@251
   344
                ts.append(t);
jjg@251
   345
        }
duke@0
   346
        return ts.toList();
duke@0
   347
    }
duke@0
   348
jjg@904
   349
    @Override
duke@0
   350
    public void visitTopLevel(JCCompilationUnit tree) {
alanb@5016
   351
//        Assert.checkNonNull(tree.modle, tree.sourcefile.toString());
alanb@5016
   352
duke@0
   353
        JavaFileObject prev = log.useSource(tree.sourcefile);
duke@0
   354
        boolean addEnv = false;
duke@0
   355
        boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info",
duke@0
   356
                                                             JavaFileObject.Kind.SOURCE);
alanb@5016
   357
        if (TreeInfo.isModuleInfo(tree)) {
alanb@5550
   358
            JCPackageDecl pd = tree.getPackage();
alanb@5550
   359
            if (pd != null) {
alanb@5550
   360
                log.error(pd.pos(), Errors.NoPkgInModuleInfoJava);
alanb@5550
   361
            }
alanb@5016
   362
            tree.packge = syms.rootPackage;
dbalek@5609
   363
            Env<AttrContext> topEnv = topLevelEnv(tree);
dbalek@5252
   364
            if (tree.modle != syms.noModule) {
dbalek@5252
   365
                classEnter(tree.defs, topEnv);
dbalek@5252
   366
                tree.modle.usesProvidesCompleter = modules.getUsesProvidesCompleter();
dbalek@5252
   367
            }
alanb@5016
   368
        } else {
alanb@5016
   369
            JCPackageDecl pd = tree.getPackage();
alanb@5016
   370
            if (pd != null) {
alanb@5016
   371
                tree.packge = pd.packge = syms.enterPackage(tree.modle, TreeInfo.fullName(pd.pid));
dbalek@5244
   372
                PackageAttributer.attrib(pd.pid, tree.packge);
alanb@5016
   373
                if (   pd.annotations.nonEmpty()
alanb@5016
   374
                    || pkginfoOpt == PkgInfo.ALWAYS
alanb@5016
   375
                    || tree.docComments != null) {
alanb@5016
   376
                    if (isPkgInfo) {
alanb@5016
   377
                        addEnv = true;
alanb@5016
   378
                    } else if (pd.annotations.nonEmpty()) {
alanb@5016
   379
                        log.error(pd.annotations.head.pos(),
alanb@5016
   380
                                  "pkg.annotations.sb.in.package-info.java");
alanb@5016
   381
                    }
duke@0
   382
                }
alanb@5016
   383
            } else {
alanb@5016
   384
                tree.packge = tree.modle.unnamedPackage;
duke@0
   385
            }
duke@0
   386
alanb@5016
   387
            Map<Name, PackageSymbol> visiblePackages = tree.modle.visiblePackages;
alanb@5016
   388
            Optional<ModuleSymbol> dependencyWithPackage =
alanb@5016
   389
                syms.listPackageModules(tree.packge.fullname)
alanb@5016
   390
                    .stream()
alanb@5016
   391
                    .filter(m -> m != tree.modle)
dbalek@5956
   392
                    .filter(cand -> visiblePackages != null && visiblePackages.get(tree.packge.fullname) == syms.getPackage(cand, tree.packge.fullname))
alanb@5016
   393
                    .findAny();
alanb@5016
   394
alanb@5016
   395
            if (dependencyWithPackage.isPresent()) {
alanb@5016
   396
                log.error(pd, Errors.PackageInOtherModule(dependencyWithPackage.get()));
alanb@5016
   397
            }
alanb@5016
   398
alanb@5016
   399
            tree.packge.complete(); // Find all classes in package.
alanb@5016
   400
alanb@5016
   401
            Env<AttrContext> topEnv = topLevelEnv(tree);
alanb@5016
   402
            Env<AttrContext> packageEnv = isPkgInfo ? topEnv.dup(pd) : null;
alanb@5016
   403
alanb@5016
   404
            // Save environment of package-info.java file.
alanb@5016
   405
            if (isPkgInfo) {
alanb@5016
   406
                Env<AttrContext> env0 = typeEnvs.get(tree.packge);
alanb@5016
   407
                if (env0 != null) {
alanb@5016
   408
                    JCCompilationUnit tree0 = env0.toplevel;
alanb@5016
   409
                    if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
alanb@5016
   410
                        log.warning(pd != null ? pd.pid.pos() : null,
alanb@5016
   411
                                    "pkg-info.already.seen",
alanb@5016
   412
                                    tree.packge);
alanb@5016
   413
                    }
duke@0
   414
                }
alanb@5016
   415
                typeEnvs.put(tree.packge, packageEnv);
alanb@5016
   416
alanb@5016
   417
                for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner)
alanb@5016
   418
                    q.flags_field |= EXISTS;
alanb@5016
   419
alanb@5016
   420
                Name name = names.package_info;
alanb@5016
   421
                ClassSymbol c = syms.enterClass(tree.modle, name, tree.packge);
alanb@5016
   422
                c.flatname = names.fromString(tree.packge + "." + name);
alanb@5016
   423
                c.sourcefile = tree.sourcefile;
dbalek@5244
   424
                c.completer = Completer.NULL_COMPLETER;
alanb@5016
   425
                c.members_field = WriteableScope.create(c);
alanb@5016
   426
                tree.packge.package_info = c;
duke@0
   427
            }
dbalek@5244
   428
            compilationUnits.put(tree.sourcefile.toUri(), tree);
alanb@5016
   429
            classEnter(tree.defs, topEnv);
alanb@5016
   430
            if (addEnv) {
dbalek@5244
   431
                if ((tree.packge.flags_field & APT_CLEANED) != 0)
dbalek@5244
   432
                    todo.remove(tree.packge);
alanb@5016
   433
                todo.append(packageEnv);
alanb@5016
   434
            }
duke@0
   435
        }
duke@0
   436
        log.useSource(prev);
duke@0
   437
        result = null;
duke@0
   438
    }
duke@0
   439
dbalek@89
   440
    private static class PackageAttributer extends TreeScanner {
dbalek@89
   441
dbalek@89
   442
        private Symbol pkg;
dbalek@89
   443
dbalek@89
   444
        public static void attrib(JCExpression pid, Symbol pkg) {
dbalek@89
   445
            PackageAttributer pa = new PackageAttributer();
dbalek@89
   446
            pa.pkg = pkg;
dbalek@89
   447
            pa.scan(pid);
dbalek@89
   448
        }
dbalek@89
   449
dbalek@89
   450
        @Override
dbalek@89
   451
        public void visitIdent(JCIdent that) {
dbalek@89
   452
            that.sym = pkg;
dbalek@89
   453
        }
dbalek@89
   454
dbalek@89
   455
        @Override
dbalek@89
   456
        public void visitSelect(JCFieldAccess that) {
dbalek@89
   457
            that.sym = pkg;
dbalek@89
   458
            pkg = pkg.owner;
dbalek@89
   459
            super.visitSelect(that);
dbalek@89
   460
        }
dbalek@89
   461
    }
dbalek@89
   462
dbalek@957
   463
jjg@904
   464
    @Override
duke@0
   465
    public void visitClassDef(JCClassDecl tree) {
duke@0
   466
        Symbol owner = env.info.scope.owner;
jlahoda@4103
   467
        WriteableScope enclScope = enterScope(env);
jlahoda@5
   468
        ClassSymbol c = null;
jlahoda@5
   469
        boolean doEnterClass = true;
jlahoda@5
   470
        boolean reattr=false, noctx=false;
duke@0
   471
        if (owner.kind == PCK) {
duke@0
   472
            // We are seeing a toplevel class.
duke@0
   473
            PackageSymbol packge = (PackageSymbol)owner;
duke@0
   474
            for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner)
duke@0
   475
                q.flags_field |= EXISTS;
alanb@5016
   476
            c = syms.enterClass(env.toplevel.modle, tree.name, packge);
duke@0
   477
            packge.members().enterIfAbsent(c);
duke@0
   478
            if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {
vromero@5735
   479
                KindName topElement = KindName.CLASS;
vromero@5735
   480
                if ((tree.mods.flags & ENUM) != 0) {
vromero@5735
   481
                    topElement = KindName.ENUM;
vromero@5735
   482
                } else if ((tree.mods.flags & INTERFACE) != 0) {
vromero@5735
   483
                    topElement = KindName.INTERFACE;
vromero@5735
   484
                }
duke@0
   485
                log.error(tree.pos(),
vromero@5735
   486
                          "class.public.should.be.in.file", topElement, tree.name);
duke@0
   487
            }
duke@0
   488
        } else {
jlahoda@5
   489
            if ((enclScope.owner.flags_field & FROMCLASS) != 0) {
dbalek@4426
   490
                for (Symbol sym : enclScope.getSymbolsByName(tree.name)) {
dbalek@4426
   491
                    if (sym.kind == TYP) {
dbalek@4426
   492
                        c = (ClassSymbol)sym;
jlahoda@5
   493
                        break;
jlahoda@5
   494
                    }
duke@0
   495
                }
dbalek@731
   496
                if (c != null) {
dbalek@5244
   497
                    if (chk.getCompiled(c) != null) {
dbalek@748
   498
                        c = null;
dbalek@748
   499
                    } else {
dbalek@748
   500
                        reattr = true;
dbalek@748
   501
                        if (owner.kind == TYP) {
dbalek@748
   502
                            if ((owner.flags_field & INTERFACE) != 0) {
dbalek@748
   503
                                tree.mods.flags |= PUBLIC | STATIC;
dbalek@748
   504
                            }
dbalek@27
   505
                        }
dbalek@748
   506
                        doEnterClass = false;
jlahoda@5
   507
                    }
dbalek@731
   508
                } else if ((enclScope.owner.flags_field & APT_CLEANED) == 0) {
dbalek@731
   509
                    ClassSymbol cs = enclScope.owner.outermostClass();
dbalek@731
   510
                    treeLoader.couplingError(cs, tree);
dbalek@731
   511
                    doEnterClass = false;
jlahoda@5
   512
                }
duke@0
   513
            }
dbalek@27
   514
            if (c == null) {
dbalek@391
   515
                if (!tree.name.isEmpty() &&
jlahoda@5
   516
                        !chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {
dbalek@391
   517
                    result = types.createErrorType(tree.name, owner, Type.noType);
jlahoda@5
   518
                    tree.sym = (ClassSymbol)result.tsym;
jlahoda@5
   519
                    Env<AttrContext> localEnv = classEnv(tree, env);
jlahoda@5
   520
                    typeEnvs.put(tree.sym, localEnv);
dbalek@4426
   521
                    tree.sym.completer = typeEnter;
dbalek@181
   522
                    ((ClassType)result).typarams_field = classEnter(tree.typarams, localEnv);
dbalek@120
   523
                    if (!tree.sym.isLocal() && uncompleted != null) uncompleted.append(tree.sym);
dbalek@4741
   524
                    tree.type = tree.sym.type;
jlahoda@5
   525
                    return;
duke@0
   526
                }
dbalek@488
   527
                if (owner.kind == TYP || owner.kind == ERR) {
jlahoda@5
   528
                    // We are seeing a member class.
dbalek@5244
   529
                    c = syms.enterClass(env.toplevel.modle, tree.name, (TypeSymbol)owner);
dbalek@5603
   530
                    if (c.owner != owner) {
dbalek@5603
   531
                        //anonymous class loaded from a classfile may be recreated from source (see below)
dbalek@5603
   532
                        //if this class is a member of such an anonymous class, fix the owner:
dbalek@5616
   533
                        Assert.check(owner.owner.kind != TYP && owner.owner.kind != ERR, owner::toString);
dbalek@5603
   534
                        Symbol own = c.owner;
dbalek@5758
   535
                        Assert.check(c.owner.kind == TYP || c.owner.kind == ERR, own::toString);
dbalek@5603
   536
                        ClassSymbol cowner = (ClassSymbol) c.owner;
dbalek@5603
   537
                        if (cowner.members_field != null) {
dbalek@5603
   538
                            cowner.members_field.remove(c);
dbalek@5603
   539
                        }
dbalek@5603
   540
                        c.owner = owner;
jlahoda@5554
   541
                    }
jlahoda@5
   542
                    if ((owner.flags_field & INTERFACE) != 0) {
jlahoda@5
   543
                        tree.mods.flags |= PUBLIC | STATIC;
jlahoda@5
   544
                    }
jlahoda@5
   545
                    Symbol q = owner;
dbalek@4426
   546
                    while(q != null && q.kind.matches(KindSelector.TYP)) {
jlahoda@5
   547
                        q = q.owner;
jlahoda@5
   548
                    }
dbalek@5244
   549
                    if (q != null && q.kind != PCK && chk.getCompiled(c) != null) {
jlahoda@5
   550
                        reattr = true;
jlahoda@5
   551
                    }
jlahoda@5
   552
                } else {
jlahoda@5
   553
                    // We are seeing a local class.
jlahoda@1764
   554
                    if (getIndex(tree) == -1) {
dbalek@4426
   555
                        c = syms.defineClass(tree.name, owner);
jlahoda@5
   556
                        c.flatname = chk.localClassName(c);
jlahoda@5
   557
                        noctx = true;
jlahoda@5
   558
                    }
jlahoda@5
   559
                    else {
jlahoda@1764
   560
                        Name flatname = chk.localClassName(owner.enclClass(), tree.name, getIndex(tree));
dbalek@5244
   561
                        if ((c=chk.getCompiled(env.toplevel.modle, flatname)) != null) {
jlahoda@5
   562
                            reattr = true;
jlahoda@5
   563
                        }
jlahoda@5
   564
                        else {
dbalek@5244
   565
                            c = syms.enterClass(env.toplevel.modle, flatname, tree.name, owner);
dbalek@4743
   566
                            if (c.completer.isTerminal())
dbalek@35
   567
                                reattr = true;
jlahoda@5
   568
                        }
jlahoda@5
   569
                    }
dbalek@391
   570
                    if (!c.name.isEmpty())
jlahoda@5
   571
                        chk.checkTransparentClass(tree.pos(), c, env.info.scope);
jlahoda@5
   572
                }
duke@0
   573
            }
duke@0
   574
        }
duke@0
   575
        tree.sym = c;
duke@0
   576
dbalek@112
   577
        if (c.kind == ERR && c.type.isErroneous()) {
dbalek@112
   578
            c.flags_field &= ~FROMCLASS;
dbalek@112
   579
            c.kind = TYP;
dbalek@112
   580
            c.type = new ClassType(Type.noType, List.<Type>nil(), c);
dbalek@4741
   581
        } else if (reattr && c.completer.isTerminal()) {
dbalek@749
   582
            new ElementScanner6<Void, Void>() {
dbalek@749
   583
                @Override
dbalek@2734
   584
                public Void visitType(TypeElement te, Void p) {
dbalek@4743
   585
                    if (te instanceof ClassSymbol && ((ClassSymbol) te).completer.isTerminal()) {
dbalek@2734
   586
                        ((ClassSymbol) te).flags_field |= FROMCLASS;
dbalek@4426
   587
                        for (Symbol sym : ((ClassSymbol) te).members().getSymbols()) {
dbalek@2734
   588
                            try {
dbalek@4426
   589
                                if (sym != null && sym.owner == te)
dbalek@4426
   590
                                    scan(sym);
dbalek@2734
   591
                            } catch (CompletionFailure cf) {}
dbalek@2734
   592
                        }
dbalek@2734
   593
                    }
dbalek@749
   594
                    return null;
dbalek@749
   595
                }
dbalek@749
   596
                @Override
dbalek@2734
   597
                public Void visitExecutable(ExecutableElement ee, Void p) {
dbalek@2734
   598
                    if (ee instanceof MethodSymbol)
dbalek@2734
   599
                        ((MethodSymbol) ee).flags_field |= FROMCLASS;
dbalek@2734
   600
                    return null;
dbalek@2734
   601
                }
dbalek@2734
   602
                @Override
dbalek@2734
   603
                public Void visitVariable(VariableElement ve, Void p) {
dbalek@2734
   604
                    if (ve instanceof VarSymbol)
dbalek@2734
   605
                        ((VarSymbol) ve).flags_field |= FROMCLASS;
dbalek@749
   606
                    return null;
dbalek@749
   607
                }
dbalek@749
   608
            }.scan(c);
jlahoda@5
   609
        }
jlahoda@5
   610
duke@0
   611
        // Enter class into `compiled' table and enclosing scope.
dbalek@5244
   612
        if (!reattr && !noctx && (chk.getCompiled(c) != null
dbalek@3773
   613
                || (!c.isLocal() && duplicateClassChecker != null && duplicateClassChecker.check(c.fullname, env.toplevel.getSourceFile())))) {
duke@0
   614
            duplicateClass(tree.pos(), c);
dbalek@748
   615
            result = types.createErrorType(tree.name, owner, Type.noType);
dbalek@748
   616
            tree.sym = c = (ClassSymbol)result.tsym;
dbalek@748
   617
        } else {
dbalek@5244
   618
            chk.putCompiled(c);
duke@0
   619
        }
jlahoda@5
   620
        if (doEnterClass) {
jlahoda@5
   621
            enclScope.enter(c);
jlahoda@5
   622
        }
duke@0
   623
jlahoda@5
   624
        if (typeEnvsShadow != null) {
jlahoda@5
   625
            Env<AttrContext> localEnv = typeEnvs.get(c);
jlahoda@5
   626
            typeEnvsShadow.put(c, localEnv);
jlahoda@5
   627
        }
duke@0
   628
        // Set up an environment for class block and store in `typeEnvs'
duke@0
   629
        // table, to be retrieved later in memberEnter and attribution.
duke@0
   630
        Env<AttrContext> localEnv = classEnv(tree, env);
duke@0
   631
        typeEnvs.put(c, localEnv);
duke@0
   632
duke@0
   633
        // Fill out class fields.
dbalek@4654
   634
        boolean notYetCompleted = !c.completer.isTerminal();
alundblad@4474
   635
        c.completer = Completer.NULL_COMPLETER; // do not allow the initial completer linger on.
duke@0
   636
        c.sourcefile = env.toplevel.sourcefile;
dbalek@27
   637
        if (notYetCompleted || (c.flags_field & FROMCLASS) == 0 && (enclScope.owner.flags_field & FROMCLASS) == 0) {
jlahoda@474
   638
            c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
dbalek@4426
   639
            c.members_field = WriteableScope.create(c);
duke@0
   640
jlahoda@5
   641
            ClassType ct = (ClassType)c.type;
jlahoda@5
   642
            if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
jlahoda@5
   643
                // We are seeing a local or inner class.
jlahoda@5
   644
                // Set outer_field of this class to closest enclosing class
jlahoda@5
   645
                // which contains this class in a non-static context
jlahoda@5
   646
                // (its "enclosing instance class"), provided such a class exists.
jlahoda@5
   647
                Symbol owner1 = owner;
dbalek@4426
   648
                while (owner1.kind.matches(KindSelector.VAL_MTH) &&
dbalek@4426
   649
                       (owner1.flags_field & STATIC) == 0) {
jlahoda@5
   650
                    owner1 = owner1.owner;
jlahoda@5
   651
                }
jlahoda@5
   652
                if (owner1.kind == TYP) {
jlahoda@5
   653
                    ct.setEnclosingType(owner1.type);
jlahoda@5
   654
                }
duke@0
   655
            }
jlahoda@5
   656
            // Enter type parameters.
jlahoda@5
   657
            ct.typarams_field = classEnter(tree.typarams, localEnv);
dbalek@5244
   658
            ct.allparams_field = null;
jlahoda@5
   659
        } else {
dbalek@743
   660
            c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree) | (c.flags_field & (FROMCLASS | APT_CLEANED));
jlahoda@5
   661
            ClassType ct = (ClassType)c.type;
jlahoda@1608
   662
            if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
jlahoda@1608
   663
                // We are seeing a local or inner class.
jlahoda@1608
   664
                // Set outer_field of this class to closest enclosing class
jlahoda@1608
   665
                // which contains this class in a non-static context
jlahoda@1608
   666
                // (its "enclosing instance class"), provided such a class exists.
jlahoda@1608
   667
                Symbol owner1 = owner;
dbalek@4426
   668
                while (owner1.kind.matches(KindSelector.VAL_MTH) &&
jlahoda@1608
   669
                        (owner1.flags_field & STATIC) == 0) {
jlahoda@1608
   670
                    owner1 = owner1.owner;
jlahoda@1608
   671
                }
jlahoda@1608
   672
                if (owner1.kind == TYP) {
jlahoda@1608
   673
                    ct.setEnclosingType(owner1.type);
jlahoda@1608
   674
                }
jlahoda@1608
   675
            }
jlahoda@5
   676
            boolean wasNull = false;
jlahoda@5
   677
            if (ct.typarams_field != null) {
jlahoda@5
   678
                for (List<Type> l = ct.typarams_field; l.nonEmpty(); l = l.tail)
jlahoda@5
   679
                    localEnv.info.scope.enter(l.head.tsym);
jlahoda@5
   680
            } else {
jlahoda@5
   681
                wasNull = true;
jlahoda@5
   682
            }
jlahoda@5
   683
            List<Type> classEnter = classEnter(tree.typarams, localEnv);
jlahoda@5
   684
            if (wasNull) {
jlahoda@5
   685
                if (!classEnter.isEmpty()) {
jlahoda@5
   686
                    //the symbol from class does not have any type parameters,
jlahoda@5
   687
                    //but the symbol in the source code does:
dbalek@4426
   688
                    ClassSymbol cs = env.info.scope.owner.outermostClass();
dbalek@4426
   689
                    treeLoader.couplingError(cs, tree);
jlahoda@5
   690
                } else {
jlahoda@5
   691
                    ct.typarams_field = List.nil();
dbalek@5244
   692
                    ct.allparams_field = null;
jlahoda@5
   693
                }
jlahoda@5
   694
            }
jlahoda@5
   695
            if (c.members_field == null) {
dbalek@4426
   696
                c.members_field = WriteableScope.create(c);
jlahoda@5
   697
                c.flags_field &= ~FROMCLASS;
duke@0
   698
            }
dbalek@4741
   699
            if (c.owner.kind.matches(KindSelector.VAL_MTH)) {
dbalek@4741
   700
                // local or anonymous class
dbalek@4741
   701
                for (Symbol ctor : c.members_field.getSymbolsByName(names.init)) {
dbalek@4741
   702
                    c.members_field.remove(ctor);
dbalek@4741
   703
                }
dbalek@4741
   704
            }
dbalek@4741
   705
       }
duke@0
   706
jlahoda@4374
   707
        // install further completer for this type.
jlahoda@4374
   708
        c.completer = typeEnter;
jlahoda@4374
   709
duke@0
   710
        // Add non-local class to uncompleted, to make sure it will be
duke@0
   711
        // completed later.
duke@0
   712
        if (!c.isLocal() && uncompleted != null) uncompleted.append(c);
duke@0
   713
//      System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG
duke@0
   714
duke@0
   715
        // Recursively enter all member classes.
duke@0
   716
        classEnter(tree.defs, localEnv);
duke@0
   717
dbalek@4741
   718
        result = tree.type = c.type;
duke@0
   719
    }
duke@0
   720
    //where
duke@0
   721
        /** Does class have the same name as the file it appears in?
duke@0
   722
         */
duke@0
   723
        private static boolean classNameMatchesFileName(ClassSymbol c,
duke@0
   724
                                                        Env<AttrContext> env) {
duke@0
   725
            return env.toplevel.sourcefile.isNameCompatible(c.name.toString(),
duke@0
   726
                                                            JavaFileObject.Kind.SOURCE);
duke@0
   727
        }
duke@0
   728
duke@0
   729
    /** Complain about a duplicate class. */
duke@0
   730
    protected void duplicateClass(DiagnosticPosition pos, ClassSymbol c) {
duke@0
   731
        log.error(pos, "duplicate.class", c.fullname);
duke@0
   732
    }
duke@0
   733
jlahoda@1764
   734
    protected int getIndex(JCClassDecl clazz) {
jlahoda@1764
   735
        return -1;
jlahoda@1764
   736
    }
jlahoda@1764
   737
duke@0
   738
    /** Class enter visitor method for type parameters.
duke@0
   739
     *  Enter a symbol for type parameter in local scope, after checking that it
duke@0
   740
     *  is unique.
duke@0
   741
     */
jjg@904
   742
    @Override
duke@0
   743
    public void visitTypeParameter(JCTypeParameter tree) {
jlahoda@5
   744
        result = null;
jlahoda@5
   745
        if ((env.info.scope.owner.flags_field & FROMCLASS) != 0) {
dbalek@4426
   746
            for (Symbol sym : env.info.scope.getSymbolsByName(tree.name)) {
dbalek@4426
   747
                if (sym.kind == TYP) {
dbalek@4426
   748
                    result = sym.type;
jlahoda@5
   749
                    tree.type = result;
jlahoda@5
   750
                    break;
jlahoda@5
   751
                }
jlahoda@5
   752
            }
dbalek@160
   753
            if (result != null)
dbalek@160
   754
                return;
dbalek@731
   755
            if ((env.info.scope.owner.flags_field & APT_CLEANED) == 0) {
dbalek@731
   756
                ClassSymbol cs = env.info.scope.owner.outermostClass();
dbalek@731
   757
                treeLoader.couplingError(cs, tree);
dbalek@731
   758
            }
duke@0
   759
        }
duke@0
   760
        TypeVar a = (tree.type != null)
dbalek@160
   761
        ? (TypeVar)tree.type
dbalek@160
   762
                : new TypeVar(tree.name, env.info.scope.owner, syms.botType);
duke@0
   763
        tree.type = a;
duke@0
   764
        if (chk.checkUnique(tree.pos(), a.tsym, env.info.scope)) {
duke@0
   765
            env.info.scope.enter(a.tsym);
duke@0
   766
        }
duke@0
   767
        result = a;
duke@0
   768
    }
duke@0
   769
alanb@5016
   770
    @Override
alanb@5016
   771
    public void visitModuleDef(JCModuleDecl tree) {
alanb@5016
   772
        Env<AttrContext> moduleEnv = moduleEnv(tree, env);
alanb@5016
   773
        typeEnvs.put(tree.sym, moduleEnv);
alanb@5550
   774
        if (modules.isInModuleGraph(tree.sym)) {
alanb@5550
   775
            todo.append(moduleEnv);
alanb@5550
   776
        }
alanb@5016
   777
    }
alanb@5016
   778
duke@0
   779
    /** Default class enter visitor method: do nothing.
duke@0
   780
     */
jjg@904
   781
    @Override
duke@0
   782
    public void visitTree(JCTree tree) {
duke@0
   783
        result = null;
duke@0
   784
    }
duke@0
   785
duke@0
   786
    /** Main method: enter all classes in a list of toplevel trees.
duke@0
   787
     *  @param trees      The list of trees to be processed.
duke@0
   788
     */
duke@0
   789
    public void main(List<JCCompilationUnit> trees) {
duke@0
   790
        complete(trees, null);
duke@0
   791
    }
duke@0
   792
jlahoda@4314
   793
    /** Main method: enter classes from the list of toplevel trees, possibly
jlahoda@4314
   794
     *  skipping TypeEnter for all but 'c' by placing them on the uncompleted
jlahoda@4314
   795
     *  list.
duke@0
   796
     *  @param trees      The list of trees to be processed.
jlahoda@4314
   797
     *  @param c          The class symbol to be processed or null to process all.
duke@0
   798
     */
duke@0
   799
    public void complete(List<JCCompilationUnit> trees, ClassSymbol c) {
jjg@4454
   800
        annotate.blockAnnotations();
duke@0
   801
        ListBuffer<ClassSymbol> prevUncompleted = uncompleted;
jlahoda@4314
   802
        if (typeEnter.completionEnabled) uncompleted = new ListBuffer<>();
duke@0
   803
duke@0
   804
        try {
duke@0
   805
            // enter all classes, and construct uncompleted list
duke@0
   806
            classEnter(trees, null);
duke@0
   807
duke@0
   808
            // complete all uncompleted classes in memberEnter
jlahoda@4314
   809
            if (typeEnter.completionEnabled) {
duke@0
   810
                while (uncompleted.nonEmpty()) {
duke@0
   811
                    ClassSymbol clazz = uncompleted.next();
duke@0
   812
                    if (c == null || c == clazz || prevUncompleted == null)
duke@0
   813
                        clazz.complete();
duke@0
   814
                    else
duke@0
   815
                        // defer
duke@0
   816
                        prevUncompleted.append(clazz);
duke@0
   817
                }
duke@0
   818
alanb@5550
   819
                if (!modules.modulesInitialized()) {
alanb@5550
   820
                    for (JCCompilationUnit cut : trees) {
dbalek@5607
   821
                        if (TreeInfo.isModuleInfo(cut)) {
alanb@5550
   822
                            unfinishedModules.append(cut);
alanb@5550
   823
                        } else {
alanb@5550
   824
                            typeEnter.ensureImportsChecked(List.of(cut));
alanb@5550
   825
                        }
alanb@5550
   826
                    }
alanb@5550
   827
                } else {
alanb@5550
   828
                    typeEnter.ensureImportsChecked(unfinishedModules.toList());
alanb@5550
   829
                    unfinishedModules.clear();
alanb@5550
   830
                    typeEnter.ensureImportsChecked(trees);
alanb@5550
   831
                }
duke@0
   832
            }
duke@0
   833
        } finally {
duke@0
   834
            uncompleted = prevUncompleted;
jjg@4454
   835
            annotate.unblockAnnotations();
duke@0
   836
        }
duke@0
   837
    }
jlahoda@3928
   838
jlahoda@3928
   839
    public void newRound() {
jlahoda@3928
   840
        typeEnvs.clear();
jlahoda@3928
   841
    }
duke@0
   842
}