# HG changeset patch # User pgovereau # Date 1398200874 14400 # Node ID dfb8f11542fc15ddf0ec5ede853bcadcdd3a8819 # Parent d8a1180faaa91d8be7f618d3209734b0a2f0e784 8034245: Refactor TopLevel tree node. Summary: Added JCPackageDecl to JCTree to store package-level information. Reviewed-by: jjg, jlahoda diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java --- a/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java Tue Apr 22 17:07:54 2014 -0400 @@ -41,6 +41,12 @@ public interface CompilationUnitTree extends Tree { List getPackageAnnotations(); ExpressionTree getPackageName(); + + /** + * Return the PackageTree associated with this compilation unit. + * @since 1.9 + */ + PackageTree getPackage(); List getImports(); List getTypeDecls(); JavaFileObject getSourceFile(); diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/source/tree/PackageTree.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/source/tree/PackageTree.java Tue Apr 22 17:07:54 2014 -0400 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.source.tree; + +import java.util.List; + +/** + * Represents the package declaration. + * + * @jls sections 7.3, and 7.4 + * + * @author Paul Govereau + * @since 1.9 + */ +@jdk.Exported +public interface PackageTree extends Tree { + List getAnnotations(); + ExpressionTree getPackageName(); +} diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/source/tree/Tree.java --- a/langtools/src/share/classes/com/sun/source/tree/Tree.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/source/tree/Tree.java Tue Apr 22 17:07:54 2014 -0400 @@ -208,6 +208,12 @@ LAMBDA_EXPRESSION(LambdaExpressionTree.class), /** + * Used for instances of {@link PackageTree}. + * @since 1.9 + */ + PACKAGE(PackageTree.class), + + /** * Used for instances of {@link ParenthesizedTree}. */ PARENTHESIZED(ParenthesizedTree.class), diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java --- a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java Tue Apr 22 17:07:54 2014 -0400 @@ -88,6 +88,7 @@ R visitNewArray(NewArrayTree node, P p); R visitNewClass(NewClassTree node, P p); R visitLambdaExpression(LambdaExpressionTree node, P p); + R visitPackage(PackageTree node, P p); R visitParenthesized(ParenthesizedTree node, P p); R visitReturn(ReturnTree node, P p); R visitMemberSelect(MemberSelectTree node, P p); diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java --- a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Tue Apr 22 17:07:54 2014 -0400 @@ -65,6 +65,10 @@ return defaultAction(node, p); } + public R visitPackage(PackageTree node, P p) { + return defaultAction(node, p); + } + public R visitImport(ImportTree node, P p) { return defaultAction(node, p); } diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/source/util/TreeScanner.java --- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java Tue Apr 22 17:07:54 2014 -0400 @@ -114,13 +114,18 @@ ****************************************************************************/ public R visitCompilationUnit(CompilationUnitTree node, P p) { - R r = scan(node.getPackageAnnotations(), p); - r = scanAndReduce(node.getPackageName(), p, r); + R r = scan(node.getPackage(), p); r = scanAndReduce(node.getImports(), p, r); r = scanAndReduce(node.getTypeDecls(), p, r); return r; } + public R visitPackage(PackageTree node, P p) { + R r = scan(node.getAnnotations(), p); + r = scanAndReduce(node.getPackageName(), p, r); + return r; + } + public R visitImport(ImportTree node, P p) { return scan(node.getQualifiedIdentifier(), p); } diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/doclint/Checker.java --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Tue Apr 22 17:07:54 2014 -0400 @@ -75,6 +75,7 @@ import com.sun.source.doctree.UnknownInlineTagTree; import com.sun.source.doctree.ValueTree; import com.sun.source.doctree.VersionTree; +import com.sun.source.tree.Tree; import com.sun.source.util.DocTreePath; import com.sun.source.util.DocTreePathScanner; import com.sun.source.util.TreePath; @@ -145,8 +146,8 @@ boolean isOverridingMethod = !env.currOverriddenMethods.isEmpty(); - if (p.getLeaf() == p.getCompilationUnit()) { - // If p points to a compilation unit, the implied declaration is the + if (p.getLeaf().getKind() == Tree.Kind.PACKAGE) { + // If p points to a package, the implied declaration is the // package declaration (if any) for the compilation unit. // Handle this case specially, because doc comments are only // expected in package-info files. diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/doclint/DocLint.java --- a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java Tue Apr 22 17:07:54 2014 -0400 @@ -42,6 +42,7 @@ import com.sun.source.doctree.DocCommentTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.PackageTree; import com.sun.source.tree.MethodTree; import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; @@ -346,13 +347,10 @@ abstract void visitDecl(Tree tree, Name name); @Override - public Void visitCompilationUnit(CompilationUnitTree tree, Void ignore) { - if (tree.getPackageName() != null) { - visitDecl(tree, null); - } - return super.visitCompilationUnit(tree, ignore); + public Void visitPackage(PackageTree tree, Void ignore) { + visitDecl(tree, null); + return super.visitPackage(tree, ignore); } - @Override public Void visitClass(ClassTree tree, Void ignore) { visitDecl(tree, tree.getSimpleName()); diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Tue Apr 22 17:07:54 2014 -0400 @@ -288,15 +288,16 @@ boolean addEnv = false; boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE); - if (tree.pid != null) { - tree.packge = syms.enterPackage(TreeInfo.fullName(tree.pid)); - if (tree.packageAnnotations.nonEmpty() - || pkginfoOpt == PkgInfo.ALWAYS - || tree.docComments != null) { + JCPackageDecl pd = tree.getPackage(); + if (pd != null) { + tree.packge = pd.packge = syms.enterPackage(TreeInfo.fullName(pd.pid)); + if ( pd.annotations.nonEmpty() + || pkginfoOpt == PkgInfo.ALWAYS + || tree.docComments != null) { if (isPkgInfo) { addEnv = true; - } else if (tree.packageAnnotations.nonEmpty()){ - log.error(tree.packageAnnotations.head.pos(), + } else if (pd.annotations.nonEmpty()) { + log.error(pd.annotations.head.pos(), "pkg.annotations.sb.in.package-info.java"); } } @@ -305,26 +306,20 @@ } tree.packge.complete(); // Find all classes in package. Env topEnv = topLevelEnv(tree); + Env packageEnv = isPkgInfo ? topEnv.dup(pd) : null; // Save environment of package-info.java file. if (isPkgInfo) { Env env0 = typeEnvs.get(tree.packge); - if (env0 == null) { - typeEnvs.put(tree.packge, topEnv); - } else { + if (env0 != null) { JCCompilationUnit tree0 = env0.toplevel; if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) { - log.warning(tree.pid != null ? tree.pid.pos() - : null, + log.warning(pd != null ? pd.pid.pos() : null, "pkg-info.already.seen", tree.packge); - if (addEnv || (tree0.packageAnnotations.isEmpty() && - tree.docComments != null && - tree.docComments.hasComment(tree))) { - typeEnvs.put(tree.packge, topEnv); - } } } + typeEnvs.put(tree.packge, packageEnv); for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS; @@ -339,7 +334,7 @@ } classEnter(tree.defs, topEnv); if (addEnv) { - todo.append(topEnv); + todo.append(packageEnv); } log.useSource(prev); result = null; diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Apr 22 17:07:54 2014 -0400 @@ -388,6 +388,10 @@ super.scan(tree); } } + + public void visitPackageDef(JCPackageDecl tree) { + // Do nothing for PackageDecl + } } /** @@ -723,10 +727,6 @@ } } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ @@ -1289,10 +1289,6 @@ } } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ @@ -2357,10 +2353,6 @@ tree.underlyingType.accept(this); } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ @@ -2677,10 +2669,6 @@ } } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Apr 22 17:07:54 2014 -0400 @@ -2408,39 +2408,39 @@ return trees; } - public void visitTopLevel(JCCompilationUnit tree) { - if (needPackageInfoClass(tree)) { - Name name = names.package_info; - long flags = Flags.ABSTRACT | Flags.INTERFACE; - if (target.isPackageInfoSynthetic()) - // package-info is marked SYNTHETIC in JDK 1.6 and later releases - flags = flags | Flags.SYNTHETIC; - JCClassDecl packageAnnotationsClass - = make.ClassDef(make.Modifiers(flags, - tree.packageAnnotations), - name, List.nil(), - null, List.nil(), List.nil()); - ClassSymbol c = tree.packge.package_info; - c.flags_field |= flags; - c.setAttributes(tree.packge); - ClassType ctype = (ClassType) c.type; - ctype.supertype_field = syms.objectType; - ctype.interfaces_field = List.nil(); - packageAnnotationsClass.sym = c; - - translated.append(packageAnnotationsClass); - } + public void visitPackageDef(JCPackageDecl tree) { + if (!needPackageInfoClass(tree)) + return; + + Name name = names.package_info; + long flags = Flags.ABSTRACT | Flags.INTERFACE; + if (target.isPackageInfoSynthetic()) + // package-info is marked SYNTHETIC in JDK 1.6 and later releases + flags = flags | Flags.SYNTHETIC; + JCClassDecl packageAnnotationsClass + = make.ClassDef(make.Modifiers(flags, tree.getAnnotations()), + name, List.nil(), + null, List.nil(), List.nil()); + ClassSymbol c = tree.packge.package_info; + c.flags_field |= flags; + c.setAttributes(tree.packge); + ClassType ctype = (ClassType) c.type; + ctype.supertype_field = syms.objectType; + ctype.interfaces_field = List.nil(); + packageAnnotationsClass.sym = c; + + translated.append(packageAnnotationsClass); } // where - private boolean needPackageInfoClass(JCCompilationUnit tree) { + private boolean needPackageInfoClass(JCPackageDecl pd) { switch (pkginfoOpt) { case ALWAYS: return true; case LEGACY: - return tree.packageAnnotations.nonEmpty(); + return pd.getAnnotations().nonEmpty(); case NONEMPTY: for (Attribute.Compound a : - tree.packge.getDeclarationAttributes()) { + pd.packge.getDeclarationAttributes()) { Attribute.RetentionPolicy p = types.getRetention(a); if (p != Attribute.RetentionPolicy.SOURCE) return true; diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Apr 22 17:07:54 2014 -0400 @@ -493,10 +493,26 @@ return; } + DiagnosticPosition prevLintPos = deferredLintHandler.immediate(); + Lint prevLint = chk.setLint(lint); + + try { + // Import-on-demand java.lang. + importAll(tree.pos, syms.enterPackage(names.java_lang), env); + + // Process the package def and all import clauses. + memberEnter(tree.defs, env); + } finally { + chk.setLint(prevLint); + deferredLintHandler.setPos(prevLintPos); + } + } + + public void visitPackageDef(JCPackageDecl tree) { // check that no class exists with same fully qualified name as // toplevel package if (checkClash && tree.pid != null) { - Symbol p = tree.packge; + Symbol p = env.toplevel.packge; while (p.owner != syms.rootPackage) { p.owner.complete(); // enter all class members of p if (syms.classes.get(p.getQualifiedName()) != null) { @@ -507,23 +523,8 @@ p = p.owner; } } - // process package annotations - annotate.annotateLater(tree.packageAnnotations, env, tree.packge, null); - - DiagnosticPosition prevLintPos = deferredLintHandler.immediate(); - Lint prevLint = chk.setLint(lint); - - try { - // Import-on-demand java.lang. - importAll(tree.pos, syms.enterPackage(names.java_lang), env); - - // Process all import clauses. - memberEnter(tree.defs, env); - } finally { - chk.setLint(prevLint); - deferredLintHandler.setPos(prevLintPos); - } + annotate.annotateLater(tree.annotations, env, env.toplevel.packge, null); } // process the non-static imports and the static imports of types. diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Apr 22 17:07:54 2014 -0400 @@ -601,8 +601,7 @@ */ protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) { long msec = now(); - JCCompilationUnit tree = make.TopLevel(List.nil(), - null, List.nil()); + JCCompilationUnit tree = make.TopLevel(List.nil()); if (content != null) { if (verbose) { log.printVerbose("parsing.started", filename); @@ -689,7 +688,7 @@ : make.Select(tree, names.fromString(s)); } JCCompilationUnit toplevel = - make.TopLevel(List.nil(), null, List.nil()); + make.TopLevel(List.nil()); toplevel.packge = syms.unnamedPackage; return attr.attribIdent(tree, toplevel); } finally { @@ -768,7 +767,7 @@ tree = parse(filename, filename.getCharContent(false)); } catch (IOException e) { log.error("error.reading.file", filename, JavacFileManager.getMessage(e)); - tree = make.TopLevel(List.nil(), null, List.nil()); + tree = make.TopLevel(List.nil()); } finally { log.useSource(prev); } @@ -1440,7 +1439,7 @@ make.at(Position.FIRSTPOS); TreeMaker localMake = make.forToplevel(env.toplevel); - if (env.tree instanceof JCCompilationUnit) { + if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF)) { if (!(stubOutput || sourceOutput || printFlat)) { if (shouldStop(CompileState.LOWER)) return; diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Tue Apr 22 17:07:54 2014 -0400 @@ -170,8 +170,8 @@ Symbol sym = cast(Symbol.class, e); class Vis extends JCTree.Visitor { List result = null; - public void visitTopLevel(JCCompilationUnit tree) { - result = tree.packageAnnotations; + public void visitPackageDef(JCPackageDecl tree) { + result = tree.annotations; } public void visitClassDef(JCClassDecl tree) { result = tree.mods.annotations; diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Apr 22 17:07:54 2014 -0400 @@ -3081,27 +3081,33 @@ */ public JCTree.JCCompilationUnit parseCompilationUnit() { Token firstToken = token; - JCExpression pid = null; JCModifiers mods = null; boolean consumedToplevelDoc = false; boolean seenImport = false; boolean seenPackage = false; - List packageAnnotations = List.nil(); + ListBuffer defs = new ListBuffer<>(); if (token.kind == MONKEYS_AT) mods = modifiersOpt(); if (token.kind == PACKAGE) { + int packagePos = token.pos; + List annotations = List.nil(); seenPackage = true; if (mods != null) { checkNoMods(mods.flags); - packageAnnotations = mods.annotations; + annotations = mods.annotations; mods = null; } nextToken(); - pid = qualident(false); + JCExpression pid = qualident(false); accept(SEMI); + JCPackageDecl pd = F.at(packagePos).PackageDecl(annotations, pid); + attach(pd, firstToken.comment(CommentStyle.JAVADOC)); + consumedToplevelDoc = true; + storeEnd(pd, token.pos); + defs.append(pd); } - ListBuffer defs = new ListBuffer<>(); + boolean checkForImports = true; boolean firstTypeDecl = true; while (token.kind != EOF) { @@ -3130,7 +3136,7 @@ firstTypeDecl = false; } } - JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(packageAnnotations, pid, defs.toList()); + JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList()); if (!consumedToplevelDoc) attach(toplevel, firstToken.comment(CommentStyle.JAVADOC)); if (defs.isEmpty()) diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Tue Apr 22 17:07:54 2014 -0400 @@ -89,6 +89,10 @@ */ TOPLEVEL, + /** Package level definitions. + */ + PACKAGEDEF, + /** Import clauses, of type Import. */ IMPORT, @@ -478,9 +482,6 @@ * Everything in one source file is kept in a {@linkplain JCCompilationUnit} structure. */ public static class JCCompilationUnit extends JCTree implements CompilationUnitTree { - public List packageAnnotations; - /** The tree representing the package clause. */ - public JCExpression pid; /** All definitions in this file (ClassDef, Import, and Skip) */ public List defs; /* The source file name. */ @@ -499,39 +500,39 @@ /* An object encapsulating ending positions of source ranges indexed by * the tree nodes they belong to. Defined only if option -Xjcov is set. */ public EndPosTable endPositions = null; - protected JCCompilationUnit(List packageAnnotations, - JCExpression pid, - List defs, - JavaFileObject sourcefile, - PackageSymbol packge, - ImportScope namedImportScope, - StarImportScope starImportScope) { - this.packageAnnotations = packageAnnotations; - this.pid = pid; + protected JCCompilationUnit(List defs) { this.defs = defs; - this.sourcefile = sourcefile; - this.packge = packge; - this.namedImportScope = namedImportScope; - this.starImportScope = starImportScope; } @Override public void accept(Visitor v) { v.visitTopLevel(this); } public Kind getKind() { return Kind.COMPILATION_UNIT; } + + public JCPackageDecl getPackage() { + // PackageDecl must be the first entry if it exists + if (!defs.isEmpty() && defs.head.hasTag(PACKAGEDEF)) + return (JCPackageDecl)defs.head; + return null; + } public List getPackageAnnotations() { - return packageAnnotations; + JCPackageDecl pd = getPackage(); + return pd != null ? pd.getAnnotations() : List.nil(); } + public ExpressionTree getPackageName() { + JCPackageDecl pd = getPackage(); + return pd != null ? pd.getPackageName() : null; + } + public List getImports() { ListBuffer imports = new ListBuffer<>(); for (JCTree tree : defs) { if (tree.hasTag(IMPORT)) imports.append((JCImport)tree); - else if (!tree.hasTag(SKIP)) + else if (!tree.hasTag(PACKAGEDEF) && !tree.hasTag(SKIP)) break; } return imports.toList(); } - public JCExpression getPackageName() { return pid; } public JavaFileObject getSourceFile() { return sourcefile; } @@ -541,7 +542,7 @@ public List getTypeDecls() { List typeDefs; for (typeDefs = defs; !typeDefs.isEmpty(); typeDefs = typeDefs.tail) - if (!typeDefs.head.hasTag(IMPORT)) + if (!typeDefs.head.hasTag(PACKAGEDEF) && !typeDefs.head.hasTag(IMPORT)) break; return typeDefs; } @@ -557,6 +558,39 @@ } /** + * Package definition. + */ + public static class JCPackageDecl extends JCTree implements PackageTree { + public List annotations; + /** The tree representing the package clause. */ + public JCExpression pid; + public PackageSymbol packge; + public JCPackageDecl(List annotations, JCExpression pid) { + this.annotations = annotations; + this.pid = pid; + } + @Override + public void accept(Visitor v) { v.visitPackageDef(this); } + public Kind getKind() { + return Kind.PACKAGE; + } + public List getAnnotations() { + return annotations; + } + public JCExpression getPackageName() { + return pid; + } + @Override + public R accept(TreeVisitor v, D d) { + return v.visitPackage(this, d); + } + @Override + public Tag getTag() { + return PACKAGEDEF; + } + } + + /** * An import clause. */ public static class JCImport extends JCTree implements ImportTree { @@ -2438,9 +2472,9 @@ /** An interface for tree factories */ public interface Factory { - JCCompilationUnit TopLevel(List packageAnnotations, - JCExpression pid, - List defs); + JCCompilationUnit TopLevel(List defs); + JCPackageDecl PackageDecl(List annotations, + JCExpression pid); JCImport Import(JCTree qualid, boolean staticImport); JCClassDecl ClassDef(JCModifiers mods, Name name, @@ -2528,6 +2562,7 @@ */ public static abstract class Visitor { public void visitTopLevel(JCCompilationUnit that) { visitTree(that); } + public void visitPackageDef(JCPackageDecl that) { visitTree(that); } public void visitImport(JCImport that) { visitTree(that); } public void visitClassDef(JCClassDecl that) { visitTree(that); } public void visitMethodDef(JCMethodDecl that) { visitTree(that); } diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Tue Apr 22 17:07:54 2014 -0400 @@ -367,16 +367,13 @@ public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException { docComments = tree.docComments; printDocComment(tree); - if (tree.pid != null) { - print("package "); - printExpr(tree.pid); - print(";"); - println(); - } + boolean firstImport = true; for (List l = tree.defs; - l.nonEmpty() && (cdef == null || l.head.hasTag(IMPORT)); - l = l.tail) { + l.nonEmpty() && + (cdef == null || + l.head.hasTag(IMPORT) || l.head.hasTag(PACKAGEDEF)); + l = l.tail) { if (l.head.hasTag(IMPORT)) { JCImport imp = (JCImport)l.head; Name name = TreeInfo.name(imp.qualid); @@ -426,6 +423,21 @@ } } + public void visitPackageDef(JCPackageDecl tree) { + try { + printDocComment(tree); + printAnnotations(tree.annotations); + if (tree.pid != null) { + print("package "); + printExpr(tree.pid); + print(";"); + println(); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + public void visitImport(JCImport tree) { try { print("import "); diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Tue Apr 22 17:07:54 2014 -0400 @@ -346,10 +346,15 @@ public JCTree visitCompilationUnit(CompilationUnitTree node, P p) { JCCompilationUnit t = (JCCompilationUnit) node; - List packageAnnotations = copy(t.packageAnnotations, p); + List defs = copy(t.defs, p); + return M.at(t.pos).TopLevel(defs); + } + + public JCTree visitPackage(PackageTree node, P p) { + JCPackageDecl t = (JCPackageDecl) node; + List annotations = copy(t.annotations, p); JCExpression pid = copy(t.pid, p); - List defs = copy(t.defs, p); - return M.at(t.pos).TopLevel(packageAnnotations, pid, defs); + return M.at(t.pos).PackageDecl(annotations, pid); } public JCTree visitTry(TryTree node, P p) { diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Tue Apr 22 17:07:54 2014 -0400 @@ -406,6 +406,11 @@ return Position.NOPOS; switch(tree.getTag()) { + case PACKAGEDEF: { + JCPackageDecl pd = (JCPackageDecl)tree; + return pd.annotations.isEmpty() ? pd.pos : + pd.annotations.head.pos; + } case APPLY: return getStartPos(((JCMethodInvocation) tree).meth); case ASSIGN: @@ -788,6 +793,8 @@ switch (node.getTag()) { case TOPLEVEL: return ((JCCompilationUnit) node).packge; + case PACKAGEDEF: + return ((JCPackageDecl) node).packge; case CLASSDEF: return ((JCClassDecl) node).sym; case METHODDEF: @@ -820,6 +827,7 @@ public static boolean isDeclaration(JCTree node) { node = skipParens(node); switch (node.getTag()) { + case PACKAGEDEF: case CLASSDEF: case METHODDEF: case VARDEF: diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Tue Apr 22 17:07:54 2014 -0400 @@ -116,22 +116,28 @@ /** * Create given tree node at current position. - * @param defs a list of ClassDef, Import, and Skip + * @param defs a list of PackageDef, ClassDef, Import, and Skip */ - public JCCompilationUnit TopLevel(List packageAnnotations, - JCExpression pid, - List defs) { - Assert.checkNonNull(packageAnnotations); + public JCCompilationUnit TopLevel(List defs) { for (JCTree node : defs) Assert.check(node instanceof JCClassDecl + || node instanceof JCPackageDecl || node instanceof JCImport || node instanceof JCSkip || node instanceof JCErroneous || (node instanceof JCExpressionStatement && ((JCExpressionStatement)node).expr instanceof JCErroneous), node.getClass().getSimpleName()); - JCCompilationUnit tree = new JCCompilationUnit(packageAnnotations, pid, defs, - null, null, null, null); + JCCompilationUnit tree = new JCCompilationUnit(defs); + tree.pos = pos; + return tree; + } + + public JCPackageDecl PackageDecl(List annotations, + JCExpression pid) { + Assert.checkNonNull(annotations); + Assert.checkNonNull(pid); + JCPackageDecl tree = new JCPackageDecl(annotations, pid); tree.pos = pos; return tree; } diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Tue Apr 22 17:07:54 2014 -0400 @@ -63,9 +63,12 @@ ****************************************************************************/ public void visitTopLevel(JCCompilationUnit tree) { - scan(tree.packageAnnotations); + scan(tree.defs); + } + + public void visitPackageDef(JCPackageDecl tree) { + scan(tree.annotations); scan(tree.pid); - scan(tree.defs); } public void visitImport(JCImport tree) { diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Tue Apr 22 17:07:54 2014 -0400 @@ -116,8 +116,13 @@ ****************************************************************************/ public void visitTopLevel(JCCompilationUnit tree) { + tree.defs = translate(tree.defs); + result = tree; + } + + public void visitPackageDef(JCPackageDecl tree) { + tree.annotations = translate(tree.annotations); tree.pid = translate(tree.pid); - tree.defs = translate(tree.defs); result = tree; } diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Tue Apr 22 17:07:54 2014 -0400 @@ -743,6 +743,13 @@ return p; } + TreePath getTreePath(JCCompilationUnit toplevel, JCPackageDecl tree) { + TreePath p = treePaths.get(tree); + if (p == null) + treePaths.put(tree, p = new TreePath(getTreePath(toplevel), tree)); + return p; + } + TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl tree) { TreePath p = treePaths.get(tree); if (p == null) diff -r d8a1180faaa9 -r dfb8f11542fc langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java Tue Apr 22 17:07:54 2014 -0400 @@ -27,6 +27,7 @@ import javax.tools.JavaFileObject; +import com.sun.source.util.TreePath; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.comp.Enter; @@ -84,7 +85,9 @@ public void visitTopLevel(JCCompilationUnit tree) { super.visitTopLevel(tree); if (tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE)) { - docenv.makePackageDoc(tree.packge, docenv.getTreePath(tree)); + JCPackageDecl pd = tree.getPackage(); + TreePath tp = pd == null ? docenv.getTreePath(tree) : docenv.getTreePath(tree, pd); + docenv.makePackageDoc(tree.packge, tp); } } diff -r d8a1180faaa9 -r dfb8f11542fc langtools/test/tools/javac/tree/DocCommentToplevelTest.java --- a/langtools/test/tools/javac/tree/DocCommentToplevelTest.java Tue Apr 22 19:52:15 2014 +0100 +++ b/langtools/test/tools/javac/tree/DocCommentToplevelTest.java Tue Apr 22 17:07:54 2014 -0400 @@ -144,7 +144,8 @@ public ClassTree visitCompilationUnit(CompilationUnitTree node, Void unused) { docComments = ((JCTree.JCCompilationUnit)node).docComments; boolean expectedComment = tdk == ToplevelDocKind.HAS_DOC && - (pk != PackageKind.NO_PKG || ik != ImportKind.ZERO); + pk == PackageKind.NO_PKG && + ik != ImportKind.ZERO; boolean foundComment = docComments.hasComment((JCTree) node); if (expectedComment != foundComment) { error("Unexpected comment " + docComments.getComment((JCTree) node) + " on toplevel"); @@ -153,6 +154,17 @@ } @Override + public ClassTree visitPackage(PackageTree node, Void unused) { + boolean expectedComment = tdk == ToplevelDocKind.HAS_DOC && + pk != PackageKind.NO_PKG; + boolean foundComment = docComments.hasComment((JCTree) node); + if (expectedComment != foundComment) { + error("Unexpected comment " + docComments.getComment((JCTree) node) + " on toplevel"); + } + return super.visitPackage(node, null); + } + + @Override public ClassTree visitClass(ClassTree node, Void unused) { boolean expectedComment = tdk == ToplevelDocKind.HAS_DOC && pk == PackageKind.NO_PKG && ik == ImportKind.ZERO &&