TypeEnter.java revision 3002:7eef740c1482
19313Ssos/*
29313Ssos * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
39313Ssos * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
49313Ssos *
59313Ssos * This code is free software; you can redistribute it and/or modify it
69313Ssos * under the terms of the GNU General Public License version 2 only, as
79313Ssos * published by the Free Software Foundation.  Oracle designates this
89313Ssos * particular file as subject to the "Classpath" exception as provided
9111798Sdes * by Oracle in the LICENSE file that accompanied this code.
109313Ssos *
119313Ssos * This code is distributed in the hope that it will be useful, but WITHOUT
129313Ssos * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
139313Ssos * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
149313Ssos * version 2 for more details (a copy is included in the LICENSE file that
1597748Sschweikh * accompanied this code).
169313Ssos *
179313Ssos * You should have received a copy of the GNU General Public License version
189313Ssos * 2 along with this work; if not, write to the Free Software Foundation,
199313Ssos * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
209313Ssos *
219313Ssos * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
229313Ssos * or visit www.oracle.com if you need additional information or have any
239313Ssos * questions.
249313Ssos */
259313Ssos
269313Ssospackage com.sun.tools.javac.comp;
279313Ssos
2850477Speterimport java.util.HashSet;
299313Ssosimport java.util.Set;
309313Ssosimport java.util.function.BiConsumer;
3131784Seivind
32101189Srwatsonimport javax.tools.JavaFileObject;
3331784Seivind
349313Ssosimport com.sun.tools.javac.code.*;
359313Ssosimport com.sun.tools.javac.code.Lint.LintCategory;
3676166Smarkmimport com.sun.tools.javac.code.Scope.ImportFilter;
3776166Smarkmimport com.sun.tools.javac.code.Scope.NamedImportScope;
389313Ssosimport com.sun.tools.javac.code.Scope.StarImportScope;
399313Ssosimport com.sun.tools.javac.code.Scope.WriteableScope;
409313Ssosimport com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
4131561Sbdeimport com.sun.tools.javac.tree.*;
42101189Srwatsonimport com.sun.tools.javac.util.*;
439313Ssosimport com.sun.tools.javac.util.DefinedBy.Api;
4472538Sjlemon
4576166Smarkmimport com.sun.tools.javac.code.Symbol.*;
4676166Smarkmimport com.sun.tools.javac.code.Type.*;
47102814Siedowseimport com.sun.tools.javac.tree.JCTree.*;
4876166Smarkm
4914331Speterimport static com.sun.tools.javac.code.Flags.*;
5076166Smarkmimport static com.sun.tools.javac.code.Flags.ANNOTATION;
5112458Sbdeimport static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
5272538Sjlemonimport static com.sun.tools.javac.code.Kinds.Kind.*;
5372538Sjlemonimport static com.sun.tools.javac.code.TypeTag.CLASS;
5472538Sjlemonimport static com.sun.tools.javac.code.TypeTag.ERROR;
5572538Sjlemonimport static com.sun.tools.javac.tree.JCTree.Tag.*;
5664905Smarcel
5768583Smarcelimport com.sun.tools.javac.util.Dependencies.AttributionKind;
5864905Smarcelimport com.sun.tools.javac.util.Dependencies.CompletionCause;
599313Ssosimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
6068201Sobrienimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
619313Ssos
6283366Sjulian/** This is the second phase of Enter, in which classes are completed
639313Ssos *  by resolving their headers and entering their members in the into
64102814Siedowse *  the class scope. See Enter for an overall overview.
65102814Siedowse *
669313Ssos *  This class uses internal phases to process the classes. When a phase
67102814Siedowse *  processes classes, the lower phases are not invoked until all classes
6814331Speter *  pass through the current phase. Note that it is possible that upper phases
699313Ssos *  are run due to recursive completion. The internal phases are:
7072543Sjlemon *  - ImportPhase: shallow pass through imports, adds information about imports
71102814Siedowse *                 the NamedImportScope and StarImportScope, but avoids queries
729313Ssos *                 about class hierarchy.
73102814Siedowse *  - HierarchyPhase: resolves the supertypes of the given class. Does not handle
74102814Siedowse *                    type parameters of the class or type argument of the supertypes.
75102814Siedowse *  - HeaderPhase: finishes analysis of the header of the given class by resolving
76102814Siedowse *                 type parameters, attributing supertypes including type arguments
779313Ssos *                 and scheduling full annotation attribution. This phase also adds
7868201Sobrien *                 a synthetic default constructor if needed and synthetic "this" field.
799313Ssos *  - MembersPhase: resolves headers for fields, methods and constructors in the given class.
809313Ssos *                  Also generates synthetic enum members.
8183366Sjulian *
829313Ssos *  <p><b>This is NOT part of any supported API.
8383382Sjhb *  If you write code that depends on this, you do so at your own risk.
84102814Siedowse *  This code and its internal interfaces are subject to change or
85102814Siedowse *  deletion without notice.</b>
8614331Speter */
8714331Speterpublic class TypeEnter implements Completer {
88102814Siedowse    protected static final Context.Key<TypeEnter> typeEnterKey = new Context.Key<>();
8914331Speter
90102814Siedowse    /** A switch to determine whether we check for package/class conflicts
9114331Speter     */
929313Ssos    final static boolean checkClash = true;
9372543Sjlemon
9472543Sjlemon    private final Names names;
95102814Siedowse    private final Enter enter;
969313Ssos    private final MemberEnter memberEnter;
97102814Siedowse    private final Log log;
989313Ssos    private final Check chk;
99102814Siedowse    private final Attr attr;
100111798Sdes    private final Symtab syms;
101102814Siedowse    private final TreeMaker make;
1029313Ssos    private final Todo todo;
103102814Siedowse    private final Annotate annotate;
1049313Ssos    private final TypeAnnotations typeAnnotations;
105102814Siedowse    private final Types types;
1069313Ssos    private final JCDiagnostic.Factory diags;
107102814Siedowse    private final Source source;
1089313Ssos    private final DeferredLintHandler deferredLintHandler;
109102814Siedowse    private final Lint lint;
1109313Ssos    private final TypeEnvs typeEnvs;
111102814Siedowse    private final Dependencies dependencies;
1129313Ssos
113102814Siedowse    public static TypeEnter instance(Context context) {
1149313Ssos        TypeEnter instance = context.get(typeEnterKey);
115102814Siedowse        if (instance == null)
1169313Ssos            instance = new TypeEnter(context);
117102814Siedowse        return instance;
1189313Ssos    }
119102814Siedowse
1209313Ssos    protected TypeEnter(Context context) {
121102814Siedowse        context.put(typeEnterKey, this);
1229313Ssos        names = Names.instance(context);
123102814Siedowse        enter = Enter.instance(context);
12470061Sjhb        memberEnter = MemberEnter.instance(context);
125102814Siedowse        log = Log.instance(context);
1269313Ssos        chk = Check.instance(context);
12789306Salfred        attr = Attr.instance(context);
1289313Ssos        syms = Symtab.instance(context);
12989319Salfred        make = TreeMaker.instance(context);
13070061Sjhb        todo = Todo.instance(context);
13189319Salfred        annotate = Annotate.instance(context);
13289319Salfred        typeAnnotations = TypeAnnotations.instance(context);
133102003Srwatson        types = Types.instance(context);
134102003Srwatson        diags = JCDiagnostic.Factory.instance(context);
13589319Salfred        source = Source.instance(context);
13689319Salfred        deferredLintHandler = DeferredLintHandler.instance(context);
13791140Stanimura        lint = Lint.instance(context);
13870061Sjhb        typeEnvs = TypeEnvs.instance(context);
13914331Speter        dependencies = Dependencies.instance(context);
14072543Sjlemon        Source source = Source.instance(context);
14172543Sjlemon        allowTypeAnnos = source.allowTypeAnnotations();
14214331Speter        allowDeprecationOnImport = source.allowDeprecationOnImport();
14391140Stanimura    }
144102814Siedowse
1459313Ssos    /** Switch: support type annotations.
1469313Ssos     */
1479313Ssos    boolean allowTypeAnnos;
1489313Ssos
14983366Sjulian    /**
1509313Ssos     * Switch: should deprecation warnings be issued on import
1519313Ssos     */
15212858Speter    boolean allowDeprecationOnImport;
15312858Speter
1549313Ssos    /** A flag to disable completion from time to time during member
15512858Speter     *  enter, as we only need to look up types.  This avoids
1569313Ssos     *  unnecessarily deep recursion.
15712858Speter     */
1589313Ssos    boolean completionEnabled = true;
1599313Ssos
1609313Ssos    /* Verify Imports:
16172543Sjlemon     */
16272543Sjlemon    protected void ensureImportsChecked(List<JCCompilationUnit> trees) {
16383221Smarcel        // if there remain any unimported toplevels (these must have
1649313Ssos        // no classes at all), process their import statements as well.
16512858Speter        for (JCCompilationUnit tree : trees) {
16612858Speter            if (!tree.starImportScope.isFilled()) {
1679313Ssos                Env<AttrContext> topEnv = enter.topLevelEnv(tree);
16883366Sjulian                finishImports(tree, () -> { completeClass.resolveImports(tree, topEnv); });
1699313Ssos            }
1709313Ssos        }
1719313Ssos    }
17268201Sobrien
17314331Speter/* ********************************************************************
17483366Sjulian * Source completer
17514331Speter *********************************************************************/
17614331Speter
17714331Speter    /** Complete entering a class.
17814331Speter     *  @param sym         The symbol of the class to be completed.
17914331Speter     */
18014331Speter    public void complete(Symbol sym) throws CompletionFailure {
18172543Sjlemon        // Suppress some (recursive) MemberEnter invocations
18272543Sjlemon        if (!completionEnabled) {
18372543Sjlemon            // Re-install same completer for next time around and return.
18414331Speter            Assert.check((sym.flags() & Flags.COMPOUND) == 0);
18514331Speter            sym.completer = this;
18614331Speter            return;
18714331Speter        }
18814331Speter
18914331Speter        try {
19014331Speter            annotate.blockAnnotations();
19183366Sjulian            sym.flags_field |= UNATTRIBUTED;
19214331Speter
19314331Speter            List<Env<AttrContext>> queue;
194111797Sdes
19514331Speter            dependencies.push((ClassSymbol) sym, CompletionCause.MEMBER_ENTER);
19614331Speter            try {
19783366Sjulian                queue = completeClass.runPhase(List.of(typeEnvs.get((ClassSymbol) sym)));
19814331Speter            } finally {
19914331Speter                dependencies.pop();
20068201Sobrien            }
20114331Speter
20268201Sobrien            if (!queue.isEmpty()) {
2039313Ssos                Set<JCCompilationUnit> seen = new HashSet<>();
20483366Sjulian
2059313Ssos                for (Env<AttrContext> env : queue) {
20614331Speter                    if (env.toplevel.defs.contains(env.enclClass) && seen.add(env.toplevel)) {
20714331Speter                        finishImports(env.toplevel, () -> {});
20814331Speter                    }
20914331Speter                }
21014331Speter            }
21183366Sjulian        } finally {
21214331Speter            annotate.unblockAnnotations();
21368201Sobrien        }
21414331Speter    }
21583221Smarcel
21683221Smarcel    void finishImports(JCCompilationUnit toplevel, Runnable resolve) {
21783221Smarcel        JavaFileObject prev = log.useSource(toplevel.sourcefile);
21883221Smarcel        try {
21983221Smarcel            resolve.run();
22083221Smarcel            chk.checkImportsUnique(toplevel);
22183221Smarcel            chk.checkImportsResolvable(toplevel);
22283221Smarcel            chk.checkImportedPackagesObservable(toplevel);
22383221Smarcel            toplevel.namedImportScope.finalizeScope();
22483221Smarcel            toplevel.starImportScope.finalizeScope();
22583221Smarcel        } finally {
22683221Smarcel            log.useSource(prev);
22783221Smarcel        }
22883221Smarcel    }
22983221Smarcel
23083221Smarcel    abstract class Phase {
23183221Smarcel        private final ListBuffer<Env<AttrContext>> queue = new ListBuffer<>();
23283221Smarcel        private final Phase next;
23383221Smarcel        private final CompletionCause phaseName;
23483221Smarcel
23583221Smarcel        Phase(CompletionCause phaseName, Phase next) {
23683221Smarcel            this.phaseName = phaseName;
23783221Smarcel            this.next = next;
23883221Smarcel        }
23983221Smarcel
24083221Smarcel        public List<Env<AttrContext>> runPhase(List<Env<AttrContext>> envs) {
24183221Smarcel            boolean firstToComplete = queue.isEmpty();
24283221Smarcel
24383221Smarcel            for (Env<AttrContext> env : envs) {
24483221Smarcel                JCClassDecl tree = (JCClassDecl)env.tree;
24583366Sjulian
24683221Smarcel                queue.add(env);
24714331Speter
248111798Sdes                JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
24983221Smarcel                DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
25083221Smarcel                try {
25183221Smarcel                    dependencies.push(env.enclClass.sym, phaseName);
25283221Smarcel                    doRunPhase(env);
25383221Smarcel                } catch (CompletionFailure ex) {
25483221Smarcel                    chk.completionError(tree.pos(), ex);
25583221Smarcel                } finally {
25683221Smarcel                    dependencies.pop();
25783221Smarcel                    deferredLintHandler.setPos(prevLintPos);
25883221Smarcel                    log.useSource(prev);
25983221Smarcel                }
26083221Smarcel            }
26183221Smarcel
26283221Smarcel            if (firstToComplete) {
26383221Smarcel                List<Env<AttrContext>> out = queue.toList();
2649313Ssos
26583366Sjulian                queue.clear();
26683221Smarcel                return next != null ? next.runPhase(out) : out;
2679313Ssos            } else {
26889306Salfred                return List.nil();
26989306Salfred            }
27083221Smarcel       }
27189306Salfred
2729313Ssos        protected abstract void doRunPhase(Env<AttrContext> env);
273109153Sdillon    }
27489306Salfred
27589306Salfred    private final ImportsPhase completeClass = new ImportsPhase();
27683221Smarcel
27789306Salfred    /**Analyze import clauses.
2789313Ssos     */
27991406Sjhb    private final class ImportsPhase extends Phase {
28089306Salfred
28183221Smarcel        public ImportsPhase() {
28289306Salfred            super(CompletionCause.IMPORTS_PHASE, new HierarchyPhase());
2839313Ssos        }
28483221Smarcel
28583221Smarcel        Env<AttrContext> env;
28683221Smarcel        ImportFilter staticImportFilter;
28789306Salfred        ImportFilter typeImportFilter;
28889306Salfred        BiConsumer<JCImport, CompletionFailure> cfHandler =
28983221Smarcel                (imp, cf) -> chk.completionError(imp.pos(), cf);
29089306Salfred
29183221Smarcel        @Override
29283221Smarcel        protected void doRunPhase(Env<AttrContext> env) {
29383221Smarcel            JCClassDecl tree = env.enclClass;
29483221Smarcel            ClassSymbol sym = tree.sym;
2959313Ssos
29683221Smarcel            // If sym is a toplevel-class, make sure any import
2979313Ssos            // clauses in its source file have been seen.
29883221Smarcel            if (sym.owner.kind == PCK) {
29983221Smarcel                resolveImports(env.toplevel, env.enclosing(TOPLEVEL));
300111119Simp                todo.append(env);
30183366Sjulian            }
30283221Smarcel
3039313Ssos            if (sym.owner.kind == TYP)
30483221Smarcel                sym.owner.complete();
30583221Smarcel        }
30683221Smarcel
30783221Smarcel        private void resolveImports(JCCompilationUnit tree, Env<AttrContext> env) {
30883221Smarcel            if (tree.starImportScope.isFilled()) {
30983221Smarcel                // we must have already processed this toplevel
31083366Sjulian                return;
31183221Smarcel            }
31283221Smarcel
3139313Ssos            ImportFilter prevStaticImportFilter = staticImportFilter;
31483221Smarcel            ImportFilter prevTypeImportFilter = typeImportFilter;
31583221Smarcel            DiagnosticPosition prevLintPos = deferredLintHandler.immediate();
31683221Smarcel            Lint prevLint = chk.setLint(lint);
31783221Smarcel            Env<AttrContext> prevEnv = this.env;
31824654Sdfr            try {
319101189Srwatson                this.env = env;
320101189Srwatson                final PackageSymbol packge = env.toplevel.packge;
321101189Srwatson                this.staticImportFilter =
322101189Srwatson                        (origin, sym) -> sym.isStatic() &&
323101706Srwatson                                         chk.importAccessible(sym, packge) &&
324101189Srwatson                                         sym.isMemberOf((TypeSymbol) origin.owner, types);
325101189Srwatson                this.typeImportFilter =
32683221Smarcel                        (origin, sym) -> sym.kind == TYP &&
32783221Smarcel                                         chk.importAccessible(sym, packge);
32883221Smarcel
3299313Ssos                // Import-on-demand java.lang.
33083221Smarcel                PackageSymbol javaLang = syms.enterPackage(names.java_lang);
33183221Smarcel                if (javaLang.members().isEmpty() && !javaLang.exists())
33283221Smarcel                    throw new FatalError(diags.fragment("fatal.err.no.java.lang"));
33383221Smarcel                importAll(make.at(tree.pos()).Import(make.QualIdent(javaLang), false), javaLang, env);
33483221Smarcel
3359313Ssos                // Process the package def and all import clauses.
33683221Smarcel                if (tree.getPackage() != null)
33724654Sdfr                    checkClassPackageClash(tree.getPackage());
33883221Smarcel
33983221Smarcel                for (JCImport imp : tree.getImports()) {
34083221Smarcel                    doImport(imp);
34183221Smarcel                }
34283221Smarcel            } finally {
34383221Smarcel                this.env = prevEnv;
34483221Smarcel                chk.setLint(prevLint);
34583221Smarcel                deferredLintHandler.setPos(prevLintPos);
34683221Smarcel                this.staticImportFilter = prevStaticImportFilter;
34783221Smarcel                this.typeImportFilter = prevTypeImportFilter;
34883221Smarcel            }
34983221Smarcel        }
35083221Smarcel
35183221Smarcel        private void checkClassPackageClash(JCPackageDecl tree) {
35283221Smarcel            // check that no class exists with same fully qualified name as
35324654Sdfr            // toplevel package
35424654Sdfr            if (checkClash && tree.pid != null) {
35583221Smarcel                Symbol p = env.toplevel.packge;
35683221Smarcel                while (p.owner != syms.rootPackage) {
35783221Smarcel                    p.owner.complete(); // enter all class members of p
35883221Smarcel                    if (syms.classes.get(p.getQualifiedName()) != null) {
35983221Smarcel                        log.error(tree.pos,
36083221Smarcel                                  "pkg.clashes.with.class.of.same.name",
36183221Smarcel                                  p);
36283221Smarcel                    }
36383221Smarcel                    p = p.owner;
36483221Smarcel                }
36583221Smarcel            }
36683221Smarcel            // process package annotations
36783221Smarcel            annotate.annotateLater(tree.annotations, env, env.toplevel.packge, null);
36883221Smarcel        }
36983221Smarcel
37083221Smarcel        private void doImport(JCImport tree) {
37183221Smarcel            dependencies.push(AttributionKind.IMPORT, tree);
37283221Smarcel            JCFieldAccess imp = (JCFieldAccess)tree.qualid;
37383221Smarcel            Name name = TreeInfo.name(imp);
37483221Smarcel
37583221Smarcel            // Create a local environment pointing to this tree to disable
37683221Smarcel            // effects of other imports in Resolve.findGlobalType
37783221Smarcel            Env<AttrContext> localEnv = env.dup(tree);
37883221Smarcel
37983221Smarcel            TypeSymbol p = attr.attribImportQualifier(tree, localEnv).tsym;
38083221Smarcel            if (name == names.asterisk) {
38183221Smarcel                // Import on demand.
38283221Smarcel                chk.checkCanonical(imp.selected);
38383221Smarcel                if (tree.staticImport)
38483221Smarcel                    importStaticAll(tree, p, env);
38583221Smarcel                else
38683221Smarcel                    importAll(tree, p, env);
38783221Smarcel            } else {
38883221Smarcel                // Named type import.
38983221Smarcel                if (tree.staticImport) {
39083221Smarcel                    importNamedStatic(tree, p, name, localEnv);
39183221Smarcel                    chk.checkCanonical(imp.selected);
39283221Smarcel                } else {
39383221Smarcel                    TypeSymbol c = attribImportType(imp, localEnv).tsym;
39483221Smarcel                    chk.checkCanonical(imp);
39583221Smarcel                    importNamed(tree.pos(), c, env, tree);
39683221Smarcel                }
39783221Smarcel            }
39883221Smarcel            dependencies.pop();
39983221Smarcel        }
40083221Smarcel
40183221Smarcel        Type attribImportType(JCTree tree, Env<AttrContext> env) {
40283221Smarcel            Assert.check(completionEnabled);
40383221Smarcel            Lint prevLint = chk.setLint(allowDeprecationOnImport ?
40483221Smarcel                    lint : lint.suppress(LintCategory.DEPRECATION));
40583221Smarcel            try {
40683221Smarcel                // To prevent deep recursion, suppress completion of some
40783221Smarcel                // types.
40883221Smarcel                completionEnabled = false;
40983221Smarcel                return attr.attribType(tree, env);
41083221Smarcel            } finally {
41183221Smarcel                completionEnabled = true;
41283221Smarcel                chk.setLint(prevLint);
41383221Smarcel            }
41483221Smarcel        }
41583221Smarcel
41683221Smarcel        /** Import all classes of a class or package on demand.
41783221Smarcel         *  @param imp           The import that is being handled.
41883221Smarcel         *  @param tsym          The class or package the members of which are imported.
41983221Smarcel         *  @param env           The env in which the imported classes will be entered.
42083221Smarcel         */
42183221Smarcel        private void importAll(JCImport imp,
42283221Smarcel                               final TypeSymbol tsym,
42383221Smarcel                               Env<AttrContext> env) {
42483221Smarcel            env.toplevel.starImportScope.importAll(types, tsym.members(), typeImportFilter, imp, cfHandler);
42583221Smarcel        }
42683221Smarcel
42783221Smarcel        /** Import all static members of a class or package on demand.
42883221Smarcel         *  @param imp           The import that is being handled.
42983221Smarcel         *  @param tsym          The class or package the members of which are imported.
43083221Smarcel         *  @param env           The env in which the imported classes will be entered.
43110355Sswallace         */
4329313Ssos        private void importStaticAll(JCImport imp,
43383221Smarcel                                     final TypeSymbol tsym,
43483221Smarcel                                     Env<AttrContext> env) {
4359313Ssos            final StarImportScope toScope = env.toplevel.starImportScope;
43683221Smarcel            final TypeSymbol origin = tsym;
43783221Smarcel
43883221Smarcel            toScope.importAll(types, origin.members(), staticImportFilter, imp, cfHandler);
43910355Sswallace        }
4409313Ssos
44183366Sjulian        /** Import statics types of a given name.  Non-types are handled in Attr.
44283221Smarcel         *  @param imp           The import that is being handled.
4439313Ssos         *  @param tsym          The class from which the name is imported.
44483221Smarcel         *  @param name          The (simple) name being imported.
44583221Smarcel         *  @param env           The environment containing the named import
44683221Smarcel         *                  scope to add to.
44783366Sjulian         */
44889306Salfred        private void importNamedStatic(final JCImport imp,
44983221Smarcel                                       final TypeSymbol tsym,
45083221Smarcel                                       final Name name,
4519313Ssos                                       final Env<AttrContext> env) {
45214331Speter            if (tsym.kind != TYP) {
45383221Smarcel                log.error(DiagnosticFlag.RECOVERABLE, imp.pos(), "static.imp.only.classes.and.interfaces");
45483366Sjulian                return;
45583221Smarcel            }
45683221Smarcel
45783221Smarcel            final NamedImportScope toScope = env.toplevel.namedImportScope;
45883221Smarcel            final Scope originMembers = tsym.members();
45983221Smarcel
46083221Smarcel            imp.importScope = toScope.importByName(types, originMembers, name, staticImportFilter, imp, cfHandler);
46183221Smarcel        }
46283366Sjulian
46383221Smarcel        /** Import given class.
46483221Smarcel         *  @param pos           Position to be used for error reporting.
46583221Smarcel         *  @param tsym          The class to be imported.
46683366Sjulian         *  @param env           The environment containing the named import
46783221Smarcel         *                  scope to add to.
46883221Smarcel         */
46983221Smarcel        private void importNamed(DiagnosticPosition pos, final Symbol tsym, Env<AttrContext> env, JCImport imp) {
47083221Smarcel            if (tsym.kind == TYP)
47183221Smarcel                imp.importScope = env.toplevel.namedImportScope.importType(tsym.owner.members(), tsym.owner.members(), tsym);
47283221Smarcel        }
47383221Smarcel
47483366Sjulian    }
47583221Smarcel
47683221Smarcel    /**Defines common utility methods used by the HierarchyPhase and HeaderPhase.
47714331Speter     */
47814331Speter    private abstract class AbstractHeaderPhase extends Phase {
47914331Speter
48014331Speter        public AbstractHeaderPhase(CompletionCause phaseName, Phase next) {
48114331Speter            super(phaseName, next);
48283366Sjulian        }
48314331Speter
484102814Siedowse        protected Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
485102814Siedowse            WriteableScope baseScope = WriteableScope.create(tree.sym);
48614331Speter            //import already entered local classes into base scope
487102814Siedowse            for (Symbol sym : env.outer.info.scope.getSymbols(NON_RECURSIVE)) {
48814331Speter                if (sym.isLocal()) {
48914331Speter                    baseScope.enter(sym);
49072543Sjlemon                }
491102814Siedowse            }
49214331Speter            //import current type-parameters into base scope
493102814Siedowse            if (tree.typarams != null)
494102814Siedowse                for (List<JCTypeParameter> typarams = tree.typarams;
495102814Siedowse                     typarams.nonEmpty();
49614331Speter                     typarams = typarams.tail)
49714331Speter                    baseScope.enter(typarams.head.type.tsym);
49814331Speter            Env<AttrContext> outer = env.outer; // the base clause can't see members of this class
49983366Sjulian            Env<AttrContext> localEnv = outer.dup(tree, outer.info.dup(baseScope));
50014331Speter            localEnv.baseClause = true;
501102814Siedowse            localEnv.outer = outer;
502102814Siedowse            localEnv.info.isSelfCall = false;
50314331Speter            return localEnv;
504102814Siedowse        }
50514331Speter
50614331Speter        /** Generate a base clause for an enum type.
50772543Sjlemon         *  @param pos              The position for trees and diagnostics, if any
508102814Siedowse         *  @param c                The class symbol of the enum
50914331Speter         */
51014331Speter        protected  JCExpression enumBase(int pos, ClassSymbol c) {
511102814Siedowse            JCExpression result = make.at(pos).
512102814Siedowse                TypeApply(make.QualIdent(syms.enumSym),
513102814Siedowse                          List.<JCExpression>of(make.Type(c.type)));
51414331Speter            return result;
51514331Speter        }
51614331Speter
51783366Sjulian        protected Type modelMissingTypes(Type t, final JCExpression tree, final boolean interfaceExpected) {
51814331Speter            if (!t.hasTag(ERROR))
519102814Siedowse                return t;
520102814Siedowse
52114331Speter            return new ErrorType(t.getOriginalType(), t.tsym) {
522102814Siedowse                private Type modelType;
52314331Speter
52414331Speter                @Override
52572543Sjlemon                public Type getModelType() {
526102814Siedowse                    if (modelType == null)
52714331Speter                        modelType = new Synthesizer(getOriginalType(), interfaceExpected).visit(tree);
528102814Siedowse                    return modelType;
529102814Siedowse                }
530102814Siedowse            };
53114331Speter        }
53214331Speter            // where:
53314331Speter            private class Synthesizer extends JCTree.Visitor {
53483366Sjulian                Type originalType;
53514331Speter                boolean interfaceExpected;
536102814Siedowse                List<ClassSymbol> synthesizedSymbols = List.nil();
537102814Siedowse                Type result;
53814331Speter
539102814Siedowse                Synthesizer(Type originalType, boolean interfaceExpected) {
54014331Speter                    this.originalType = originalType;
54114331Speter                    this.interfaceExpected = interfaceExpected;
54272543Sjlemon                }
543102814Siedowse
54414331Speter                Type visit(JCTree tree) {
545102814Siedowse                    tree.accept(this);
546102814Siedowse                    return result;
547102814Siedowse                }
54814331Speter
54914331Speter                List<Type> visit(List<? extends JCTree> trees) {
55014331Speter                    ListBuffer<Type> lb = new ListBuffer<>();
55183366Sjulian                    for (JCTree t: trees)
55214331Speter                        lb.append(visit(t));
553102814Siedowse                    return lb.toList();
554102814Siedowse                }
55514331Speter
556102814Siedowse                @Override
55714331Speter                public void visitTree(JCTree tree) {
55814331Speter                    result = syms.errType;
55972543Sjlemon                }
560102814Siedowse
56114331Speter                @Override
562102814Siedowse                public void visitIdent(JCIdent tree) {
563102814Siedowse                    if (!tree.type.hasTag(ERROR)) {
564102814Siedowse                        result = tree.type;
56514331Speter                    } else {
56614331Speter                        result = synthesizeClass(tree.name, syms.unnamedPackage).type;
56714331Speter                    }
56883366Sjulian                }
56914331Speter
570102814Siedowse                @Override
571102814Siedowse                public void visitSelect(JCFieldAccess tree) {
57214331Speter                    if (!tree.type.hasTag(ERROR)) {
573102814Siedowse                        result = tree.type;
57414331Speter                    } else {
57514331Speter                        Type selectedType;
57672543Sjlemon                        boolean prev = interfaceExpected;
577102814Siedowse                        try {
57814331Speter                            interfaceExpected = false;
579102814Siedowse                            selectedType = visit(tree.selected);
580102814Siedowse                        } finally {
581102814Siedowse                            interfaceExpected = prev;
58214331Speter                        }
58314331Speter                        ClassSymbol c = synthesizeClass(tree.name, selectedType.tsym);
58414331Speter                        result = c.type;
58583366Sjulian                    }
58614331Speter                }
587102814Siedowse
588102814Siedowse                @Override
58914331Speter                public void visitTypeApply(JCTypeApply tree) {
590102814Siedowse                    if (!tree.type.hasTag(ERROR)) {
591102814Siedowse                        result = tree.type;
592102814Siedowse                    } else {
593102814Siedowse                        ClassType clazzType = (ClassType) visit(tree.clazz);
594102814Siedowse                        if (synthesizedSymbols.contains(clazzType.tsym))
595102814Siedowse                            synthesizeTyparams((ClassSymbol) clazzType.tsym, tree.arguments.size());
596102814Siedowse                        final List<Type> actuals = visit(tree.arguments);
59714331Speter                        result = new ErrorType(tree.type, clazzType.tsym) {
59814331Speter                            @Override @DefinedBy(Api.LANGUAGE_MODEL)
59972543Sjlemon                            public List<Type> getTypeArguments() {
600102814Siedowse                                return actuals;
60114331Speter                            }
602102814Siedowse                        };
603102814Siedowse                    }
604102814Siedowse                }
605102814Siedowse
60614331Speter                ClassSymbol synthesizeClass(Name name, Symbol owner) {
60714331Speter                    int flags = interfaceExpected ? INTERFACE : 0;
60814331Speter                    ClassSymbol c = new ClassSymbol(flags, name, owner);
60983366Sjulian                    c.members_field = new Scope.ErrorScope(c);
61014331Speter                    c.type = new ErrorType(originalType, c) {
611102814Siedowse                        @Override @DefinedBy(Api.LANGUAGE_MODEL)
612102814Siedowse                        public List<Type> getTypeArguments() {
61314331Speter                            return typarams_field;
614102814Siedowse                        }
615102814Siedowse                    };
616102814Siedowse                    synthesizedSymbols = synthesizedSymbols.prepend(c);
617102814Siedowse                    return c;
618102814Siedowse                }
619102814Siedowse
620102814Siedowse                void synthesizeTyparams(ClassSymbol sym, int n) {
62114331Speter                    ClassType ct = (ClassType) sym.type;
62214331Speter                    Assert.check(ct.typarams_field.isEmpty());
62372543Sjlemon                    if (n == 1) {
624102814Siedowse                        TypeVar v = new TypeVar(names.fromString("T"), sym, syms.botType);
62514331Speter                        ct.typarams_field = ct.typarams_field.prepend(v);
626102814Siedowse                    } else {
627102814Siedowse                        for (int i = n; i > 0; i--) {
628102814Siedowse                            TypeVar v = new TypeVar(names.fromString("T" + i), sym,
629102814Siedowse                                                    syms.botType);
63014331Speter                            ct.typarams_field = ct.typarams_field.prepend(v);
63114331Speter                        }
63214331Speter                    }
63383366Sjulian                }
63414331Speter            }
635102814Siedowse
636102814Siedowse        protected void attribSuperTypes(Env<AttrContext> env, Env<AttrContext> baseEnv) {
63714331Speter            JCClassDecl tree = env.enclClass;
638102814Siedowse            ClassSymbol sym = tree.sym;
63914331Speter            ClassType ct = (ClassType)sym.type;
64014331Speter            // Determine supertype.
64172543Sjlemon            Type supertype;
642102814Siedowse            JCExpression extending;
643102814Siedowse
64414331Speter            if (tree.extending != null) {
645102814Siedowse                extending = clearTypeParams(tree.extending);
646102814Siedowse                dependencies.push(AttributionKind.EXTENDS, tree.extending);
647102814Siedowse                try {
648102814Siedowse                    supertype = attr.attribBase(extending, baseEnv,
64914331Speter                                                true, false, true);
65014331Speter                } finally {
65114331Speter                    dependencies.pop();
65283366Sjulian                }
65314331Speter            } else {
654102814Siedowse                extending = null;
655102814Siedowse                supertype = ((tree.mods.flags & Flags.ENUM) != 0)
65614331Speter                ? attr.attribBase(enumBase(tree.pos, sym), baseEnv,
657102814Siedowse                                  true, false, false)
65814331Speter                : (sym.fullname == names.java_lang_Object)
65914331Speter                ? Type.noType
66072543Sjlemon                : syms.objectType;
661102814Siedowse            }
66214331Speter            ct.supertype_field = modelMissingTypes(supertype, extending, false);
66314331Speter
664102814Siedowse            // Determine interfaces.
665102814Siedowse            ListBuffer<Type> interfaces = new ListBuffer<>();
666102814Siedowse            ListBuffer<Type> all_interfaces = null; // lazy init
66714331Speter            List<JCExpression> interfaceTrees = tree.implementing;
66814331Speter            for (JCExpression iface : interfaceTrees) {
66949662Smarcel                iface = clearTypeParams(iface);
67083366Sjulian                dependencies.push(AttributionKind.IMPLEMENTS, iface);
67149662Smarcel                try {
672102814Siedowse                    Type it = attr.attribBase(iface, baseEnv, false, true, true);
673102814Siedowse                    if (it.hasTag(CLASS)) {
67449662Smarcel                        interfaces.append(it);
675102814Siedowse                        if (all_interfaces != null) all_interfaces.append(it);
676102814Siedowse                    } else {
677102814Siedowse                        if (all_interfaces == null)
678102814Siedowse                            all_interfaces = new ListBuffer<Type>().appendList(interfaces);
679102814Siedowse                        all_interfaces.append(modelMissingTypes(it, iface, true));
680102814Siedowse
681102814Siedowse                    }
68249662Smarcel                } finally {
68349662Smarcel                    dependencies.pop();
68472543Sjlemon                }
685102814Siedowse            }
68649662Smarcel
687102814Siedowse            if ((sym.flags_field & ANNOTATION) != 0) {
688102814Siedowse                ct.interfaces_field = List.of(syms.annotationType);
689102814Siedowse                ct.all_interfaces_field = ct.interfaces_field;
690102814Siedowse            }  else {
69149662Smarcel                ct.interfaces_field = interfaces.toList();
69249788Smarcel                ct.all_interfaces_field = (all_interfaces == null)
69368201Sobrien                        ? ct.interfaces_field : all_interfaces.toList();
69453713Smarcel            }
69583366Sjulian        }
69683366Sjulian            //where:
69753713Smarcel            protected JCExpression clearTypeParams(JCExpression superType) {
69853713Smarcel                return superType;
69953713Smarcel            }
70053713Smarcel    }
70153713Smarcel
70283366Sjulian    private final class HierarchyPhase extends AbstractHeaderPhase {
70353713Smarcel
70468201Sobrien        public HierarchyPhase() {
70563285Smarcel            super(CompletionCause.HIERARCHY_PHASE, new HeaderPhase());
70663285Smarcel        }
70783366Sjulian
70883366Sjulian        @Override
70963285Smarcel        protected void doRunPhase(Env<AttrContext> env) {
71063285Smarcel            JCClassDecl tree = env.enclClass;
71163285Smarcel            ClassSymbol sym = tree.sym;
71263285Smarcel            ClassType ct = (ClassType)sym.type;
71363285Smarcel
71463285Smarcel            Env<AttrContext> baseEnv = baseEnv(tree, env);
71563285Smarcel
71663285Smarcel            attribSuperTypes(env, baseEnv);
71783366Sjulian
71863285Smarcel            if (sym.fullname == names.java_lang_Object) {
71963285Smarcel                if (tree.extending != null) {
72063285Smarcel                    chk.checkNonCyclic(tree.extending.pos(),
72183366Sjulian                                       ct.supertype_field);
72283366Sjulian                    ct.supertype_field = Type.noType;
72363285Smarcel                }
72463285Smarcel                else if (tree.implementing.nonEmpty()) {
72563285Smarcel                    chk.checkNonCyclic(tree.implementing.head.pos(),
72663285Smarcel                                       ct.interfaces_field.head);
72763285Smarcel                    ct.interfaces_field = List.nil();
72863285Smarcel                }
72963285Smarcel            }
73063285Smarcel
73183366Sjulian            // Annotations.
73263285Smarcel            // In general, we cannot fully process annotations yet,  but we
73372538Sjlemon            // can attribute the annotation types and then check to see if the
73472538Sjlemon            // @Deprecated annotation is present.
73583366Sjulian            attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
73672538Sjlemon            if (hasDeprecatedAnnotation(tree.mods.annotations))
73772538Sjlemon                sym.flags_field |= DEPRECATED;
738111798Sdes
739111798Sdes            chk.checkNonCyclicDecl(tree);
74073286Sadrian        }
74173286Sadrian            //where:
74273286Sadrian            protected JCExpression clearTypeParams(JCExpression superType) {
74373286Sadrian                switch (superType.getTag()) {
74472538Sjlemon                    case TYPEAPPLY:
745111798Sdes                        return ((JCTypeApply) superType).clazz;
74673286Sadrian                }
74772538Sjlemon
748111798Sdes                return superType;
749111798Sdes            }
75072538Sjlemon
751111798Sdes            /**
752111798Sdes             * Check if a list of annotations contains a reference to
75372538Sjlemon             * java.lang.Deprecated.
754111798Sdes             **/
75572538Sjlemon            private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
75672538Sjlemon                for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
75772538Sjlemon                    JCAnnotation a = al.head;
75872538Sjlemon                    if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
75972538Sjlemon                        return true;
76072538Sjlemon                }
76172538Sjlemon                return false;
76272538Sjlemon            }
76373286Sadrian    }
76473286Sadrian
76572538Sjlemon    private final class HeaderPhase extends AbstractHeaderPhase {
76672538Sjlemon
76772538Sjlemon        public HeaderPhase() {
76872538Sjlemon            super(CompletionCause.HEADER_PHASE, new MembersPhase());
76972538Sjlemon        }
77072538Sjlemon
77173286Sadrian        @Override
77273286Sadrian        protected void doRunPhase(Env<AttrContext> env) {
77372538Sjlemon            JCClassDecl tree = env.enclClass;
77472538Sjlemon            ClassSymbol sym = tree.sym;
77572538Sjlemon            ClassType ct = (ClassType)sym.type;
77672538Sjlemon
77773286Sadrian            // create an environment for evaluating the base clauses
77872538Sjlemon            Env<AttrContext> baseEnv = baseEnv(tree, env);
77972538Sjlemon
78072538Sjlemon            if (tree.extending != null)
78172538Sjlemon                annotate.queueScanTreeAndTypeAnnotate(tree.extending, baseEnv, sym, tree.pos());
78272538Sjlemon            for (JCExpression impl : tree.implementing)
78372538Sjlemon                annotate.queueScanTreeAndTypeAnnotate(impl, baseEnv, sym, tree.pos());
78472538Sjlemon            annotate.flush();
785111798Sdes
78672538Sjlemon            attribSuperTypes(env, baseEnv);
787111798Sdes
78872538Sjlemon            Set<Type> interfaceSet = new HashSet<>();
789111798Sdes
79072538Sjlemon            for (JCExpression iface : tree.implementing) {
791111798Sdes                Type it = iface.type;
79272538Sjlemon                if (it.hasTag(CLASS))
793111798Sdes                    chk.checkNotRepeated(iface.pos(), types.erasure(it), interfaceSet);
79472538Sjlemon            }
79572538Sjlemon
79683366Sjulian            annotate.annotateLater(tree.mods.annotations, baseEnv,
79772538Sjlemon                        sym, tree.pos());
79872538Sjlemon
79972538Sjlemon            attr.attribTypeVariables(tree.typarams, baseEnv);
80083366Sjulian            for (JCTypeParameter tp : tree.typarams)
80172538Sjlemon                annotate.queueScanTreeAndTypeAnnotate(tp, baseEnv, sym, tree.pos());
80283221Smarcel
80372538Sjlemon            // check that no package exists with same fully qualified name,
80472538Sjlemon            // but admit classes in the unnamed package which have the same
80572538Sjlemon            // name as a top-level package.
80683366Sjulian            if (checkClash &&
80772538Sjlemon                sym.owner.kind == PCK && sym.owner != syms.unnamedPackage &&
80872538Sjlemon                syms.packageExists(sym.fullname)) {
80972538Sjlemon                log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), sym);
81083366Sjulian            }
81172538Sjlemon            if (sym.owner.kind == PCK && (sym.flags_field & PUBLIC) == 0 &&
81272538Sjlemon                !env.toplevel.sourcefile.isNameCompatible(sym.name.toString(),JavaFileObject.Kind.SOURCE)) {
81372538Sjlemon                sym.flags_field |= AUXILIARY;
81472538Sjlemon            }
81572538Sjlemon        }
81683366Sjulian    }
81772538Sjlemon
81883221Smarcel    /** Enter member fields and methods of a class
81983221Smarcel     */
82083221Smarcel    private final class MembersPhase extends Phase {
82183221Smarcel
82283221Smarcel        public MembersPhase() {
82383221Smarcel            super(CompletionCause.MEMBERS_PHASE, null);
82483221Smarcel        }
82583221Smarcel
82683221Smarcel        @Override
82783221Smarcel        protected void doRunPhase(Env<AttrContext> env) {
82883221Smarcel            JCClassDecl tree = env.enclClass;
82983221Smarcel            ClassSymbol sym = tree.sym;
83083221Smarcel            ClassType ct = (ClassType)sym.type;
83183221Smarcel
83283221Smarcel            // Add default constructor if needed.
83383221Smarcel            if ((sym.flags() & INTERFACE) == 0 &&
83483221Smarcel                !TreeInfo.hasConstructors(tree.defs)) {
83583221Smarcel                List<Type> argtypes = List.nil();
83683221Smarcel                List<Type> typarams = List.nil();
83783221Smarcel                List<Type> thrown = List.nil();
83883221Smarcel                long ctorFlags = 0;
83983221Smarcel                boolean based = false;
84083221Smarcel                boolean addConstructor = true;
84183221Smarcel                JCNewClass nc = null;
84283221Smarcel                if (sym.name.isEmpty()) {
84383221Smarcel                    nc = (JCNewClass)env.next.tree;
84483221Smarcel                    if (nc.constructor != null) {
84583221Smarcel                        addConstructor = nc.constructor.kind != ERR;
84683221Smarcel                        Type superConstrType = types.memberType(sym.type,
84783221Smarcel                                                                nc.constructor);
84883221Smarcel                        argtypes = superConstrType.getParameterTypes();
84983221Smarcel                        typarams = superConstrType.getTypeArguments();
85083221Smarcel                        ctorFlags = nc.constructor.flags() & VARARGS;
85183221Smarcel                        if (nc.encl != null) {
85283221Smarcel                            argtypes = argtypes.prepend(nc.encl.type);
85383221Smarcel                            based = true;
85483221Smarcel                        }
85583221Smarcel                        thrown = superConstrType.getThrownTypes();
85683221Smarcel                    }
85783221Smarcel                }
85883221Smarcel                if (addConstructor) {
85983221Smarcel                    MethodSymbol basedConstructor = nc != null ?
86083221Smarcel                            (MethodSymbol)nc.constructor : null;
86183221Smarcel                    JCTree constrDef = DefaultConstructor(make.at(tree.pos), sym,
86283221Smarcel                                                        basedConstructor,
86383221Smarcel                                                        typarams, argtypes, thrown,
86483221Smarcel                                                        ctorFlags, based);
86583221Smarcel                    tree.defs = tree.defs.prepend(constrDef);
86683221Smarcel                }
86783221Smarcel            }
86883221Smarcel
86983221Smarcel            // enter symbols for 'this' into current scope.
87083221Smarcel            VarSymbol thisSym =
87183221Smarcel                new VarSymbol(FINAL | HASINIT, names._this, sym.type, sym);
87283221Smarcel            thisSym.pos = Position.FIRSTPOS;
87383221Smarcel            env.info.scope.enter(thisSym);
87483221Smarcel            // if this is a class, enter symbol for 'super' into current scope.
87583221Smarcel            if ((sym.flags_field & INTERFACE) == 0 &&
87683221Smarcel                    ct.supertype_field.hasTag(CLASS)) {
87783221Smarcel                VarSymbol superSym =
87883221Smarcel                    new VarSymbol(FINAL | HASINIT, names._super,
87983221Smarcel                                  ct.supertype_field, sym);
88083221Smarcel                superSym.pos = Position.FIRSTPOS;
88183221Smarcel                env.info.scope.enter(superSym);
88283221Smarcel            }
88383221Smarcel
88483221Smarcel            finishClass(tree, env);
88583221Smarcel
88683221Smarcel            if (allowTypeAnnos) {
88783221Smarcel                typeAnnotations.organizeTypeAnnotationsSignatures(env, (JCClassDecl)env.tree);
88883221Smarcel                typeAnnotations.validateTypeAnnotationsSignatures(env, (JCClassDecl)env.tree);
88983221Smarcel            }
89083221Smarcel        }
89183221Smarcel
89283221Smarcel        /** Enter members for a class.
89383221Smarcel         */
89483221Smarcel        void finishClass(JCClassDecl tree, Env<AttrContext> env) {
89583221Smarcel            if ((tree.mods.flags & Flags.ENUM) != 0 &&
89683221Smarcel                (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {
89783221Smarcel                addEnumMembers(tree, env);
89883221Smarcel            }
89983221Smarcel            memberEnter.memberEnter(tree.defs, env);
90083221Smarcel
90183221Smarcel            if (tree.sym.isAnnotationType()) {
90283221Smarcel                Assert.check(tree.sym.isCompleted());
90383221Smarcel                tree.sym.setAnnotationTypeMetadata(new AnnotationTypeMetadata(tree.sym, annotate.annotationTypeSourceCompleter()));
90483221Smarcel            }
90583221Smarcel        }
90683221Smarcel
90783221Smarcel        /** Add the implicit members for an enum type
90883221Smarcel         *  to the symbol table.
90983221Smarcel         */
91083221Smarcel        private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) {
91183221Smarcel            JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass));
91283221Smarcel
91383221Smarcel            // public static T[] values() { return ???; }
91483221Smarcel            JCMethodDecl values = make.
91583221Smarcel                MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
91683221Smarcel                          names.values,
91783221Smarcel                          valuesType,
91883221Smarcel                          List.<JCTypeParameter>nil(),
91983221Smarcel                          List.<JCVariableDecl>nil(),
92083221Smarcel                          List.<JCExpression>nil(), // thrown
92183221Smarcel                          null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
92283221Smarcel                          null);
92383221Smarcel            memberEnter.memberEnter(values, env);
92483221Smarcel
92583221Smarcel            // public static T valueOf(String name) { return ???; }
92683221Smarcel            JCMethodDecl valueOf = make.
92783221Smarcel                MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
92883221Smarcel                          names.valueOf,
92983221Smarcel                          make.Type(tree.sym.type),
93083221Smarcel                          List.<JCTypeParameter>nil(),
93183221Smarcel                          List.of(make.VarDef(make.Modifiers(Flags.PARAMETER |
93283366Sjulian                                                             Flags.MANDATED),
93383221Smarcel                                                names.fromString("name"),
934107680Siedowse                                                make.Type(syms.stringType), null)),
935107680Siedowse                          List.<JCExpression>nil(), // thrown
93683221Smarcel                          null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
937102872Siedowse                          null);
93883221Smarcel            memberEnter.memberEnter(valueOf, env);
93983221Smarcel        }
94083221Smarcel
94183221Smarcel    }
942102872Siedowse
94383221Smarcel/* ***************************************************************************
94483221Smarcel * tree building
945102872Siedowse ****************************************************************************/
94683221Smarcel
94783221Smarcel    /** Generate default constructor for given class. For classes different
948102872Siedowse     *  from java.lang.Object, this is:
94983221Smarcel     *
95083221Smarcel     *    c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
951102872Siedowse     *      super(x_0, ..., x_n)
95283366Sjulian     *    }
95383366Sjulian     *
95483221Smarcel     *  or, if based == true:
95583366Sjulian     *
95683221Smarcel     *    c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
95783366Sjulian     *      x_0.super(x_1, ..., x_n)
95883221Smarcel     *    }
95983366Sjulian     *
96083221Smarcel     *  @param make     The tree factory.
96183366Sjulian     *  @param c        The class owning the default constructor.
96283221Smarcel     *  @param argtypes The parameter types of the constructor.
96383366Sjulian     *  @param thrown   The thrown exceptions of the constructor.
96483221Smarcel     *  @param based    Is first parameter a this$n?
96583366Sjulian     */
96683221Smarcel    JCTree DefaultConstructor(TreeMaker make,
96783366Sjulian                            ClassSymbol c,
96883221Smarcel                            MethodSymbol baseInit,
96983221Smarcel                            List<Type> typarams,
97083221Smarcel                            List<Type> argtypes,
971102872Siedowse                            List<Type> thrown,
97283221Smarcel                            long flags,
973102872Siedowse                            boolean based) {
97483221Smarcel        JCTree result;
975102872Siedowse        if ((c.flags() & ENUM) != 0 &&
97683221Smarcel            (types.supertype(c.type).tsym == syms.enumSym)) {
977102872Siedowse            // constructors of true enums are private
97883221Smarcel            flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR;
979102872Siedowse        } else
980102872Siedowse            flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR;
98183221Smarcel        if (c.name.isEmpty()) {
982107680Siedowse            flags |= ANONCONSTR;
983111797Sdes        }
984107680Siedowse        Type mType = new MethodType(argtypes, null, thrown, c);
985107680Siedowse        Type initType = typarams.nonEmpty() ?
986107680Siedowse            new ForAll(typarams, mType) :
987107680Siedowse            mType;
988107680Siedowse        MethodSymbol init = new MethodSymbol(flags, names.init,
989107680Siedowse                initType, c);
990107680Siedowse        init.params = createDefaultConstructorParams(make, baseInit, init,
991107680Siedowse                argtypes, based);
992111797Sdes        List<JCVariableDecl> params = make.Params(argtypes, init);
993107680Siedowse        List<JCStatement> stats = List.nil();
994107680Siedowse        if (c.type != syms.objectType) {
995107680Siedowse            stats = stats.prepend(SuperCall(make, typarams, params, based));
996111797Sdes        }
997107680Siedowse        result = make.MethodDef(init, make.Block(0, stats));
998107680Siedowse        return result;
999107680Siedowse    }
1000107680Siedowse
1001107680Siedowse    private List<VarSymbol> createDefaultConstructorParams(
1002107680Siedowse            TreeMaker make,
1003107680Siedowse            MethodSymbol baseInit,
1004107680Siedowse            MethodSymbol init,
1005111797Sdes            List<Type> argtypes,
1006107680Siedowse            boolean based) {
1007107680Siedowse        List<VarSymbol> initParams = null;
1008107680Siedowse        List<Type> argTypesList = argtypes;
1009107680Siedowse        if (based) {
1010107680Siedowse            /*  In this case argtypes will have an extra type, compared to baseInit,
1011107680Siedowse             *  corresponding to the type of the enclosing instance i.e.:
1012107680Siedowse             *
101383221Smarcel             *  Inner i = outer.new Inner(1){}
1014102872Siedowse             *
101583221Smarcel             *  in the above example argtypes will be (Outer, int) and baseInit
101683221Smarcel             *  will have parameter's types (int). So in this case we have to add
101783221Smarcel             *  first the extra type in argtypes and then get the names of the
101883221Smarcel             *  parameters from baseInit.
101983221Smarcel             */
102083221Smarcel            initParams = List.nil();
102183221Smarcel            VarSymbol param = new VarSymbol(PARAMETER, make.paramName(0), argtypes.head, init);
102289319Salfred            initParams = initParams.append(param);
102389319Salfred            argTypesList = argTypesList.tail;
102489319Salfred        }
102589306Salfred        if (baseInit != null && baseInit.params != null &&
102689306Salfred            baseInit.params.nonEmpty() && argTypesList.nonEmpty()) {
102783221Smarcel            initParams = (initParams == null) ? List.<VarSymbol>nil() : initParams;
102889306Salfred            List<VarSymbol> baseInitParams = baseInit.params;
102989306Salfred            while (baseInitParams.nonEmpty() && argTypesList.nonEmpty()) {
103083221Smarcel                VarSymbol param = new VarSymbol(baseInitParams.head.flags() | PARAMETER,
1031102872Siedowse                        baseInitParams.head.name, argTypesList.head, init);
103283221Smarcel                initParams = initParams.append(param);
103383221Smarcel                baseInitParams = baseInitParams.tail;
103483221Smarcel                argTypesList = argTypesList.tail;
103583221Smarcel            }
103683221Smarcel        }
103783221Smarcel        return initParams;
103883366Sjulian    }
103983221Smarcel
104083221Smarcel    /** Generate call to superclass constructor. This is:
104183221Smarcel     *
104283221Smarcel     *    super(id_0, ..., id_n)
104383221Smarcel     *
104483221Smarcel     * or, if based == true
104583221Smarcel     *
104683221Smarcel     *    id_0.super(id_1,...,id_n)
104783221Smarcel     *
104883221Smarcel     *  where id_0, ..., id_n are the names of the given parameters.
104983221Smarcel     *
105083366Sjulian     *  @param make    The tree factory
105183221Smarcel     *  @param params  The parameters that need to be passed to super
105283221Smarcel     *  @param typarams  The type parameters that need to be passed to super
105383221Smarcel     *  @param based   Is first parameter a this$n?
105483221Smarcel     */
105583366Sjulian    JCExpressionStatement SuperCall(TreeMaker make,
105683221Smarcel                   List<Type> typarams,
105783221Smarcel                   List<JCVariableDecl> params,
1058102872Siedowse                   boolean based) {
105983221Smarcel        JCExpression meth;
106083221Smarcel        if (based) {
106183221Smarcel            meth = make.Select(make.Ident(params.head), names._super);
106283221Smarcel            params = params.tail;
106383221Smarcel        } else {
106483221Smarcel            meth = make.Ident(names._super);
106583221Smarcel        }
106683221Smarcel        List<JCExpression> typeargs = typarams.nonEmpty() ? make.Types(typarams) : null;
106799687Srobert        return make.Exec(make.Apply(typeargs, meth, make.Idents(params)));
1068111797Sdes    }
106983221Smarcel}
107083221Smarcel