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