mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 14:11:36 +00:00
8034245: Refactor TopLevel tree node
Added JCPackageDecl to JCTree to store package-level information. Reviewed-by: jjg, jlahoda
This commit is contained in:
parent
b349726850
commit
9783b65028
@ -41,6 +41,12 @@ import javax.tools.JavaFileObject;
|
||||
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();
|
||||
|
||||
@ -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();
|
||||
}
|
||||
@ -207,6 +207,12 @@ public interface Tree {
|
||||
*/
|
||||
LAMBDA_EXPRESSION(LambdaExpressionTree.class),
|
||||
|
||||
/**
|
||||
* Used for instances of {@link PackageTree}.
|
||||
* @since 1.9
|
||||
*/
|
||||
PACKAGE(PackageTree.class),
|
||||
|
||||
/**
|
||||
* Used for instances of {@link ParenthesizedTree}.
|
||||
*/
|
||||
|
||||
@ -88,6 +88,7 @@ public interface TreeVisitor<R,P> {
|
||||
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);
|
||||
|
||||
@ -65,6 +65,10 @@ public class SimpleTreeVisitor <R,P> implements TreeVisitor<R,P> {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -114,13 +114,18 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
|
||||
****************************************************************************/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -75,6 +75,7 @@ import com.sun.source.doctree.UnknownBlockTagTree;
|
||||
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 @@ public class Checker extends DocTreePathScanner<Void, Void> {
|
||||
|
||||
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.
|
||||
|
||||
@ -42,6 +42,7 @@ import javax.tools.StandardLocation;
|
||||
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 @@ public class DocLint implements Plugin {
|
||||
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());
|
||||
|
||||
@ -288,15 +288,16 @@ public class Enter extends JCTree.Visitor {
|
||||
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 @@ public class Enter extends JCTree.Visitor {
|
||||
}
|
||||
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 @@ public class Enter extends JCTree.Visitor {
|
||||
}
|
||||
classEnter(tree.defs, topEnv);
|
||||
if (addEnv) {
|
||||
todo.append(topEnv);
|
||||
todo.append(packageEnv);
|
||||
}
|
||||
log.useSource(prev);
|
||||
result = null;
|
||||
|
||||
@ -388,6 +388,10 @@ public class Flow {
|
||||
super.scan(tree);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitPackageDef(JCPackageDecl tree) {
|
||||
// Do nothing for PackageDecl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -723,10 +727,6 @@ public class Flow {
|
||||
}
|
||||
}
|
||||
|
||||
public void visitTopLevel(JCCompilationUnit tree) {
|
||||
// Do nothing for TopLevel since each class is visited individually
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* main method
|
||||
*************************************************************************/
|
||||
@ -1289,10 +1289,6 @@ public class Flow {
|
||||
}
|
||||
}
|
||||
|
||||
public void visitTopLevel(JCCompilationUnit tree) {
|
||||
// Do nothing for TopLevel since each class is visited individually
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* main method
|
||||
*************************************************************************/
|
||||
@ -2357,10 +2353,6 @@ public class Flow {
|
||||
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 class Flow {
|
||||
}
|
||||
}
|
||||
|
||||
public void visitTopLevel(JCCompilationUnit tree) {
|
||||
// Do nothing for TopLevel since each class is visited individually
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* main method
|
||||
*************************************************************************/
|
||||
|
||||
@ -2408,39 +2408,39 @@ public class Lower extends TreeTranslator {
|
||||
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;
|
||||
public void visitPackageDef(JCPackageDecl tree) {
|
||||
if (!needPackageInfoClass(tree))
|
||||
return;
|
||||
|
||||
translated.append(packageAnnotationsClass);
|
||||
}
|
||||
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;
|
||||
|
||||
@ -493,10 +493,26 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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.
|
||||
|
||||
@ -601,8 +601,7 @@ public class JavaCompiler {
|
||||
*/
|
||||
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 @@ public class JavaCompiler {
|
||||
: 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 @@ public class JavaCompiler {
|
||||
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 @@ public class JavaCompiler {
|
||||
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;
|
||||
|
||||
@ -170,8 +170,8 @@ public class JavacElements implements Elements {
|
||||
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;
|
||||
|
||||
@ -3081,27 +3081,33 @@ public class JavacParser implements Parser {
|
||||
*/
|
||||
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 @@ public class JavacParser implements Parser {
|
||||
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())
|
||||
|
||||
@ -89,6 +89,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
*/
|
||||
TOPLEVEL,
|
||||
|
||||
/** Package level definitions.
|
||||
*/
|
||||
PACKAGEDEF,
|
||||
|
||||
/** Import clauses, of type Import.
|
||||
*/
|
||||
IMPORT,
|
||||
@ -478,9 +482,6 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
* 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 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
/* 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 List<JCAnnotation> getPackageAnnotations() {
|
||||
return packageAnnotations;
|
||||
|
||||
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() {
|
||||
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 abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
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;
|
||||
}
|
||||
@ -556,6 +557,39 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@ -2438,9 +2472,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
/** 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 abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
*/
|
||||
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); }
|
||||
|
||||
@ -367,16 +367,13 @@ public class Pretty extends JCTree.Visitor {
|
||||
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 class Pretty extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
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 ");
|
||||
|
||||
@ -346,10 +346,15 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
|
||||
|
||||
public JCTree visitCompilationUnit(CompilationUnitTree node, P p) {
|
||||
JCCompilationUnit t = (JCCompilationUnit) node;
|
||||
List<JCAnnotation> packageAnnotations = copy(t.packageAnnotations, 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).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);
|
||||
return M.at(t.pos).PackageDecl(annotations, pid);
|
||||
}
|
||||
|
||||
public JCTree visitTry(TryTree node, P p) {
|
||||
|
||||
@ -406,6 +406,11 @@ public class TreeInfo {
|
||||
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 @@ public class TreeInfo {
|
||||
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 class TreeInfo {
|
||||
public static boolean isDeclaration(JCTree node) {
|
||||
node = skipParens(node);
|
||||
switch (node.getTag()) {
|
||||
case PACKAGEDEF:
|
||||
case CLASSDEF:
|
||||
case METHODDEF:
|
||||
case VARDEF:
|
||||
|
||||
@ -116,22 +116,28 @@ public class TreeMaker implements JCTree.Factory {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
@ -63,11 +63,14 @@ public class TreeScanner extends Visitor {
|
||||
****************************************************************************/
|
||||
|
||||
public void visitTopLevel(JCCompilationUnit tree) {
|
||||
scan(tree.packageAnnotations);
|
||||
scan(tree.pid);
|
||||
scan(tree.defs);
|
||||
}
|
||||
|
||||
public void visitPackageDef(JCPackageDecl tree) {
|
||||
scan(tree.annotations);
|
||||
scan(tree.pid);
|
||||
}
|
||||
|
||||
public void visitImport(JCImport tree) {
|
||||
scan(tree.qualid);
|
||||
}
|
||||
|
||||
@ -116,11 +116,16 @@ public class TreeTranslator extends JCTree.Visitor {
|
||||
****************************************************************************/
|
||||
|
||||
public void visitTopLevel(JCCompilationUnit tree) {
|
||||
tree.pid = translate(tree.pid);
|
||||
tree.defs = translate(tree.defs);
|
||||
result = tree;
|
||||
}
|
||||
|
||||
public void visitPackageDef(JCPackageDecl tree) {
|
||||
tree.annotations = translate(tree.annotations);
|
||||
tree.pid = translate(tree.pid);
|
||||
result = tree;
|
||||
}
|
||||
|
||||
public void visitImport(JCImport tree) {
|
||||
tree.qualid = translate(tree.qualid);
|
||||
result = tree;
|
||||
|
||||
@ -743,6 +743,13 @@ public class DocEnv {
|
||||
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)
|
||||
|
||||
@ -27,6 +27,7 @@ package com.sun.tools.javadoc;
|
||||
|
||||
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 class JavadocEnter extends Enter {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -144,7 +144,8 @@ public class DocCommentToplevelTest {
|
||||
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");
|
||||
@ -152,6 +153,17 @@ public class DocCommentToplevelTest {
|
||||
return super.visitCompilationUnit(node, null);
|
||||
}
|
||||
|
||||
@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 &&
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user