8034245: Refactor TopLevel tree node.
Summary: Added JCPackageDecl to JCTree to store package-level information.
Reviewed-by: jjg, jlahoda
--- 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<? extends AnnotationTree> getPackageAnnotations();
ExpressionTree getPackageName();
+
+ /**
+ * Return the PackageTree associated with this compilation unit.
+ * @since 1.9
+ */
+ PackageTree getPackage();
List<? extends ImportTree> getImports();
List<? extends Tree> getTypeDecls();
JavaFileObject getSourceFile();
--- /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<? extends AnnotationTree> getAnnotations();
+ ExpressionTree getPackageName();
+}
--- 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),
--- 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);
--- 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);
}
--- 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);
}
--- 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.
--- 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());
--- 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<AttrContext> topEnv = topLevelEnv(tree);
+ Env<AttrContext> packageEnv = isPkgInfo ? topEnv.dup(pd) : null;
// Save environment of package-info.java file.
if (isPkgInfo) {
Env<AttrContext> 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;
--- 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
*************************************************************************/
--- 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.<JCTypeParameter>nil(),
- null, List.<JCExpression>nil(), List.<JCTree>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.<JCTypeParameter>nil(),
+ null, List.<JCExpression>nil(), List.<JCTree>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;
--- 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.
--- 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.<JCTree.JCAnnotation>nil(),
- null, List.<JCTree>nil());
+ JCCompilationUnit tree = make.TopLevel(List.<JCTree>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.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
+ make.TopLevel(List.<JCTree>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.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
+ tree = make.TopLevel(List.<JCTree>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;
--- 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<JCAnnotation> 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;
--- 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<JCAnnotation> packageAnnotations = List.nil();
+ ListBuffer<JCTree> defs = new ListBuffer<>();
if (token.kind == MONKEYS_AT)
mods = modifiersOpt();
if (token.kind == PACKAGE) {
+ int packagePos = token.pos;
+ List<JCAnnotation> 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<JCTree> 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())
--- 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<JCAnnotation> packageAnnotations;
- /** The tree representing the package clause. */
- public JCExpression pid;
/** All definitions in this file (ClassDef, Import, and Skip) */
public List<JCTree> 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<JCAnnotation> packageAnnotations,
- JCExpression pid,
- List<JCTree> defs,
- JavaFileObject sourcefile,
- PackageSymbol packge,
- ImportScope namedImportScope,
- StarImportScope starImportScope) {
- this.packageAnnotations = packageAnnotations;
- this.pid = pid;
+ protected JCCompilationUnit(List<JCTree> 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<JCAnnotation> getPackageAnnotations() {
- return packageAnnotations;
+ JCPackageDecl pd = getPackage();
+ return pd != null ? pd.getAnnotations() : List.<JCAnnotation>nil();
}
+ public ExpressionTree getPackageName() {
+ JCPackageDecl pd = getPackage();
+ return pd != null ? pd.getPackageName() : null;
+ }
+
public List<JCImport> getImports() {
ListBuffer<JCImport> 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<JCTree> getTypeDecls() {
List<JCTree> 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<JCAnnotation> annotations;
+ /** The tree representing the package clause. */
+ public JCExpression pid;
+ public PackageSymbol packge;
+ public JCPackageDecl(List<JCAnnotation> 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<JCAnnotation> getAnnotations() {
+ return annotations;
+ }
+ public JCExpression getPackageName() {
+ return pid;
+ }
+ @Override
+ public <R,D> R accept(TreeVisitor<R,D> 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<JCAnnotation> packageAnnotations,
- JCExpression pid,
- List<JCTree> defs);
+ JCCompilationUnit TopLevel(List<JCTree> defs);
+ JCPackageDecl PackageDecl(List<JCAnnotation> 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); }
--- 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<JCTree> 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 ");
--- 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<JCAnnotation> packageAnnotations = copy(t.packageAnnotations, p);
+ List<JCTree> defs = copy(t.defs, p);
+ return M.at(t.pos).TopLevel(defs);
+ }
+
+ public JCTree visitPackage(PackageTree node, P p) {
+ JCPackageDecl t = (JCPackageDecl) node;
+ List<JCAnnotation> annotations = copy(t.annotations, p);
JCExpression pid = copy(t.pid, p);
- List<JCTree> 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) {
--- 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:
--- 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<JCAnnotation> packageAnnotations,
- JCExpression pid,
- List<JCTree> defs) {
- Assert.checkNonNull(packageAnnotations);
+ public JCCompilationUnit TopLevel(List<JCTree> 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<JCAnnotation> annotations,
+ JCExpression pid) {
+ Assert.checkNonNull(annotations);
+ Assert.checkNonNull(pid);
+ JCPackageDecl tree = new JCPackageDecl(annotations, pid);
tree.pos = pos;
return tree;
}
--- 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) {
--- 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;
}
--- 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)
--- 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);
}
}
--- 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 &&