diff --git a/langtools/make/netbeans/langtools/build.xml b/langtools/make/netbeans/langtools/build.xml index c0b6ae26c29..0f7aeb2cee6 100644 --- a/langtools/make/netbeans/langtools/build.xml +++ b/langtools/make/netbeans/langtools/build.xml @@ -1,6 +1,6 @@ diff --git a/langtools/make/netbeans/langtools/nbproject/project.properties b/langtools/make/netbeans/langtools/nbproject/project.properties new file mode 100644 index 00000000000..31b5a412ac6 --- /dev/null +++ b/langtools/make/netbeans/langtools/nbproject/project.properties @@ -0,0 +1,10 @@ +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs=true +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width=4 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab=4 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=100 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap=none +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=project +auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.importGroupsOrder=java;javax;*;static java;static javax;static * +auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.importInnerClasses=true +auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.separateStaticImports=true diff --git a/langtools/make/netbeans/langtools/nbproject/project.xml b/langtools/make/netbeans/langtools/nbproject/project.xml index 710d523bfae..1327daed9f3 100644 --- a/langtools/make/netbeans/langtools/nbproject/project.xml +++ b/langtools/make/netbeans/langtools/nbproject/project.xml @@ -1,6 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/langtools/make/netbeans/langtools/nbproject/standard-ide-actions.ent b/langtools/make/netbeans/langtools/nbproject/standard-ide-actions.ent deleted file mode 100644 index 2d1afa7a046..00000000000 --- a/langtools/make/netbeans/langtools/nbproject/standard-ide-actions.ent +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - build - - - - clean - - - - clean - build - - - - compile-single - ${root}/src/share/classes - - includes - ${root}/src/share/classes - \.java$ - relative-path - - , - - - - - - run - - - - run-single - - run.classname - ${root}/src/share/classes - \.java$ - java-name - - - - - - - - - - jtreg - - jtreg.tests - ${root}/test - \.(java|sh)$ - relative-path - - , - - - - - - jtreg - - - - debug - - - - debug-single - - debug.classname - ${root}/src/share/classes - \.java$ - java-name - - - - - - - - - - debug-jtreg - - jtreg.tests - ${root}/test - \.(java|sh)$ - relative-path - - - - - - - - debug-fix - ${root}/src/share/classes - - class - ${root}/src/share/classes - \.java$ - relative-path-noext - - - - - - - - javadoc - - - - select-tool - - - - test-select-tool-1 - - - - test-select-tool-2 - diff --git a/langtools/make/tools/genstubs/GenStubs.java b/langtools/make/tools/genstubs/GenStubs.java index ffa95c97792..9f8fc7a7a59 100644 --- a/langtools/make/tools/genstubs/GenStubs.java +++ b/langtools/make/tools/genstubs/GenStubs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -316,7 +316,8 @@ public class GenStubs { } defs.add(def); } - return m.TopLevel(tree.packageAnnotations, tree.pid, defs.toList()); + tree.defs = tree.defs.intersect(defs.toList()); + return tree; } @Override diff --git a/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java b/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java index 9ded6b676b5..d401a31bfa5 100644 --- a/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java +++ b/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java @@ -41,6 +41,12 @@ import javax.tools.JavaFileObject; 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 --git a/langtools/src/share/classes/com/sun/source/tree/PackageTree.java b/langtools/src/share/classes/com/sun/source/tree/PackageTree.java new file mode 100644 index 00000000000..c2d822e8b05 --- /dev/null +++ b/langtools/src/share/classes/com/sun/source/tree/PackageTree.java @@ -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 --git a/langtools/src/share/classes/com/sun/source/tree/Tree.java b/langtools/src/share/classes/com/sun/source/tree/Tree.java index b416f08a0fe..de3166dc5ad 100644 --- a/langtools/src/share/classes/com/sun/source/tree/Tree.java +++ b/langtools/src/share/classes/com/sun/source/tree/Tree.java @@ -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}. */ diff --git a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java index 9a03ef2518c..db1f32af9ee 100644 --- a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java +++ b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java @@ -88,6 +88,7 @@ public interface TreeVisitor { 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 --git a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java index 4ae4ac15e12..19599456959 100644 --- a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java +++ b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java @@ -65,6 +65,10 @@ public class SimpleTreeVisitor implements TreeVisitor { 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 --git a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java index c709f59d730..a14cad476c4 100644 --- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java +++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java @@ -114,13 +114,18 @@ public class TreeScanner implements TreeVisitor { ****************************************************************************/ 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 --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index e89a460525f..54b79ba4271 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -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 { 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 --git a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java index 0c8e6661e36..1f8db0dc414 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java @@ -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()); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 7660b2d0b34..c23b92881f9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2616,7 +2616,7 @@ public class Attr extends JCTree.Visitor { * - an instance field, we use the first constructor. * - a static field, we create a fake clinit method. */ - private Env lambdaEnv(JCLambda that, Env env) { + public Env lambdaEnv(JCLambda that, Env env) { Env lambdaEnv; Symbol owner = env.info.scope.owner; if (owner.kind == VAR && owner.owner.kind == TYP) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index f3a6489e42a..617d2d177e7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,7 +25,7 @@ package com.sun.tools.javac.comp; -import com.sun.source.tree.MemberReferenceTree; +import com.sun.source.tree.LambdaExpressionTree.BodyKind; import com.sun.tools.javac.code.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; @@ -35,10 +35,8 @@ import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.comp.Attr.ResultInfo; import com.sun.tools.javac.comp.Infer.InferenceContext; import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase; -import com.sun.tools.javac.comp.Resolve.ReferenceLookupHelper; import com.sun.tools.javac.tree.JCTree.*; - import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; @@ -48,6 +46,7 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import static com.sun.tools.javac.code.Kinds.VAL; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*; @@ -75,6 +74,8 @@ public class DeferredAttr extends JCTree.Visitor { final Symtab syms; final TreeMaker make; final Types types; + final Flow flow; + final Names names; public static DeferredAttr instance(Context context) { DeferredAttr instance = context.get(deferredAttrKey); @@ -95,7 +96,8 @@ public class DeferredAttr extends JCTree.Visitor { syms = Symtab.instance(context); make = TreeMaker.instance(context); types = Types.instance(context); - Names names = Names.instance(context); + flow = Flow.instance(context); + names = Names.instance(context); stuckTree = make.Ident(names.empty).setType(Type.stuckType); emptyDeferredAttrContext = new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) { @@ -138,6 +140,11 @@ public class DeferredAttr extends JCTree.Visitor { return DEFERRED; } + @Override + public String toString() { + return "DeferredType"; + } + /** * A speculative cache is used to keep track of all overload resolution rounds * that triggered speculative attribution on a given deferred type. Each entry @@ -376,7 +383,9 @@ public class DeferredAttr extends JCTree.Visitor { } } //where - protected TreeScanner unenterScanner = new TreeScanner() { + protected UnenterScanner unenterScanner = new UnenterScanner(); + + class UnenterScanner extends TreeScanner { @Override public void visitClassDef(JCClassDecl tree) { ClassSymbol csym = tree.sym; @@ -389,7 +398,7 @@ public class DeferredAttr extends JCTree.Visitor { syms.classes.remove(csym.flatname); super.visitClassDef(tree); } - }; + } /** * A deferred context is created on each method check. A deferred context is @@ -593,19 +602,111 @@ public class DeferredAttr extends JCTree.Visitor { public void visitLambda(JCLambda tree) { Check.CheckContext checkContext = resultInfo.checkContext; Type pt = resultInfo.pt; - if (inferenceContext.inferencevars.contains(pt)) { - //ok - return; - } else { + if (!inferenceContext.inferencevars.contains(pt)) { //must be a functional descriptor + Type descriptorType = null; try { - Type desc = types.findDescriptorType(pt); - if (desc.getParameterTypes().length() != tree.params.length()) { - checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); - } + descriptorType = types.findDescriptorType(pt); } catch (Types.FunctionDescriptorLookupError ex) { checkContext.report(null, ex.getDiagnostic()); } + + if (descriptorType.getParameterTypes().length() != tree.params.length()) { + checkContext.report(tree, + diags.fragment("incompatible.arg.types.in.lambda")); + } + + Type currentReturnType = descriptorType.getReturnType(); + boolean returnTypeIsVoid = currentReturnType.hasTag(VOID); + if (tree.getBodyKind() == BodyKind.EXPRESSION) { + boolean isExpressionCompatible = !returnTypeIsVoid || + TreeInfo.isExpressionStatement((JCExpression)tree.getBody()); + if (!isExpressionCompatible) { + resultInfo.checkContext.report(tree.pos(), + diags.fragment("incompatible.ret.type.in.lambda", + diags.fragment("missing.ret.val", currentReturnType))); + } + } else { + LambdaBodyStructChecker lambdaBodyChecker = + new LambdaBodyStructChecker(); + + tree.body.accept(lambdaBodyChecker); + boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible; + + if (returnTypeIsVoid) { + if (!isVoidCompatible) { + resultInfo.checkContext.report(tree.pos(), + diags.fragment("unexpected.ret.val")); + } + } else { + boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible + && !canLambdaBodyCompleteNormally(tree); + if (!isValueCompatible && !isVoidCompatible) { + log.error(tree.body.pos(), + "lambda.body.neither.value.nor.void.compatible"); + } + + if (!isValueCompatible) { + resultInfo.checkContext.report(tree.pos(), + diags.fragment("incompatible.ret.type.in.lambda", + diags.fragment("missing.ret.val", currentReturnType))); + } + } + } + } + } + + boolean canLambdaBodyCompleteNormally(JCLambda tree) { + JCLambda newTree = new TreeCopier<>(make).copy(tree); + /* attr.lambdaEnv will create a meaningful env for the + * lambda expression. This is specially useful when the + * lambda is used as the init of a field. But we need to + * remove any added symbol. + */ + Env localEnv = attr.lambdaEnv(newTree, env); + try { + List tmpParams = newTree.params; + while (tmpParams.nonEmpty()) { + tmpParams.head.vartype = make.at(tmpParams.head).Type(syms.errType); + tmpParams = tmpParams.tail; + } + + attr.attribStats(newTree.params, localEnv); + + /* set pt to Type.noType to avoid generating any bound + * which may happen if lambda's return type is an + * inference variable + */ + Attr.ResultInfo bodyResultInfo = attr.new ResultInfo(VAL, Type.noType); + localEnv.info.returnResult = bodyResultInfo; + + // discard any log output + Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); + try { + JCBlock body = (JCBlock)newTree.body; + /* we need to attribute the lambda body before + * doing the aliveness analysis. This is because + * constant folding occurs during attribution + * and the reachability of some statements depends + * on constant values, for example: + * + * while (true) {...} + */ + attr.attribStats(body.stats, localEnv); + + attr.preFlow(newTree); + /* make an aliveness / reachability analysis of the lambda + * to determine if it can complete normally + */ + flow.analyzeLambda(localEnv, newTree, make, true); + } finally { + log.popDiagnosticHandler(diagHandler); + } + return newTree.canCompleteNormally; + } finally { + JCBlock body = (JCBlock)newTree.body; + unenterScanner.scan(body.stats); + localEnv.info.scope.leave(); } } @@ -623,10 +724,7 @@ public class DeferredAttr extends JCTree.Visitor { public void visitReference(JCMemberReference tree) { Check.CheckContext checkContext = resultInfo.checkContext; Type pt = resultInfo.pt; - if (inferenceContext.inferencevars.contains(pt)) { - //ok - return; - } else { + if (!inferenceContext.inferencevars.contains(pt)) { try { types.findDescriptorType(pt); } catch (Types.FunctionDescriptorLookupError ex) { @@ -656,6 +754,40 @@ public class DeferredAttr extends JCTree.Visitor { } } } + + /* This visitor looks for return statements, its analysis will determine if + * a lambda body is void or value compatible. We must analyze return + * statements contained in the lambda body only, thus any return statement + * contained in an inner class or inner lambda body, should be ignored. + */ + class LambdaBodyStructChecker extends TreeScanner { + boolean isVoidCompatible = true; + boolean isPotentiallyValueCompatible = true; + + @Override + public void visitClassDef(JCClassDecl tree) { + // do nothing + } + + @Override + public void visitLambda(JCLambda tree) { + // do nothing + } + + @Override + public void visitNewClass(JCNewClass tree) { + // do nothing + } + + @Override + public void visitReturn(JCReturn tree) { + if (tree.expr != null) { + isVoidCompatible = false; + } else { + isPotentiallyValueCompatible = false; + } + } + } } /** an empty deferred attribution context - all methods throw exceptions */ @@ -767,7 +899,7 @@ public class DeferredAttr extends JCTree.Visitor { /** * handler that is executed when a node has been discarded */ - abstract void skip(JCTree tree); + void skip(JCTree tree) {} } /** @@ -779,11 +911,6 @@ public class DeferredAttr extends JCTree.Visitor { PolyScanner() { super(EnumSet.of(CONDEXPR, PARENS, LAMBDA, REFERENCE)); } - - @Override - void skip(JCTree tree) { - //do nothing - } } /** @@ -796,11 +923,6 @@ public class DeferredAttr extends JCTree.Visitor { super(EnumSet.of(BLOCK, CASE, CATCH, DOLOOP, FOREACHLOOP, FORLOOP, RETURN, SYNCHRONIZED, SWITCH, TRY, WHILELOOP)); } - - @Override - void skip(JCTree tree) { - //do nothing - } } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java index c9985f7c997..bd189b3b696 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java @@ -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 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 @@ public class Enter extends JCTree.Visitor { } classEnter(tree.defs, topEnv); if (addEnv) { - todo.append(topEnv); + todo.append(packageEnv); } log.useSource(prev); result = null; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index d18988c7515..a269fcec866 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -45,7 +45,7 @@ import static com.sun.tools.javac.code.TypeTag.VOID; import static com.sun.tools.javac.tree.JCTree.Tag.*; /** This pass implements dataflow analysis for Java programs though - * different AST visitor steps. Liveness analysis (see AliveAlanyzer) checks that + * different AST visitor steps. Liveness analysis (see AliveAnalyzer) checks that * every statement is reachable. Exception analysis (see FlowAnalyzer) ensures that * every checked exception that is thrown is declared or caught. Definite assignment analysis * (see AssignAnalyzer) ensures that each variable is assigned when used. Definite @@ -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 *************************************************************************/ diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index 1fe49587172..b34f36fefa9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -515,6 +515,32 @@ public class Infer { /** max number of incorporation rounds */ static final int MAX_INCORPORATION_STEPS = 100; + /* If for two types t and s there is a least upper bound that is a + * parameterized type G, then there exists a supertype of 't' of the form + * G and a supertype of 's' of the form G + * which will be returned by this method. If no such supertypes exists then + * null is returned. + * + * As an example for the following input: + * + * t = java.util.ArrayList + * s = java.util.List + * + * we get this ouput: + * + * Pair[java.util.List,java.util.List] + */ + private Pair getParameterizedSupers(Type t, Type s) { + Type lubResult = types.lub(t, s); + if (lubResult == syms.errType || lubResult == syms.botType || + !lubResult.isParameterized()) { + return null; + } + Type asSuperOfT = types.asSuper(t, lubResult.tsym); + Type asSuperOfS = types.asSuper(s, lubResult.tsym); + return new Pair<>(asSuperOfT, asSuperOfS); + } + /** * This enumeration defines an entry point for doing inference variable * bound incorporation - it can be used to inject custom incorporation @@ -681,6 +707,53 @@ public class Infer { uv.getBounds(InferenceBound.LOWER).nonEmpty(); } }, + /** + * Given a bound set containing {@code alpha <: P} and + * {@code alpha <: P} where P is a parameterized type, + * perform {@code T = S} (which could lead to new bounds). + */ + CROSS_UPPER_UPPER() { + @Override + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { + Infer infer = inferenceContext.infer(); + List boundList = uv.getBounds(InferenceBound.UPPER); + List boundListTail = boundList.tail; + while (boundList.nonEmpty()) { + List tmpTail = boundListTail; + while (tmpTail.nonEmpty()) { + Type b1 = boundList.head; + Type b2 = tmpTail.head; + if (b1 != b2) { + Pair commonSupers = infer.getParameterizedSupers(b1, b2); + if (commonSupers != null) { + List allParamsSuperBound1 = commonSupers.fst.allparams(); + List allParamsSuperBound2 = commonSupers.snd.allparams(); + while (allParamsSuperBound1.nonEmpty() && allParamsSuperBound2.nonEmpty()) { + //traverse the list of all params comparing them + if (!allParamsSuperBound1.head.hasTag(WILDCARD) && + !allParamsSuperBound2.head.hasTag(WILDCARD)) { + isSameType(inferenceContext.asUndetVar(allParamsSuperBound1.head), + inferenceContext.asUndetVar(allParamsSuperBound2.head), infer); + } + allParamsSuperBound1 = allParamsSuperBound1.tail; + allParamsSuperBound2 = allParamsSuperBound2.tail; + } + Assert.check(allParamsSuperBound1.isEmpty() && allParamsSuperBound2.isEmpty()); + } + } + tmpTail = tmpTail.tail; + } + boundList = boundList.tail; + boundListTail = boundList.tail; + } + } + + @Override + boolean accepts(UndetVar uv, InferenceContext inferenceContext) { + return !uv.isCaptured() && + uv.getBounds(InferenceBound.UPPER).nonEmpty(); + } + }, /** * Given a bound set containing {@code alpha == S} and {@code alpha == T} * perform {@code S == T} (which could lead to new bounds). diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 31f5095e93b..269fd1938ef 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -2359,6 +2359,7 @@ public class Lower extends TreeTranslator { /** Visitor method: Translate a single node. * Attach the source position from the old tree to its replacement tree. */ + @Override public T translate(T tree) { if (tree == null) { return null; @@ -2407,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.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; + 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.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 --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 3e002c7d501..ffecda19573 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -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. diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 85417c08f00..87bddd8b2e2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -475,14 +475,14 @@ public class ClassReader { break; case CONSTANT_Fieldref: { ClassSymbol owner = readClassSymbol(getChar(index + 1)); - NameAndType nt = (NameAndType)readPool(getChar(index + 3)); + NameAndType nt = readNameAndType(getChar(index + 3)); poolObj[i] = new VarSymbol(0, nt.name, nt.uniqueType.type, owner); break; } case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: { ClassSymbol owner = readClassSymbol(getChar(index + 1)); - NameAndType nt = (NameAndType)readPool(getChar(index + 3)); + NameAndType nt = readNameAndType(getChar(index + 3)); poolObj[i] = new MethodSymbol(0, nt.name, nt.uniqueType.type, owner); break; } @@ -551,13 +551,34 @@ public class ClassReader { /** Read class entry. */ ClassSymbol readClassSymbol(int i) { - return (ClassSymbol) (readPool(i)); + Object obj = readPool(i); + if (obj != null && !(obj instanceof ClassSymbol)) + throw badClassFile("bad.const.pool.entry", + currentClassFile.toString(), + "CONSTANT_Class_info", i); + return (ClassSymbol)obj; } /** Read name. */ Name readName(int i) { - return (Name) (readPool(i)); + Object obj = readPool(i); + if (obj != null && !(obj instanceof Name)) + throw badClassFile("bad.const.pool.entry", + currentClassFile.toString(), + "CONSTANT_Utf8_info or CONSTANT_String_info", i); + return (Name)obj; + } + + /** Read name and type. + */ + NameAndType readNameAndType(int i) { + Object obj = readPool(i); + if (obj != null && !(obj instanceof NameAndType)) + throw badClassFile("bad.const.pool.entry", + currentClassFile.toString(), + "CONSTANT_NameAndType_info", i); + return (NameAndType)obj; } /************************************************************************ @@ -1209,7 +1230,7 @@ public class ClassReader { sym.owner.members().remove(sym); ClassSymbol self = (ClassSymbol)sym; ClassSymbol c = readClassSymbol(nextChar()); - NameAndType nt = (NameAndType)readPool(nextChar()); + NameAndType nt = readNameAndType(nextChar()); if (c.members_field == null) throw badClassFile("bad.enclosing.class", self, c); diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 18db5cf5554..90883092e3a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -601,8 +601,7 @@ public class JavaCompiler { */ 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 @@ public class JavaCompiler { : 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 @@ 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.nil(), null, List.nil()); + tree = make.TopLevel(List.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; diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java index dbe7bb59d7c..f04fb38c83d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -170,8 +170,8 @@ public class JavacElements implements Elements { 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 --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index c8a26f35f61..52c18418e55 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -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 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 @@ 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()) @@ -3417,16 +3423,28 @@ public class JavacParser implements Parser { * | ModifiersOpt * ( Type Ident * ( VariableDeclaratorsRest ";" | MethodDeclaratorRest ) - * | VOID Ident MethodDeclaratorRest - * | TypeParameters (Type | VOID) Ident MethodDeclaratorRest + * | VOID Ident VoidMethodDeclaratorRest + * | TypeParameters [Annotations] + * ( Type Ident MethodDeclaratorRest + * | VOID Ident VoidMethodDeclaratorRest + * ) * | Ident ConstructorDeclaratorRest * | TypeParameters Ident ConstructorDeclaratorRest * | ClassOrInterfaceOrEnumDeclaration * ) * InterfaceBodyDeclaration = * ";" - * | ModifiersOpt Type Ident - * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" ) + * | ModifiersOpt + * ( Type Ident + * ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest ) + * | VOID Ident MethodDeclaratorRest + * | TypeParameters [Annotations] + * ( Type Ident MethodDeclaratorRest + * | VOID Ident VoidMethodDeclaratorRest + * ) + * | ClassOrInterfaceOrEnumDeclaration + * ) + * */ protected List classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { if (token.kind == SEMI) { @@ -3458,28 +3476,29 @@ public class JavacParser implements Parser { } List annosAfterParams = annotationsOpt(Tag.ANNOTATION); + if (annosAfterParams.nonEmpty()) { + checkAnnotationsAfterTypeParams(annosAfterParams.head.pos); + mods.annotations = mods.annotations.appendList(annosAfterParams); + if (mods.pos == Position.NOPOS) + mods.pos = mods.annotations.head.pos; + } + Token tk = token; pos = token.pos; JCExpression type; boolean isVoid = token.kind == VOID; if (isVoid) { - if (annosAfterParams.nonEmpty()) - illegal(annosAfterParams.head.pos); type = to(F.at(pos).TypeIdent(TypeTag.VOID)); nextToken(); } else { - if (annosAfterParams.nonEmpty()) { - checkAnnotationsAfterTypeParams(annosAfterParams.head.pos); - mods.annotations = mods.annotations.appendList(annosAfterParams); - if (mods.pos == Position.NOPOS) - mods.pos = mods.annotations.head.pos; - } // method returns types are un-annotated types type = unannotatedType(); } if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) { if (isInterface || tk.name() != className) error(pos, "invalid.meth.decl.ret.type.req"); + else if (annosAfterParams.nonEmpty()) + illegal(annosAfterParams.head.pos); return List.of(methodDeclaratorRest( pos, mods, null, names.init, typarams, isInterface, true, dc)); @@ -3511,13 +3530,9 @@ public class JavacParser implements Parser { } /** MethodDeclaratorRest = - * FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") + * FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") * VoidMethodDeclaratorRest = - * FormalParameters [Throws TypeList] ( MethodBody | ";") - * InterfaceMethodDeclaratorRest = - * FormalParameters BracketsOpt [THROWS TypeList] ";" - * VoidInterfaceMethodDeclaratorRest = - * FormalParameters [THROWS TypeList] ";" + * FormalParameters [THROWS TypeList] ( MethodBody | ";") * ConstructorDeclaratorRest = * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody */ diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 8f792bd15e8..e8417df496a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -738,6 +738,9 @@ compiler.misc.incompatible.ret.type.in.mref=\ bad return type in method reference\n\ {0} +compiler.err.lambda.body.neither.value.nor.void.compatible=\ + lambda body is neither value nor void compatible + # 0: list of type compiler.err.incompatible.thrown.types.in.mref=\ incompatible thrown types {0} in method reference @@ -1716,6 +1719,11 @@ compiler.err.cant.access=\ compiler.misc.bad.class.file=\ class file is invalid for class {0} +# 0: file name, 1: expected CP entry type, 2: constant pool index +compiler.misc.bad.const.pool.entry=\ + bad constant pool entry in {0}\n\ + expected {1} at index {2} + # 0: file name, 1: message segment compiler.misc.bad.class.file.header=\ bad class file: {0}\n\ diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java index 10eae9fcf87..441264bccef 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -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 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 @@ 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 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 List 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 getPackageAnnotations() { + 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 abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { 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; } @@ -556,6 +557,39 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } } + /** + * 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. */ @@ -2438,9 +2472,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /** 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 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); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java index 9076ce47532..15d9ca586be 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java @@ -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 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 "); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java index c2e2e004a10..b9bd7b0f317 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java @@ -346,10 +346,15 @@ public class TreeCopier

implements TreeVisitor { public JCTree visitCompilationUnit(CompilationUnitTree node, P p) { JCCompilationUnit t = (JCCompilationUnit) node; - List packageAnnotations = copy(t.packageAnnotations, 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).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); + return M.at(t.pos).PackageDecl(annotations, pid); } public JCTree visitTry(TryTree node, P p) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java index 8299b71c430..9f8179810e2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -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: diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java index a27ead1a32e..9178af72973 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -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 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 --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java index 626f70ac5b3..2ef47d309ce 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java @@ -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); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java index b290ac8902b..67e50a0a47c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -56,9 +56,9 @@ public class TreeTranslator extends JCTree.Visitor { return null; } else { tree.accept(this); - JCTree result = this.result; + JCTree tmpResult = this.result; this.result = null; - return (T)result; // XXX cast + return (T)tmpResult; // XXX cast } } @@ -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; diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java index ef6f1a09cbe..dfe014ca1fc 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java @@ -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) diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java index cc0f2125177..5215edcb894 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java @@ -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); } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java b/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java index 4e9413da026..346853c9faf 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -29,13 +29,14 @@ import java.io.*; import java.net.URI; import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.HashSet; import java.util.Map; import java.util.Properties; +import com.sun.tools.sjavac.options.Options; + /** * The clean properties transform should not be necessary. * Eventually we will cleanup the property file sources in the OpenJDK instead. @@ -51,7 +52,7 @@ public class CleanProperties implements Transformer // Any extra information is ignored for clean properties. } - public void setExtra(String[] a) { + public void setExtra(Options a) { // Any extra information is ignored for clean properties. } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java index 6747c3fc917..f66e8952c1e 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,15 +25,16 @@ package com.sun.tools.sjavac; +import java.io.PrintStream; import java.net.URI; import java.util.Arrays; import java.util.Random; import java.util.Set; import java.util.Map; +import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.server.JavacServer; import com.sun.tools.sjavac.server.SysInfo; -import java.io.PrintStream; /** * This transform compiles a set of packages containing Java sources. @@ -54,13 +55,12 @@ public class CompileJavaPackages implements Transformer { // We hope to improve this in the future. final static int limitOnConcurrency = 3; - String serverSettings; + Options args; + public void setExtra(String e) { - serverSettings = e; } - String[] args; - public void setExtra(String[] a) { + public void setExtra(Options a) { args = a; } @@ -82,14 +82,14 @@ public class CompileJavaPackages implements Transformer { boolean concurrentCompiles = true; // Fetch the id. - String id = Util.extractStringOption("id", serverSettings); + String id = Util.extractStringOption("id", args.getServerConf()); if (id == null || id.equals("")) { // No explicit id set. Create a random id so that the requests can be // grouped properly in the server. id = "id"+(((new Random()).nextLong())&Long.MAX_VALUE); } // Only keep portfile and sjavac settings.. - String psServerSettings = Util.cleanSubOptions("--server:", Util.set("portfile","sjavac","background","keepalive"), serverSettings); + String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), args.getServerConf()); // Get maximum heap size from the server! SysInfo sysinfo = JavacServer.connectGetSysInfo(psServerSettings, out, err); @@ -223,7 +223,7 @@ public class CompileJavaPackages implements Transformer { @Override public void run() { rn[ii] = JavacServer.useServer(cleanedServerSettings, - Main.removeWrapperArgs(args), + args.prepJavacArgs(), cc.srcs, fvisible_sources, fvisible_classes, diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java b/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java index dadb0ce07da..48213c47991 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -37,6 +37,8 @@ import java.util.Set; import java.util.HashSet; import java.util.Map; +import com.sun.tools.sjavac.options.Options; + /** * Compile properties transform a properties file into a Java source file. * Java has built in support for reading properties from either a text file @@ -58,7 +60,7 @@ public class CompileProperties implements Transformer extra = e; } - public void setExtra(String[] a) { + public void setExtra(Options a) { } public boolean transform(Map> pkgSrcs, diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java b/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java index dd4bef2f371..a791ef0f28b 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -31,6 +31,8 @@ import java.util.Set; import java.util.HashSet; import java.util.Map; +import com.sun.tools.sjavac.options.Options; + /** * The copy file transform simply copies a matching file from -src to -d . * Such files are typically images, xml documents and other data files. @@ -45,7 +47,7 @@ public class CopyFile implements Transformer { public void setExtra(String e) { } - public void setExtra(String[] a) { + public void setExtra(Options a) { } public boolean transform(Map> pkgSrcs, diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java index c7dd8425408..1ec71c2bf56 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -26,6 +26,7 @@ package com.sun.tools.sjavac; import java.io.*; +import java.nio.file.Path; import java.util.Collections; import java.util.Date; import java.util.Set; @@ -37,6 +38,9 @@ import java.text.SimpleDateFormat; import java.net.URI; import java.util.*; +import com.sun.tools.sjavac.options.Options; +import com.sun.tools.sjavac.options.SourceLocation; + /** * The javac state class maintains the previous (prev) and the current (now) * build states and everything else that goes into the javac_state file. @@ -117,25 +121,20 @@ public class JavacState // It can also map from a jar file to the set of visible classes for that jar file. Map> visibleClasses; - // Setup two transforms that always exist. - private CopyFile copyFiles = new CopyFile(); + // Setup transform that always exist. private CompileJavaPackages compileJavaPackages = new CompileJavaPackages(); // Where to send stdout and stderr. private PrintStream out, err; - JavacState(String[] args, File bd, File gd, File hd, boolean permitUnidentifiedArtifacts, boolean removeJavacState, - PrintStream o, PrintStream e) { + JavacState(Options options, boolean removeJavacState, PrintStream o, PrintStream e) { out = o; err = e; - numCores = Main.findNumberOption(args, "-j"); - theArgs = ""; - for (String a : removeArgsNotAffectingState(args)) { - theArgs = theArgs+a+" "; - } - binDir = bd; - gensrcDir = gd; - headerDir = hd; + numCores = options.getNumCores(); + theArgs = options.getStateArgsString(); + binDir = Util.pathToFile(options.getDestDir()); + gensrcDir = Util.pathToFile(options.getGenSrcDir()); + headerDir = Util.pathToFile(options.getHeaderDir()); javacStateFilename = binDir.getPath()+File.separator+"javac_state"; javacState = new File(javacStateFilename); if (removeJavacState && javacState.exists()) { @@ -148,7 +147,7 @@ public class JavacState // We do not want to risk building a broken incremental build. // BUT since the makefiles still copy things straight into the bin_dir et al, // we avoid deleting files here, if the option --permit-unidentified-classes was supplied. - if (!permitUnidentifiedArtifacts) { + if (!options.isUnidentifiedArtifactPermitted()) { deleteContents(binDir); deleteContents(gensrcDir); deleteContents(headerDir); @@ -301,9 +300,8 @@ public class JavacState /** * Load a javac_state file. */ - public static JavacState load(String[] args, File binDir, File gensrcDir, File headerDir, - boolean permitUnidentifiedArtifacts, PrintStream out, PrintStream err) { - JavacState db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, false, out, err); + public static JavacState load(Options options, PrintStream out, PrintStream err) { + JavacState db = new JavacState(options, false, out, err); Module lastModule = null; Package lastPackage = null; Source lastSource = null; @@ -370,22 +368,22 @@ public class JavacState noFileFound = true; } catch (IOException e) { Log.info("Dropping old javac_state because of errors when reading it."); - db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err); + db = new JavacState(options, true, out, err); foundCorrectVerNr = true; newCommandLine = false; syntaxError = false; } if (foundCorrectVerNr == false && !noFileFound) { Log.info("Dropping old javac_state since it is of an old version."); - db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err); + db = new JavacState(options, true, out, err); } else if (newCommandLine == true && !noFileFound) { Log.info("Dropping old javac_state since a new command line is used!"); - db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err); + db = new JavacState(options, true, out, err); } else if (syntaxError == true) { Log.info("Dropping old javac_state since it contains syntax errors."); - db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err); + db = new JavacState(options, true, out, err); } db.prev.calculateDependents(); return db; @@ -467,12 +465,6 @@ public class JavacState return sr; } - /** - * Acquire the copying transform. - */ - public Transformer getCopier() { - return copyFiles; - } /** * If artifacts have gone missing, force a recompile of the packages @@ -629,7 +621,7 @@ public class JavacState public void performCopying(File binDir, Map suffixRules) { Map sr = new HashMap<>(); for (Map.Entry e : suffixRules.entrySet()) { - if (e.getValue() == copyFiles) { + if (e.getValue().getClass().equals(CopyFile.class)) { sr.put(e.getKey(), e.getValue()); } } @@ -643,10 +635,11 @@ public class JavacState public void performTranslation(File gensrcDir, Map suffixRules) { Map sr = new HashMap<>(); for (Map.Entry e : suffixRules.entrySet()) { - if (e.getValue() != copyFiles && - e.getValue() != compileJavaPackages) { - sr.put(e.getKey(), e.getValue()); - } + Class trClass = e.getValue().getClass(); + if (trClass == CompileJavaPackages.class || trClass == CopyFile.class) + continue; + + sr.put(e.getKey(), e.getValue()); } perform(gensrcDir, sr); } @@ -654,14 +647,11 @@ public class JavacState /** * Compile all the java sources. Return true, if it needs to be called again! */ - public boolean performJavaCompilations(File binDir, - String serverSettings, - String[] args, + public boolean performJavaCompilations(Options args, Set recentlyCompiled, boolean[] rcValue) { Map suffixRules = new HashMap<>(); suffixRules.put(".java", compileJavaPackages); - compileJavaPackages.setExtra(serverSettings); compileJavaPackages.setExtra(args); rcValue[0] = perform(binDir, suffixRules); @@ -813,7 +803,10 @@ public class JavacState for (Source s : now.sources().values()) { // Don't include link only sources when comparing sources to compile if (!s.isLinkedOnly()) { - calculatedSources.add(s.file().getPath()); + String path = s.file().getPath(); + if (mightNeedRewriting) + path = Util.normalizeDriveLetter(path); + calculatedSources.add(path); } } // Read in the file and create another set of filenames with full paths. diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Log.java b/langtools/src/share/classes/com/sun/tools/sjavac/Log.java index be209c64254..660690772ce 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Log.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Log.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -71,17 +71,19 @@ public class Log { err.println(msg); } - static public void setLogLevel(String l, PrintStream o, PrintStream e) - throws ProblemException { + static public void initializeLog(PrintStream o, PrintStream e) { out = o; err = e; + } + + static public void setLogLevel(String l) { switch (l) { case "warn": level = WARN; break; case "info": level = INFO; break; case "debug": level = DEBUG; break; case "trace": level = TRACE; break; default: - throw new ProblemException("No such log level \"" + l + "\""); + throw new IllegalArgumentException("No such log level \"" + l + "\""); } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java index b2bde85ce90..dc97eae6e11 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,13 +25,14 @@ package com.sun.tools.sjavac; -import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.nio.file.Path; +import java.nio.file.Files; +import com.sun.tools.sjavac.options.Options; +import com.sun.tools.sjavac.options.SourceLocation; import com.sun.tools.sjavac.server.JavacServer; /** @@ -151,24 +152,8 @@ public class Main { The resulting classes are written into bin. */ - // This is the final destination for classes and copied files. - private File bin_dir; - // This is where the annotation process will put generated sources. - private File gensrc_dir; - // This is where javac -h puts the generated c-header files. - private File header_dir; - - // This file contains the list of sources genereated by the makefile. - // We double check that our calculated list of sources matches this list, - // if not, then we terminate with an error! - private File makefile_source_list; - // The challenging task to manage an incremental build is done by javac_state. private JavacState javac_state; - // The suffix rules tells you for example, that .java files should be compiled, - // and .html files should be copied and .properties files be translated. - Map suffix_rules; - public static void main(String... args) { if (args.length > 0 && args[0].startsWith("--startserver:")) { if (args.length>1) { @@ -199,118 +184,142 @@ public class Main { } public int go(String[] args, PrintStream out, PrintStream err) { + + Log.initializeLog(out, err); + + Options options; try { - if (args.length == 0 || findJavaSourceFiles(args) || findAtFile(args) || null==Util.findServerSettings(args)) { - printHelp(); - return 0; - } + options = Options.parseArgs(args); + } catch (IllegalArgumentException e) { + Log.error(e.getMessage()); + return -1; + } - Log.setLogLevel(findLogLevel(args), out, err); - String server_settings = Util.findServerSettings(args); - args = verifyImplicitOption(args); - // Find the source root directories, and add the -src option before these, if not there already. - args = addSrcBeforeDirectories(args); - // Check that there is at least one -src supplied. - checkSrcOption(args); - // Check that there is one -d supplied. - bin_dir = findDirectoryOption(args,"-d","output", true, false, true); - gensrc_dir = findDirectoryOption(args,"-s","gensrc", false, false, true); - header_dir = findDirectoryOption(args,"-h","headers", false, false, true); - makefile_source_list = findFileOption(args,"--compare-found-sources","makefile source list", false); + Log.setLogLevel(options.getLogLevel()); - // Load the prev build state database. - javac_state = JavacState.load(args, bin_dir, gensrc_dir, header_dir, - findBooleanOption(args, "--permit-unidentified-artifacts"), out, err); + if (!validateOptions(options)) + return -1; - // Setup the suffix rules from the command line. - suffix_rules = javac_state.getJavaSuffixRule(); - findTranslateOptions(args, suffix_rules); - if (suffix_rules.keySet().size() > 1 && gensrc_dir == null) { - Log.error("You have translators but no gensrc dir (-s) specified!"); - return -1; - } - findCopyOptions(args, suffix_rules); + if (!createIfMissing(options.getDestDir())) + return -1; - // All found modules are put here. - Map modules = new HashMap<>(); - // We start out in the legacy empty no-name module. - // As soon as we stumble on a module-info.java file we change to that module. - Module current_module = new Module("", ""); - modules.put("", current_module); + Path gensrc = options.getGenSrcDir(); + if (gensrc != null && !createIfMissing(gensrc)) + return -1; - // Find all sources, use the suffix rules to know which files are sources. - Map sources = new HashMap<>(); - // Find the files, this will automatically populate the found modules - // with found packages where the sources are found! - findFiles(args, "-src", suffix_rules.keySet(), sources, modules, current_module, false); + Path hdrdir = options.getHeaderDir(); + if (hdrdir != null && !createIfMissing(hdrdir)) + return -1; - if (sources.isEmpty()) { - Log.error("Found nothing to compile!"); - return -1; - } + // Load the prev build state database. + javac_state = JavacState.load(options, out, err); - // Create a map of all source files that are available for linking. Both -src and - // -sourcepath point to such files. It is possible to specify multiple - // -sourcepath options to enable different filtering rules. If the - // filters are the same for multiple sourcepaths, they may be concatenated - // using :(;). Before sending the list of sourcepaths to javac, they are - // all concatenated. The list created here is used by the SmartFileWrapper to - // make sure only the correct sources are actually available. - // We might find more modules here as well. - Map sources_to_link_to = new HashMap<>(); - findFiles(args, "-src", Util.set(".java"), sources_to_link_to, modules, current_module, true); - findFiles(args, "-sourcepath", Util.set(".java"), sources_to_link_to, modules, current_module, true); - // Rewrite the -src option to make it through to the javac instances. - rewriteOptions(args, "-src", "-sourcepath"); + // Setup the suffix rules from the command line. + Map suffixRules = new HashMap<>(); - // Find all class files allowable for linking. - // And pickup knowledge of all modules found here. - // This cannot currently filter classes inside jar files. -// Map classes_to_link_to = new HashMap(); -// findFiles(args, "-classpath", Util.set(".class"), classes_to_link_to, modules, current_module, true); + // Handling of .java-compilation + suffixRules.putAll(javac_state.getJavaSuffixRule()); - // Find all module sources allowable for linking. -// Map modules_to_link_to = new HashMap(); -// findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true); + // Handling of -copy and -tr + suffixRules.putAll(options.getTranslationRules()); - // Add the set of sources to the build database. - javac_state.now().flattenPackagesSourcesAndArtifacts(modules); - javac_state.now().checkInternalState("checking sources", false, sources); - javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to); - javac_state.setVisibleSources(sources_to_link_to); + // All found modules are put here. + Map modules = new HashMap<>(); + // We start out in the legacy empty no-name module. + // As soon as we stumble on a module-info.java file we change to that module. + Module current_module = new Module("", ""); + modules.put("", current_module); - // If there is any change in the source files, taint packages - // and mark the database in need of saving. - javac_state.checkSourceStatus(false); + // Find all sources, use the suffix rules to know which files are sources. + Map sources = new HashMap<>(); - // Find all existing artifacts. Their timestamp will match the last modified timestamps stored - // in javac_state, simply because loading of the JavacState will clean out all artifacts - // that do not match the javac_state database. - javac_state.findAllArtifacts(); + // Find the files, this will automatically populate the found modules + // with found packages where the sources are found! + findSourceFiles(options.getSources(), + suffixRules.keySet(), + sources, + modules, + current_module, + options.isDefaultPackagePermitted(), + false); - // Remove unidentified artifacts from the bin, gensrc and header dirs. - // (Unless we allow them to be there.) - // I.e. artifacts that are not known according to the build database (javac_state). - // For examples, files that have been manually copied into these dirs. - // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp - // in javac_state) have already been removed when the javac_state was loaded. - if (!findBooleanOption(args, "--permit-unidentified-artifacts")) { - javac_state.removeUnidentifiedArtifacts(); - } - // Go through all sources and taint all packages that miss artifacts. - javac_state.taintPackagesThatMissArtifacts(); + if (sources.isEmpty()) { + Log.error("Found nothing to compile!"); + return -1; + } - // Now clean out all known artifacts belonging to tainted packages. - javac_state.deleteClassArtifactsInTaintedPackages(); - // Copy files, for example property files, images files, xml files etc etc. - javac_state.performCopying(bin_dir, suffix_rules); - // Translate files, for example compile properties or compile idls. - javac_state.performTranslation(gensrc_dir, suffix_rules); - // Add any potentially generated java sources to the tobe compiled list. - // (Generated sources must always have a package.) - Map generated_sources = new HashMap<>(); - Source.scanRoot(gensrc_dir, Util.set(".java"), null, null, null, null, - generated_sources, modules, current_module, false, true, false); + // Create a map of all source files that are available for linking. Both -src and + // -sourcepath point to such files. It is possible to specify multiple + // -sourcepath options to enable different filtering rules. If the + // filters are the same for multiple sourcepaths, they may be concatenated + // using :(;). Before sending the list of sourcepaths to javac, they are + // all concatenated. The list created here is used by the SmartFileWrapper to + // make sure only the correct sources are actually available. + // We might find more modules here as well. + Map sources_to_link_to = new HashMap<>(); + + List sourceResolutionLocations = new ArrayList<>(); + sourceResolutionLocations.addAll(options.getSources()); + sourceResolutionLocations.addAll(options.getSourceSearchPaths()); + findSourceFiles(sourceResolutionLocations, + Collections.singleton(".java"), + sources_to_link_to, + modules, + current_module, + options.isDefaultPackagePermitted(), + true); + + // Find all class files allowable for linking. + // And pickup knowledge of all modules found here. + // This cannot currently filter classes inside jar files. +// Map classes_to_link_to = new HashMap(); +// findFiles(args, "-classpath", Util.set(".class"), classes_to_link_to, modules, current_module, true); + + // Find all module sources allowable for linking. +// Map modules_to_link_to = new HashMap(); +// findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true); + + // Add the set of sources to the build database. + javac_state.now().flattenPackagesSourcesAndArtifacts(modules); + javac_state.now().checkInternalState("checking sources", false, sources); + javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to); + javac_state.setVisibleSources(sources_to_link_to); + + // If there is any change in the source files, taint packages + // and mark the database in need of saving. + javac_state.checkSourceStatus(false); + + // Find all existing artifacts. Their timestamp will match the last modified timestamps stored + // in javac_state, simply because loading of the JavacState will clean out all artifacts + // that do not match the javac_state database. + javac_state.findAllArtifacts(); + + // Remove unidentified artifacts from the bin, gensrc and header dirs. + // (Unless we allow them to be there.) + // I.e. artifacts that are not known according to the build database (javac_state). + // For examples, files that have been manually copied into these dirs. + // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp + // in javac_state) have already been removed when the javac_state was loaded. + if (!options.isUnidentifiedArtifactPermitted()) { + javac_state.removeUnidentifiedArtifacts(); + } + // Go through all sources and taint all packages that miss artifacts. + javac_state.taintPackagesThatMissArtifacts(); + + // Now clean out all known artifacts belonging to tainted packages. + javac_state.deleteClassArtifactsInTaintedPackages(); + // Copy files, for example property files, images files, xml files etc etc. + javac_state.performCopying(Util.pathToFile(options.getDestDir()), suffixRules); + // Translate files, for example compile properties or compile idls. + javac_state.performTranslation(Util.pathToFile(gensrc), suffixRules); + // Add any potentially generated java sources to the tobe compiled list. + // (Generated sources must always have a package.) + Map generated_sources = new HashMap<>(); + + try { + + Source.scanRoot(Util.pathToFile(options.getGenSrcDir()), Util.set(".java"), null, null, null, null, + generated_sources, modules, current_module, false, true, false); javac_state.now().flattenPackagesSourcesAndArtifacts(modules); // Recheck the the source files and their timestamps again. javac_state.checkSourceStatus(true); @@ -320,7 +329,7 @@ public class Main { // right, then incremental builds will fail with subtility. // If any difference is detected, then we will fail hard here. // This is an important safety net. - javac_state.compareWithMakefileList(makefile_source_list); + javac_state.compareWithMakefileList(Util.pathToFile(options.getSourceReferenceList())); // Do the compilations, repeatedly until no tainted packages exist. boolean again; @@ -330,7 +339,7 @@ public class Main { do { // Clean out artifacts in tainted packages. javac_state.deleteClassArtifactsInTaintedPackages(); - again = javac_state.performJavaCompilations(bin_dir, server_settings, args, recently_compiled, rc); + again = javac_state.performJavaCompilations(options, recently_compiled, rc); if (!rc[0]) break; } while (again); // Only update the state if the compile went well. @@ -351,620 +360,71 @@ public class Main { } } - /** - * Are java source files passed on the command line? - */ - private boolean findJavaSourceFiles(String[] args) { - String prev = ""; - for (String s : args) { - if (s.endsWith(".java") && !prev.equals("-xf") && !prev.equals("-if")) { - return true; - } - prev = s; + private static boolean validateOptions(Options options) { + + String err = null; + + if (options.getDestDir() == null) { + err = "Please specify output directory."; + } else if (options.isJavaFilesAmongJavacArgs()) { + err = "Sjavac does not handle explicit compilation of single .java files."; + } else if (options.isAtFilePresent()) { + err = "Sjavac does not handle @-files."; + } else if (options.getServerConf() == null) { + err = "No server configuration provided."; + } else if (!options.getImplicitPolicy().equals("none")) { + err = "The only allowed setting for sjavac is -implicit:none"; + } else if (options.getSources().isEmpty()) { + err = "You have to specify -src."; + } else if (options.getTranslationRules().size() > 1 + && options.getGenSrcDir() == null) { + err = "You have translators but no gensrc dir (-s) specified!"; } - return false; + + if (err != null) + Log.error(err); + + return err == null; + } - /** - * Is an at file passed on the command line? - */ - private boolean findAtFile(String[] args) { - for (String s : args) { - if (s.startsWith("@")) { - return true; - } - } - return false; - } + private static boolean createIfMissing(Path dir) { - /** - * Find the log level setting. - */ - private String findLogLevel(String[] args) { - for (String s : args) { - if (s.startsWith("--log=") && s.length()>6) { - return s.substring(6); - } - if (s.equals("-verbose")) { - return "info"; - } - } - return "info"; - } + if (Files.isDirectory(dir)) + return true; - /** - * Remove smart javac wrapper arguments, before feeding - * the args to the plain javac. - */ - static String[] removeWrapperArgs(String[] args) { - String[] out = new String[args.length]; - // The first source path index is remembered - // here. So that all following can be concatenated to it. - int source_path = -1; - // The same for class path. - int class_path = -1; - // And module path. - int module_path = -1; - int j = 0; - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a directory following "+option+"."); - } - if (args[i+1].indexOf(File.pathSeparatorChar) != -1) { - throw new ProblemException("You must only specify a single directory for "+option+"."); - } - dir = new File(args[i+1]); - if (!dir.exists()) { - if (!create) { - throw new ProblemException("This directory does not exist: "+dir.getPath()); - } else - if (!makeSureExists(dir)) { - throw new ProblemException("Cannot create directory "+dir.getPath()); - } - } - if (!dir.isDirectory()) { - throw new ProblemException("\""+args[i+1]+"\" is not a directory."); - } - } - } - if (dir == null && needed) { - throw new ProblemException("You have to specify "+option); - } try { - if (dir != null) - return dir.getCanonicalFile(); + Files.createDirectories(dir); } catch (IOException e) { - throw new ProblemException(""+e); + Log.error("Could not create directory: " + e.getMessage()); + return false; } - return null; - } - /** - * Option is followed by path. - */ - private static boolean shouldBeFollowedByPath(String o) { - return o.equals("-s") || - o.equals("-h") || - o.equals("-d") || - o.equals("-sourcepath") || - o.equals("-classpath") || - o.equals("-cp") || - o.equals("-bootclasspath") || - o.equals("-src"); - } - - /** - * Add -src before source root directories if not already there. - */ - private static String[] addSrcBeforeDirectories(String[] args) { - List newargs = new ArrayList<>(); - for (int i = 0; i dirs = new HashSet<>(); - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a directory following -src."); - } - StringTokenizer st = new StringTokenizer(args[i+1], File.pathSeparator); - while (st.hasMoreElements()) { - File dir = new File(st.nextToken()); - if (!dir.exists()) { - throw new ProblemException("This directory does not exist: "+dir.getPath()); - } - if (!dir.isDirectory()) { - throw new ProblemException("\""+dir.getPath()+"\" is not a directory."); - } - if (dirs.contains(dir)) { - throw new ProblemException("The src directory \""+dir.getPath()+"\" is specified more than once!"); - } - dirs.add(dir); - } - } - } - if (dirs.isEmpty()) { - throw new ProblemException("You have to specify -src."); - } - } - - /** - * Scan the arguments to find an option that specifies a file. - */ - private static File findFileOption(String[] args, String option, String name, boolean needed) - throws ProblemException, ProblemException { - File file = null; - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a file following "+option+"."); - } - file = new File(args[i+1]); - if (file.isDirectory()) { - throw new ProblemException("\""+args[i+1]+"\" is not a file."); - } - if (!file.exists() && needed) { - throw new ProblemException("The file \""+args[i+1]+"\" does not exist."); - } - - } - } - if (file == null && needed) { - throw new ProblemException("You have to specify "+option); - } - return file; - } - - /** - * Look for a specific switch, return true if found. - */ - public static boolean findBooleanOption(String[] args, String option) { - for (String arg : args) { - if (arg.equals(option)) - return true; - } - return false; - } - - /** - * Scan the arguments to find an option that specifies a number. - */ - public static int findNumberOption(String[] args, String option) { - int rc = 0; - for (int i = 0; i i+1) { - rc = Integer.parseInt(args[i+1]); - } - } - } - return rc; - } - - /** - * Scan the arguments to find the option (-tr) that setup translation rules to java source - * from different sources. For example: .properties are translated using CompileProperties - * The found translators are stored as suffix rules. - */ - private static void findTranslateOptions(String[] args, Map suffix_rules) - throws ProblemException, ProblemException { - - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a translate rule following -tr."); - } - String s = args[i+1]; - checkTranslatePattern(s); - int ep = s.indexOf("="); - String suffix = s.substring(0,ep); - String classname = s.substring(ep+1); - if (suffix_rules.get(suffix) != null) { - throw new ProblemException("You have already specified a "+ - "rule for the suffix "+suffix); - } - if (s.equals(".class")) { - throw new ProblemException("You cannot have a translator for .class files!"); - } - if (s.equals(".java")) { - throw new ProblemException("You cannot have a translator for .java files!"); - } - String extra = null; - int exp = classname.indexOf(","); - if (exp != -1) { - extra = classname.substring(exp+1); - classname = classname.substring(0,exp); - } - try { - Class cl = Class.forName(classname); - Transformer t = (Transformer)cl.newInstance(); - t.setExtra(extra); - suffix_rules.put(suffix, t); - } - catch (Exception e) { - throw new ProblemException("Cannot use "+classname+" as a translator!"); - } - } - } - } - - /** - * Scan the arguments to find the option (-copy) that setup copying rules into the bin dir. - * For example: -copy .html - * The found copiers are stored as suffix rules as well. No translation is done, just copying. - */ - private void findCopyOptions(String[] args, Map suffix_rules) - throws ProblemException, ProblemException { - - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a translate rule following -tr."); - } - String s = args[i+1]; - checkCopyPattern(s); - if (suffix_rules.get(s) != null) { - throw new ProblemException("You have already specified a "+ - "rule for the suffix "+s); - } - if (s.equals(".class")) { - throw new ProblemException("You cannot have a copy rule for .class files!"); - } - if (s.equals(".java")) { - throw new ProblemException("You cannot have a copy rule for .java files!"); - } - suffix_rules.put(s, javac_state.getCopier()); - } - } - } - - /** - * Rewrite a / separated path into \ separated, but only - * if we are running on a platform were File.separatorChar=='\', ie winapi. - */ - private String fixupSeparator(String p) { - if (File.separatorChar == '/') return p; - return p.replaceAll("/", "\\\\"); - } - - /** - * Scan the arguments for -i -x -xf -if followed by the option - * -src, -sourcepath, -modulepath or -classpath and produce a map of all the - * files to referenced for that particular option. - * - * Store the found sources and the found modules in the supplied maps. - */ - private boolean findFiles(String[] args, String option, Set suffixes, - Map found_files, Map found_modules, - Module current_module, boolean inLinksrc) - throws ProblemException, ProblemException - { - // Track which source roots, source path roots and class path roots have been added. - Set roots = new HashSet<>(); - // Track the current set of package includes,excludes as well as excluded source files, - // to be used in the next -src/-sourcepath/-classpath - List includes = new LinkedList<>(); - List excludes = new LinkedList<>(); - List excludefiles = new LinkedList<>(); - List includefiles = new LinkedList<>(); - // This include is used to find all modules in the source. - List moduleinfo = new LinkedList<>(); - moduleinfo.add("module-info.java"); - - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a package pattern following -i"); - } - String incl = args[i+1]; - checkPattern(incl); - includes.add(incl); - } - if (args[i].equals("-x")) { - if (i+1 >= args.length) { - throw new ProblemException("You have to specify a package pattern following -x"); - } - String excl = args[i+1]; - checkPattern(excl); - excludes.add(excl); - } - if (args[i].equals("-xf")) { - if (i+1 >= args.length) { - throw new ProblemException("You have to specify a file following -xf"); - } - String exclf = args[i+1]; - checkFilePattern(exclf); - exclf = Util.normalizeDriveLetter(exclf); - excludefiles.add(fixupSeparator(exclf)); - } - if (args[i].equals("-if")) { - if (i+1 >= args.length) { - throw new ProblemException("You have to specify a file following -xf"); - } - String inclf = args[i+1]; - checkFilePattern(inclf); - inclf = Util.normalizeDriveLetter(inclf); - includefiles.add(fixupSeparator(inclf)); - } - if (args[i].equals(option)) { - if (i+1 >= args.length) { - throw new ProblemException("You have to specify a directory following "+option); - } - String[] root_dirs = args[i+1].split(File.pathSeparator); - for (String r : root_dirs) { - File root = new File(r); - if (!root.isDirectory()) { - throw new ProblemException("\""+r+"\" is not a directory."); - } - try { - root = root.getCanonicalFile(); - } catch (IOException e) { - throw new ProblemException(""+e); - } - if (roots.contains(root)) { - throw new ProblemException("\""+r+"\" has already been used for "+option); - } - if (root.equals(bin_dir)) { - throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -d"); - } - if (root.equals(gensrc_dir)) { - throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -s"); - } - if (root.equals(header_dir)) { - throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -h"); - } - roots.add(root); - Source.scanRoot(root, suffixes, excludes, includes, excludefiles, includefiles, - found_files, found_modules, current_module, - findBooleanOption(args, "--permit-sources-without-package"), - false, inLinksrc); - } - } - if (args[i].equals("-src") || - args[i].equals("-sourcepath") || - args[i].equals("-modulepath") || - args[i].equals("-classpath") || - args[i].equals("-cp")) - { - // Reset the includes,excludes and excludefiles after they have been used. - includes = new LinkedList<>(); - excludes = new LinkedList<>(); - excludefiles = new LinkedList<>(); - includefiles = new LinkedList<>(); - } - } return true; } -} + /** Find source files in the given source locations. */ + public static void findSourceFiles(List sourceLocations, + Set sourceTypes, + Map foundFiles, + Map foundModules, + Module currentModule, + boolean permitSourcesInDefaultPackage, + boolean inLinksrc) { + + for (SourceLocation source : sourceLocations) { + source.findSourceFiles(sourceTypes, + foundFiles, + foundModules, + currentModule, + permitSourcesInDefaultPackage, + inLinksrc); + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Source.java b/langtools/src/share/classes/com/sun/tools/sjavac/Source.java index 52c870989b4..444ee1c1dc0 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Source.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Source.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -201,7 +201,7 @@ public class Source implements Comparable { // It might contain other source files however, (for -tr and -copy) these will // always be included, since no package pattern can match the root directory. currentModule = addFilesInDir(root, root_prefix, root, suffixes, permitSourcesWithoutPackage, - excludeFiles, includeFiles, false, + excludeFiles, includeFiles, foundFiles, foundModules, currentModule, inGensrc, inLinksrc); @@ -211,24 +211,28 @@ public class Source implements Comparable { // Descend into the directory structure. scanDirectory(d, root_prefix, root, suffixes, excludes, includes, excludeFiles, includeFiles, - false, foundFiles, foundModules, currentModule, inGensrc, inLinksrc); + foundFiles, foundModules, currentModule, inGensrc, inLinksrc); } } } /** * Test if a path matches any of the patterns given. - * The pattern foo.bar matches only foo.bar - * The pattern foo.* matches foo.bar and foo.bar.zoo etc + * The pattern foo/bar matches only foo/bar + * The pattern foo/* matches foo/bar and foo/bar/zoo etc */ static private boolean hasMatch(String path, List patterns) { + + // Convert Windows '\' to '/' for the sake of comparing with the patterns + path = path.replace(File.separatorChar, '/'); + for (String p : patterns) { // Exact match - if (p.equals(path)) { + if (p.equals(path)) return true; - } + // Single dot the end matches this package and all its subpackages. - if (p.endsWith(".*")) { + if (p.endsWith("/*")) { // Remove the wildcard String patprefix = p.substring(0,p.length()-2); // Does the path start with the pattern prefix? @@ -237,7 +241,7 @@ public class Source implements Comparable { // If the path is longer, then make sure that // the next part of the path starts with a dot (.) to prevent // wildcard matching in the middle of a package name. - if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='.') { + if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='/') { return true; } } @@ -251,6 +255,9 @@ public class Source implements Comparable { // The pattern foo/bar.java only matches foo/bar.java // The pattern */bar.java matches foo/bar.java and zoo/bar.java etc static private boolean hasFileMatch(String path, List patterns) { + // Convert Windows '\' to '/' for the sake of comparing with the patterns + path = path.replace(File.separatorChar, '/'); + path = Util.normalizeDriveLetter(path); for (String p : patterns) { // Exact match @@ -276,7 +283,7 @@ public class Source implements Comparable { */ static private Module addFilesInDir(File dir, int rootPrefix, File root, Set suffixes, boolean allow_javas, - List excludeFiles, List includeFiles, boolean all, + List excludeFiles, List includeFiles, Map foundFiles, Map foundModules, Module currentModule, @@ -285,79 +292,82 @@ public class Source implements Comparable { throws ProblemException { for (File f : dir.listFiles()) { - if (f.isFile()) { - boolean should_add = - (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles)) - && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles)); - if (should_add) { - if (!allow_javas && f.getName().endsWith(".java")) { - throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+ - ", please remove "+f.getName()); - } - // Extract the file name relative the root. - String fn = f.getPath().substring(rootPrefix); - // Extract the package name. - int sp = fn.lastIndexOf(File.separatorChar); - String pkg = ""; - if (sp != -1) { - pkg = fn.substring(0,sp).replace(File.separatorChar,'.'); - } - // Is this a module-info.java file? - if (fn.endsWith("module-info.java")) { - // Aha! We have recursed into a module! - if (!currentModule.name().equals("")) { - throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn); + if (!f.isFile()) + continue; + + boolean should_add = + (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles)) + && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles)); + + if (!should_add) + continue; + + if (!allow_javas && f.getName().endsWith(".java")) { + throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+ + ", please remove "+f.getName()); + } + // Extract the file name relative the root. + String fn = f.getPath().substring(rootPrefix); + // Extract the package name. + int sp = fn.lastIndexOf(File.separatorChar); + String pkg = ""; + if (sp != -1) { + pkg = fn.substring(0,sp); + } + // Is this a module-info.java file? + if (fn.endsWith("module-info.java")) { + // Aha! We have recursed into a module! + if (!currentModule.name().equals("")) { + throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn); + } + String module_name = fn.substring(0,fn.length()-16); + currentModule = new Module(module_name, f.getPath()); + foundModules.put(module_name, currentModule); + } + // Extract the suffix. + int dp = fn.lastIndexOf("."); + String suffix = ""; + if (dp > 0) { + suffix = fn.substring(dp); + } + // Should the file be added? + if (suffixes.contains(suffix)) { + Source of = foundFiles.get(f.getPath()); + if (of != null) { + throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath()); + } + of = currentModule.lookupSource(f.getPath()); + if (of != null) { + // Oups, the source is already added, could be ok, could be not, lets check. + if (inLinksrc) { + // So we are collecting sources for linking only. + if (of.isLinkedOnly()) { + // Ouch, this one is also for linking only. Bad. + throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath()); } - String module_name = fn.substring(0,fn.length()-16); - currentModule = new Module(module_name, f.getPath()); - foundModules.put(module_name, currentModule); - } - // Extract the suffix. - int dp = fn.lastIndexOf("."); - String suffix = ""; - if (dp > 0) { - suffix = fn.substring(dp); - } - // Should the file be added? - if (all || suffixes.contains(suffix)) { - Source of = foundFiles.get(f.getPath()); - if (of != null) { - throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath()); - } - of = currentModule.lookupSource(f.getPath()); - if (of != null) { - // Oups, the source is already added, could be ok, could be not, lets check. - if (inLinksrc) { - // So we are collecting sources for linking only. - if (of.isLinkedOnly()) { - // Ouch, this one is also for linking only. Bad. - throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath()); - } - // Ok, the existing source is to be compiled. Thus this link only is redundant - // since all compiled are also linked to. Continue to the next source. - // But we need to add the source, so that it will be visible to linking, - // if not the multi core compile will fail because a JavaCompiler cannot - // find the necessary dependencies for its part of the source. - foundFiles.put(f.getPath(), of); - continue; - } else { - // We are looking for sources to compile, if we find an existing to be compiled - // source with the same name, it is an internal error, since we must - // find the sources to be compiled before we find the sources to be linked to. - throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath()); - } - } - Source s = new Source(currentModule, f.getPath(), f, root); - if (inGensrc) s.markAsGenerated(); - if (inLinksrc) { - s.markAsLinkedOnly(); - } - pkg = currentModule.name()+":"+pkg; - foundFiles.put(f.getPath(), s); - currentModule.addSource(pkg, s); + // Ok, the existing source is to be compiled. Thus this link only is redundant + // since all compiled are also linked to. Continue to the next source. + // But we need to add the source, so that it will be visible to linking, + // if not the multi core compile will fail because a JavaCompiler cannot + // find the necessary dependencies for its part of the source. + foundFiles.put(f.getPath(), of); + continue; + } else { + // We are looking for sources to compile, if we find an existing to be compiled + // source with the same name, it is an internal error, since we must + // find the sources to be compiled before we find the sources to be linked to. + throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath()); } } + Source s = new Source(currentModule, f.getPath(), f, root); + if (inGensrc) s.markAsGenerated(); + if (inLinksrc) { + s.markAsLinkedOnly(); + } + pkg = currentModule.name()+":"+pkg; + foundFiles.put(f.getPath(), s); + currentModule.addSource(pkg, s); } } return currentModule; @@ -368,23 +378,22 @@ public class Source implements Comparable { static private void scanDirectory(File dir, int rootPrefix, File root, Set suffixes, List excludes, List includes, - List excludeFiles, List includeFiles, boolean all, + List excludeFiles, List includeFiles, Map foundFiles, Map foundModules, Module currentModule, boolean inGensrc, boolean inLinksrc) throws ProblemException { - String pkg_name = ""; - // Remove the root prefix from the dir path, and replace file separator with dots - // to get the package name. + String path = ""; + // Remove the root prefix from the dir path if (dir.getPath().length() > rootPrefix) { - pkg_name = dir.getPath().substring(rootPrefix).replace(File.separatorChar,'.'); + path = dir.getPath().substring(rootPrefix); } // Should this package directory be included and not excluded? - if (all || ((includes==null || includes.isEmpty() || hasMatch(pkg_name, includes)) && - (excludes==null || excludes.isEmpty() || !hasMatch(pkg_name, excludes)))) { + if ((includes==null || includes.isEmpty() || hasMatch(path, includes)) && + (excludes==null || excludes.isEmpty() || !hasMatch(path, excludes))) { // Add the source files. - currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles, all, + currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles, foundFiles, foundModules, currentModule, inGensrc, inLinksrc); } @@ -392,7 +401,7 @@ public class Source implements Comparable { if (d.isDirectory()) { // Descend into the directory structure. scanDirectory(d, rootPrefix, root, suffixes, - excludes, includes, excludeFiles, includeFiles, all, + excludes, includes, excludeFiles, includeFiles, foundFiles, foundModules, currentModule, inGensrc, inLinksrc); } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java b/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java index 954cfc7ffb6..125a02659d4 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -30,6 +30,8 @@ import java.net.URI; import java.util.Set; import java.util.Map; +import com.sun.tools.sjavac.options.Options; + /** * The transform interface is used to transform content inside a package, from one form to another. * Usually the output form is an unpredictable number of output files. (eg class files) @@ -95,5 +97,5 @@ public interface Transformer PrintStream err); void setExtra(String e); - void setExtra(String[] args); + void setExtra(Options args); } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Util.java b/langtools/src/share/classes/com/sun/tools/sjavac/Util.java index 19147a1432a..146bb172245 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Util.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -26,6 +26,7 @@ package com.sun.tools.sjavac; import java.io.File; +import java.nio.file.Path; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -94,14 +95,12 @@ public class Util { * do settings = cleanOptions("--server:",Util.set("-portfile"),settings); * now settings equals "--server:portfile=bar" * - * @param optionPrefix The option name, including colon, eg --server: * @param allowsSubOptions A set of the allowed sub options, id portfile etc. * @param s The option settings string. */ - public static String cleanSubOptions(String optionPrefix, Set allowedSubOptions, String s) { + public static String cleanSubOptions(Set allowedSubOptions, String s) { StringBuilder sb = new StringBuilder(); - if (!s.startsWith(optionPrefix)) return ""; - StringTokenizer st = new StringTokenizer(s.substring(optionPrefix.length()), ","); + StringTokenizer st = new StringTokenizer(s, ","); while (st.hasMoreTokens()) { String o = st.nextToken(); int p = o.indexOf('='); @@ -157,4 +156,9 @@ public class Util { } return null; } + + // TODO: Remove when refactoring from java.io.File to java.nio.file.Path. + public static File pathToFile(Path path) { + return path == null ? null : path.toFile(); + } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java b/langtools/src/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java new file mode 100644 index 00000000000..abb6d70b52b --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java @@ -0,0 +1,83 @@ +/* + * 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.tools.sjavac.options; + +import java.util.Iterator; + +public class ArgumentIterator implements Iterator { + + /** The underlying argument iterator */ + private Iterator iter; + + /** Extra state used to implement peek and current */ + private String current; + private String buffered; + + public ArgumentIterator(Iterable iter) { + this.iter = iter.iterator(); + } + + @Override + public boolean hasNext() { + return buffered != null || iter.hasNext(); + } + + @Override + public String next() { + fillBuffer(); + current = buffered; + buffered = null; + return current; + } + + /** + * @return the last element returned by next() (or {@code null} if next has + * never been invoked on this iterator). + */ + public String current() { + return current; + } + + /** Can't remove current element, since we may have buffered it. */ + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + /** + * @return Returns the next element without advancing the iterator + */ + public String peek() { + fillBuffer(); + return buffered; + } + + private void fillBuffer() { + if (buffered == null && iter.hasNext()) + buffered = iter.next(); + } + +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java b/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java new file mode 100644 index 00000000000..25a5f009bcc --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java @@ -0,0 +1,360 @@ +/* + * 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.tools.sjavac.options; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.sun.tools.sjavac.CopyFile; +import com.sun.tools.sjavac.Transformer; + + +/** + * Sjavac options can be classified as: + * + * (1) relevant only for sjavac, such as --server + * (2) relevant for sjavac and javac, such as -d, or + * (3) relevant only for javac, such as -g. + * + * This enum represents all options from (1) and (2). Note that instances of + * this enum only entail static information about the option. For storage of + * option values, refer to com.sun.tools.sjavac.options.Options. + */ +public enum Option { + + SRC("-src", "Location of source files to be compiled") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + List paths = getFileListArg(iter, helper); + if (paths != null) + helper.sourceRoots(paths); + } + }, + SOURCEPATH("-sourcepath", "Specify search path for sources.") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + List paths = getFileListArg(iter, helper); + if (paths != null) + helper.sourcepath(paths); + } + }, + MODULEPATH("-modulepath", "Specify search path for modules.") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + List paths = getFileListArg(iter, helper); + if (paths != null) + helper.modulepath(paths); + } + }, + CLASSPATH("-classpath", "Specify search path for classes.") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + List paths = getFileListArg(iter, helper); + if (paths != null) + helper.classpath(paths); + } + }, + CP("-cp", "An alias for -classpath") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + CLASSPATH.processMatching(iter, helper); + } + }, + X("-x", "Exclude directory from the subsequent source directory") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + String pattern = getFilePatternArg(iter, helper); + if (pattern != null) + helper.exclude(pattern); + } + }, + I("-i", "Include only the given directory from the subsequent source directory") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + String pattern = getFilePatternArg(iter, helper); + if (pattern != null) + helper.include(pattern); + } + }, + XF("-xf", "Exclude a given file") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + String pattern = getFilePatternArg(iter, helper); + if (pattern != null) + helper.excludeFile(pattern); + } + }, + IF("-if", "Include only the given file") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + String pattern = getFilePatternArg(iter, helper); + if (pattern != null) + helper.includeFile(pattern); + } + }, + TR("-tr", "Translate resources") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + + if (!iter.hasNext()) { + helper.reportError(arg + " must be followed by a translation rule"); + return; + } + + String trArg = iter.next(); + + // Validate argument syntax. Examples: + // .prop=com.sun.tools.javac.smart.CompileProperties + // .idl=com.sun.corba.CompileIdl + // .g3=antlr.CompileGrammar,debug=true + String ident = "[a-zA-Z_][a-zA-Z0-9_]*"; + Pattern p = Pattern.compile("(?\\." + ident + ")=" + + "(?" + ident + "(\\." + ident + ")*)" + + "(?,.*)?"); + // Check syntax + Matcher m = p.matcher(trArg); + if (!m.matches()) { + helper.reportError("The string \"" + trArg + "\" is not a " + + "valid translate pattern"); + return; + } + + // Extract relevant parts + String suffix = m.group("suffix"); + String classname = m.group("class"); + String extra = m.group("extra"); + + // Valid suffix? + if (suffix.matches("\\.(class|java)")) { + helper.reportError("You cannot have a translator for " + + suffix + " files!"); + return; + } + + // Construct transformer + try { + Class trCls = Class.forName(classname); + Transformer transformer = (Transformer) trCls.newInstance(); + transformer.setExtra(extra); + helper.addTransformer(suffix, transformer); + } catch (Exception e) { + helper.reportError("Cannot use " + classname + + " as a translator: " + e.getMessage()); + } + } + }, + COPY("-copy", "Copy resources") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + if (!iter.hasNext()) { + helper.reportError(arg + " must be followed by a resource type"); + return; + } + + String copyArg = iter.next(); + + // Validate argument syntax. Examples: .gif, .html + if (!copyArg.matches("\\.[a-zA-Z_][a-zA-Z0-9_]*")) { + helper.reportError("The string \"" + copyArg + "\" is not a " + + "valid resource type."); + return; + } + + helper.addTransformer(copyArg, new CopyFile()); + } + }, + J("-j", "Number of cores") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + if (!iter.hasNext() || !iter.peek().matches("\\d+")) { + helper.reportError(arg + " must be followed by an integer"); + return; + } + helper.numCores(Integer.parseInt(iter.next())); + } + }, + SERVER("--server:", "Specify server configuration file of running server") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.serverConf(iter.current().substring(arg.length())); + } + }, + STARTSERVER("--startserver:", "Start server and use the given configuration file") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.startServerConf(iter.current().substring(arg.length())); + } + }, + IMPLICIT("-implicit:", "Specify how to treat implicitly referenced source code") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.implicit(iter.current().substring(arg.length())); + } + }, + LOG("--log=", "Specify logging level") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.logLevel(iter.current().substring(arg.length())); + } + }, + VERBOSE("-verbose", "Set verbosity level to \"info\"") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.logLevel("info"); + } + }, + PERMIT_UNIDENTIFIED_ARTIFACTS("--permit-unidentified-artifacts", "Keep unidentified artifacts in destination directory") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.permitUnidentifiedArtifacts(); + } + }, + PERMIT_SOURCES_WITHOUT_PACKAGE("--permit-sources-without-package", "Permit sources in the default package") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.permitDefaultPackage(); + } + }, + COMPARE_FOUND_SOURCES("--compare-found-sources", "Compare found sources with given sources") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + Path referenceSourceList = getFileArg(iter, helper, true, false); + if (referenceSourceList != null) + helper.compareFoundSources(referenceSourceList); + } + }, + D("-d", "Output destination directory") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + Path dir = getFileArg(iter, helper, false, true); + if (dir != null) + helper.destDir(dir); + } + }, + S("-s", "Directory for generated sources") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + Path dir = getFileArg(iter, helper, false, true); + if (dir != null) + helper.generatedSourcesDir(dir); + } + }, + H("-h", "Directory for header files") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + Path dir = getFileArg(iter, helper, false, true); + if (dir != null) + helper.headerDir(dir); + } + }; + + public final String arg; + + final String description; + + private Option(String arg, String description) { + this.arg = arg; + this.description = description; + } + + /** Retrieve and verify syntax of file list argument. */ + List getFileListArg(ArgumentIterator iter, OptionHelper helper) { + if (!iter.hasNext()) { + helper.reportError(arg + " must be followed by a list of files " + + "separated by " + File.pathSeparator); + return null; + } + List result = new ArrayList<>(); + for (String pathStr : iter.next().split(File.pathSeparator)) + result.add(Paths.get(pathStr)); + return result; + } + + /** Retrieve and verify syntax of file argument. */ + Path getFileArg(ArgumentIterator iter, OptionHelper helper, boolean fileAcceptable, boolean dirAcceptable) { + + if (!iter.hasNext()) { + String errmsg = arg + " must be followed by "; + if (fileAcceptable && dirAcceptable) errmsg += "a file or directory."; + else if (fileAcceptable) errmsg += "a file."; + else if (dirAcceptable) errmsg += "a directory."; + else throw new IllegalArgumentException("File or directory must be acceptable."); + helper.reportError(errmsg); + return null; + } + + return Paths.get(iter.next()); + } + + /** Retrieve the next file or package argument. */ + String getFilePatternArg(ArgumentIterator iter, OptionHelper helper) { + + if (!iter.hasNext()) { + helper.reportError(arg + " must be followed by a file or directory pattern."); + return null; + } + + return iter.next(); + } + + // Future cleanup: Change the "=" syntax to ":" syntax to be consistent and + // to follow the javac-option style. + + public boolean hasOption() { + return arg.endsWith(":") || arg.endsWith("="); + } + + + /** + * Process current argument of argIter. + * + * It's final, since the option customization is typically done in + * processMatching. + * + * @param argIter Iterator to read current and succeeding arguments from. + * @param helper The helper to report back to. + * @return true iff the argument was processed by this option. + */ + public final boolean processCurrent(ArgumentIterator argIter, + OptionHelper helper) { + String fullArg = argIter.current(); // "-tr" or "-log=level" + if (hasOption() ? fullArg.startsWith(arg) : fullArg.equals(arg)) { + processMatching(argIter, helper); + return true; + } + // Did not match + return false; + } + + /** Called by process if the current argument matches this option. */ + protected abstract void processMatching(ArgumentIterator argIter, + OptionHelper helper); +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java b/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java new file mode 100644 index 00000000000..5fe92cef06d --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java @@ -0,0 +1,146 @@ +/* + * 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.tools.sjavac.options; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +import com.sun.tools.sjavac.Transformer; + +/** + * This class is used to decode sjavac options. + * See com.sun.tools.sjavac.options.Options for example usage. + */ +public abstract class OptionHelper { + + /** Handle error */ + public abstract void reportError(String msg); + + /** Record a package exclusion pattern */ + public abstract void exclude(String excl); + + /** Record a package inclusion pattern */ + public abstract void include(String incl); + + /** Record a file exclusion */ + public abstract void excludeFile(String exclFile); + + /** Record a file inclusion */ + public abstract void includeFile(String inclFile); + + /** Record a root of sources to be compiled */ + public abstract void sourceRoots(List path); + + /** Record a suffix + transformer */ + public abstract void addTransformer(String suffix, Transformer tr); + + /** Record a sourcepath to be used */ + public abstract void sourcepath(List path); + + /** Record a modulepath to be used */ + public abstract void modulepath(List path); + + /** Record a classpath to be used */ + public abstract void classpath(List path); + + /** Record the number of cores */ + public abstract void numCores(int parseInt); + + /** Record desired log level */ + public abstract void logLevel(String level); + + /** Record path for reference source list */ + public abstract void compareFoundSources(Path referenceList); + + /** Record the fact that unidentified artifacts are permitted */ + public abstract void permitUnidentifiedArtifacts(); + + /** Record the fact that sources in the default package are permitted */ + public abstract void permitDefaultPackage(); + + /** Record server configuration parameters */ + public abstract void serverConf(String serverConf); + + /** Record server launch configuration parameters */ + public abstract void startServerConf(String serverConf); + + /** Record some arguments to be passed on to javac */ + public abstract void javacArg(String... arg); + + /** Sets the destination directory for the compilation */ + public abstract void destDir(Path dir); + + /** Sets the directory for generated sources */ + public abstract void generatedSourcesDir(Path genSrcDir); + + /** Sets the directory for generated headers */ + public abstract void headerDir(Path dir); + + /** Sets the implicit policy */ + public abstract void implicit(String policy); + + + /** + * Traverses an array of arguments and performs the appropriate callbacks. + * + * @param args the arguments to traverse. + */ + void traverse(String[] args) { + + ArgumentIterator argIter = new ArgumentIterator(Arrays.asList(args)); + + nextArg: + while (argIter.hasNext()) { + + String arg = argIter.next(); + + if (arg.startsWith("-")) { + for (Option opt : Option.values()) { + if (opt.processCurrent(argIter, this)) + continue nextArg; + } + + javacArg(arg); + + // Does this javac argument take an argument? If so, don't + // let it pass on to sjavac as a source root directory. + for (com.sun.tools.javac.main.Option javacOpt : com.sun.tools.javac.main.Option.values()) { + if (javacOpt.matches(arg)) { + boolean takesArgument = javacOpt.hasArg(); + boolean separateToken = !arg.contains(":") && !arg.contains("="); + if (takesArgument && separateToken) + javacArg(argIter.next()); + } + } + } else { + sourceRoots(Arrays.asList(Paths.get(arg))); + } + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java b/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java new file mode 100644 index 00000000000..e27c6acbfcb --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java @@ -0,0 +1,490 @@ +/* + * 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.tools.sjavac.options; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.tools.sjavac.Transformer; + +/** + * Instances of this class represent values for sjavac command line options. + */ +public class Options { + + // Output directories + private Path destDir, genSrcDir, headerDir; + + // Input directories + private List sources = new ArrayList<>(); + private List sourceSearchPaths = new ArrayList<>(); + private List classSearchPaths = new ArrayList<>(); + private List moduleSearchPaths = new ArrayList<>(); + + private String logLevel = "info"; + + private boolean permitUnidentifiedArtifact = false; + private boolean permitSourcesInDefaultPackage = false; + + private Path sourceReferenceList; + private int numCores = 4; + private String implicitPolicy = "none"; + private List javacArgs = new ArrayList<>(); + + private Map trRules = new HashMap<>(); + + private boolean startServer = false; + + // Server configuration string + private String serverConf; + + /** Get the policy for implicit classes */ + public String getImplicitPolicy() { + return implicitPolicy; + } + + /** Get the path for generated sources (or null if no such path is set) */ + public Path getGenSrcDir() { + return genSrcDir; + } + + /** Get the path for the destination directory */ + public Path getDestDir() { + return destDir; + } + + /** Get the path for the header directory (or null if no such path is set) */ + public Path getHeaderDir() { + return headerDir; + } + + /** Get all source locations for files to be compiled */ + public List getSources() { + return sources; + } + + /** + * Get all paths to search for classes in .java format. (Java-files in + * found here should not be compiled. + */ + public List getSourceSearchPaths() { + return sourceSearchPaths; + } + + /** Get all paths to search for classes in. */ + public List getClassSearchPath() { + return classSearchPaths; + } + + /** Get all paths to search for modules in. */ + public List getModuleSearchPaths() { + return moduleSearchPaths; + } + + /** Get the log level. */ + public String getLogLevel() { + return logLevel; + } + + /** Returns true iff artifacts in the output directories should be kept, + * even if they would not be generated in a clean build. */ + public boolean isUnidentifiedArtifactPermitted() { + return permitUnidentifiedArtifact; + } + + /** Returns true iff sources in the default package should be permitted. */ + public boolean isDefaultPackagePermitted() { + return permitSourcesInDefaultPackage; + } + + /** Get the path to the list of reference sources (or null if none is set) */ + public Path getSourceReferenceList() { + return sourceReferenceList; + } + + /** Get the number of cores to be used by sjavac */ + public int getNumCores() { + return numCores; + } + + /** Returns all arguments relevant to javac but irrelevant to sjavac. */ + public List getJavacArgs() { + return javacArgs; + } + + /** + * Get a map which maps suffixes to transformers (for example + * ".java" -> CompileJavaPackages) + */ + public Map getTranslationRules() { + return trRules; + } + + /** Return true iff a new server should be started */ + public boolean startServerFlag() { + return startServer; + } + + /** Return the server configuration string. */ + public String getServerConf() { + return serverConf; + } + + /** + * Parses the given argument array and returns a corresponding Options + * instance. + */ + public static Options parseArgs(String... args) { + Options options = new Options(); + options.new ArgDecoderOptionHelper().traverse(args); + return options; + } + + /** Returns true iff a .java file is among the javac arguments */ + public boolean isJavaFilesAmongJavacArgs() { + for (String javacArg : javacArgs) + if (javacArg.endsWith(".java")) + return true; + return false; + } + + /** Returns true iff an @-file is among the javac arguments */ + public boolean isAtFilePresent() { + for (String javacArg : javacArgs) + if (javacArg.startsWith("@")) + return true; + return false; + } + + /** + * Returns a string representation of the options that affect the result of + * the compilation. (Used for saving the state of the options used in a + * previous compile.) + */ + public String getStateArgsString() { + + // Local utility class for collecting the arguments + class StateArgs { + + private List args = new ArrayList<>(); + + void addArg(Option opt) { + args.add(opt.arg); + } + + void addArg(Option opt, Object val) { + addArg(opt); + args.add(val.toString()); + } + + void addSourceLocations(Option opt, List locs) { + for (SourceLocation sl : locs) { + for (String pkg : sl.includes) addArg(Option.I, pkg); + for (String pkg : sl.excludes) addArg(Option.X, pkg); + for (String f : sl.excludedFiles) addArg(Option.XF, f); + for (String f : sl.includedFiles) addArg(Option.IF, f); + addArg(opt, sl.getPath()); + } + } + + String getResult() { + String result = ""; + for (String s : args) + result += s + " "; + return result.trim(); + } + + public void addAll(Collection toAdd) { + args.addAll(toAdd); + } + } + + StateArgs args = new StateArgs(); + + // Directories + if (genSrcDir != null) + args.addArg(Option.S, genSrcDir.normalize()); + + if (headerDir != null) + args.addArg(Option.H, headerDir.normalize()); + + if (destDir != null) + args.addArg(Option.D, destDir.normalize()); + + // Source roots + args.addSourceLocations(Option.SRC, sources); + args.addSourceLocations(Option.SOURCEPATH, sourceSearchPaths); + args.addSourceLocations(Option.CLASSPATH, classSearchPaths); + args.addSourceLocations(Option.MODULEPATH, moduleSearchPaths); + + // Boolean options + if (permitSourcesInDefaultPackage) + args.addArg(Option.PERMIT_SOURCES_WITHOUT_PACKAGE); + + if (permitUnidentifiedArtifact) + args.addArg(Option.PERMIT_UNIDENTIFIED_ARTIFACTS); + + // Translation rules + for (Map.Entry tr : trRules.entrySet()) { + String val = tr.getKey() + "=" + tr.getValue().getClass().getName(); + args.addArg(Option.TR, val); + } + + // Javac args + args.addAll(javacArgs); + + return args.getResult(); + } + + + /** Extract the arguments to be passed on to javac. */ + public String[] prepJavacArgs() { + List args = new ArrayList<>(); + + // Output directories + args.add("-d"); + args.add(destDir.toString()); + + if (getGenSrcDir() != null) { + args.add("-s"); + args.add(genSrcDir.toString()); + } + + if (headerDir != null) { + args.add("-h"); + args.add(headerDir.toString()); + } + + // Prep sourcepath + List sourcepath = new ArrayList<>(); + sourcepath.addAll(sources); + sourcepath.addAll(sourceSearchPaths); + if (sourcepath.size() > 0) { + args.add("-sourcepath"); + args.add(concatenateSourceLocations(sourcepath)); + } + + // Prep classpath + if (classSearchPaths.size() > 0) { + args.add("-classpath"); + args.add(concatenateSourceLocations(classSearchPaths)); + } + + // This can't be anything but 'none'. Enforced by sjavac main method. + args.add("-implicit:" + implicitPolicy); + + // Append javac-options (i.e. pass through options not recognized by + // sjavac to javac.) + args.addAll(javacArgs); + + return args.toArray(new String[args.size()]); + } + + // Helper method to join a list of source locations separated by + // File.pathSeparator + private static String concatenateSourceLocations(List locs) { + String s = ""; + for (SourceLocation loc : locs) + s += (s.isEmpty() ? "" : java.io.File.pathSeparator) + loc.getPath(); + return s; + } + + // OptionHelper that records the traversed options in this Options instance. + private class ArgDecoderOptionHelper extends OptionHelper { + + List includes, excludes, includeFiles, excludeFiles; + { + resetFilters(); + } + + boolean headerProvided = false; + boolean genSrcProvided = false; + + @Override + public void reportError(String msg) { + throw new IllegalArgumentException(msg); + } + + @Override + public void sourceRoots(List paths) { + sources.addAll(createSourceLocations(paths)); + } + + @Override + public void exclude(String exclPattern) { + excludes.add(exclPattern); + } + + @Override + public void include(String inclPattern) { + includes.add(inclPattern); + } + + @Override + public void excludeFile(String exclFilePattern) { + excludeFiles.add(exclFilePattern); + } + + @Override + public void includeFile(String inclFilePattern) { + includeFiles.add(inclFilePattern); + } + + @Override + public void addTransformer(String suffix, Transformer tr) { + if (trRules.containsKey(suffix)) { + reportError("More than one transformer specified for " + + "suffix " + suffix + "."); + return; + } + trRules.put(suffix, tr); + } + + @Override + public void sourcepath(List paths) { + sourceSearchPaths.addAll(createSourceLocations(paths)); + } + + @Override + public void modulepath(List paths) { + moduleSearchPaths.addAll(createSourceLocations(paths)); + } + + @Override + public void classpath(List paths) { + classSearchPaths.addAll(createSourceLocations(paths)); + } + + @Override + public void numCores(int n) { + numCores = n; + } + + @Override + public void logLevel(String level) { + logLevel = level; + } + + @Override + public void compareFoundSources(Path referenceList) { + sourceReferenceList = referenceList; + } + + @Override + public void permitUnidentifiedArtifacts() { + permitUnidentifiedArtifact = true; + } + + @Override + public void permitDefaultPackage() { + permitSourcesInDefaultPackage = true; + } + + @Override + public void serverConf(String conf) { + if (serverConf != null) + reportError("Can not specify more than one server configuration."); + else + serverConf = conf; + } + + @Override + public void implicit(String policy) { + implicitPolicy = policy; + } + + @Override + public void startServerConf(String conf) { + if (serverConf != null) + reportError("Can not specify more than one server configuration."); + else { + startServer = true; + serverConf = conf; + } + } + + @Override + public void javacArg(String... arg) { + javacArgs.addAll(Arrays.asList(arg)); + } + + @Override + public void destDir(Path dir) { + if (destDir != null) { + reportError("Destination directory already specified."); + return; + } + destDir = dir.toAbsolutePath(); + } + + @Override + public void generatedSourcesDir(Path dir) { + if (genSrcProvided) { + reportError("Directory for generated sources already specified."); + return; + } + genSrcProvided = true; + genSrcDir = dir.toAbsolutePath(); + } + + @Override + public void headerDir(Path dir) { + if (headerProvided) { + reportError("Header directory already specified."); + return; + } + headerProvided = true; + headerDir = dir.toAbsolutePath(); + } + + private List createSourceLocations(List paths) { + List result = new ArrayList<>(); + for (Path path : paths) { + result.add(new SourceLocation( + path, + includes, + excludes, + includeFiles, + excludeFiles)); + } + resetFilters(); + return result; + } + + private void resetFilters() { + includes = new ArrayList<>(); + excludes = new ArrayList<>(); + includeFiles = new ArrayList<>(); + excludeFiles = new ArrayList<>(); + } + } + +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/options/SourceLocation.java b/langtools/src/share/classes/com/sun/tools/sjavac/options/SourceLocation.java new file mode 100644 index 00000000000..b643cd64643 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/SourceLocation.java @@ -0,0 +1,115 @@ +/* + * 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.tools.sjavac.options; + +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.sun.tools.sjavac.Module; +import com.sun.tools.sjavac.ProblemException; +import com.sun.tools.sjavac.Source; + +/** + * Represents a directory to be used for input to sjavac. (For instance a + * sourcepath or classpath.) + */ +public class SourceLocation { + + // Path to the root directory + private Path path; + + // Package include / exclude patterns and file includes / excludes. + List includes, excludes, includedFiles, excludedFiles; + + public SourceLocation(Path path, + List includes, + List excludes, + List includedFiles, + List excludedFiles) { + this.path = path; + this.includes = includes; + this.excludes = excludes; + this.includedFiles = includedFiles; + this.excludedFiles = excludedFiles; + } + + + /** + * Finds all files with the given suffix that pass the include / exclude + * filters in this source location. + * + * @param suffixes The set of suffixes to search for + * @param foundFiles The map in which to store the found files + * @param foundModules The map in which to store the found modules + * @param currentModule The current module + * @param permitSourcesInDefaultPackage true if sources in default package + * are to be permitted + * @param inLinksrc true if in link source + */ + public void findSourceFiles(Set suffixes, + Map foundFiles, + Map foundModules, + Module currentModule, + boolean permitSourcesInDefaultPackage, + boolean inLinksrc) { + try { + Source.scanRoot(path.toFile(), suffixes, excludes, includes, + excludedFiles, includedFiles, foundFiles, foundModules, + currentModule, permitSourcesInDefaultPackage, false, + inLinksrc); + } catch (ProblemException e) { + e.printStackTrace(); + } + } + + /** Get the root directory of this source location */ + public Path getPath() { + return path; + } + + /** Get the package include patterns */ + public List getIncludes() { + return includes; + } + + /** Get the package exclude patterns */ + public List getExcludes() { + return excludes; + } + + /** Get the file include patterns */ + public List getIncludedFiles() { + return includedFiles; + } + + /** Get the file exclude patterns */ + public List getExcludedFiles() { + return excludedFiles; + } + +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java index 94eb1e609b0..2592a423965 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java @@ -104,6 +104,17 @@ public class JavacServer { allPortFiles = new HashMap<>(); } PortFile pf = allPortFiles.get(filename); + + // Port file known. Does it still exist? + if (pf != null) { + try { + if (!pf.exists()) + pf = null; + } catch (IOException ioex) { + ioex.printStackTrace(); + } + } + if (pf == null) { pf = new PortFile(filename); allPortFiles.put(filename, pf); @@ -305,7 +316,7 @@ public class JavacServer { // We could not connect to the server. Try again. attempts++; try { - Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS); + Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS * 1000); } catch (InterruptedException e) { } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java b/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java index 511b1ca77af..f2540a20ab6 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 diff --git a/langtools/test/com/sun/javadoc/5093723/T5093723.java b/langtools/test/com/sun/javadoc/5093723/T5093723.java index 1b23bb1a979..8bea133cc07 100644 --- a/langtools/test/com/sun/javadoc/5093723/T5093723.java +++ b/langtools/test/com/sun/javadoc/5093723/T5093723.java @@ -33,10 +33,8 @@ public class T5093723 extends JavadocTester { - private static final String BUG_ID = "5093723"; - private static final String[] ARGS = new String[] { - "-d", BUG_ID + ".out", "-Xdoclint:none", + "-d", OUTPUT_DIR + ".out", "-Xdoclint:none", SRC_DIR + "/DocumentedClass.java", SRC_DIR + "/UndocumentedClass.java" }; @@ -46,12 +44,4 @@ public class T5093723 extends JavadocTester { if (tester.runJavadoc(ARGS) != 0) throw new AssertionError("non-zero return code from javadoc"); } - - public String getBugId() { - return BUG_ID; - } - - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java b/langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java index 009d9877192..0aa3aca9852 100644 --- a/langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java +++ b/langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java @@ -34,30 +34,27 @@ public class AccessSummary extends JavadocTester { - private static final String BUG_ID = "4637604-4775148"; - private static final String OUTPUT_DIR1 = "docs1-" + BUG_ID + "/"; - /** * Assign value for [ fileToSearch, stringToFind ] */ private static final String[][] TESTARRAY1 = { // Test that the summary attribute appears - { OUTPUT_DIR1 + "overview-summary.html", + { "overview-summary.html", "summary=\"Packages table, listing packages, and an explanation\"" }, // Test that the summary attribute appears - { OUTPUT_DIR1 + "p1/C1.html", + { "p1/C1.html", "summary=\"Constructor Summary table, listing constructors, and an explanation\"" }, // Test that the summary attribute appears - { OUTPUT_DIR1 + "constant-values.html", + { "constant-values.html", "summary=\"Constant Field Values table, listing constant fields, and values\"" } }; // First test with -header only private static final String[] JAVADOC_ARGS = new String[] { - "-d", OUTPUT_DIR1, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "p1", "p2"}; @@ -67,21 +64,7 @@ public class AccessSummary extends JavadocTester { */ public static void main(String[] args) { JavadocTester tester = new AccessSummary(); - run(tester, JAVADOC_ARGS, TESTARRAY1, new String[][] {}); + tester.run(JAVADOC_ARGS, TESTARRAY1, new String[][] {}); tester.printSummary(); // Necessary for string search } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java b/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java index 893d1185938..49456b5bfa0 100644 --- a/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java +++ b/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java @@ -39,8 +39,6 @@ import java.util.Date; public class MetaTag extends JavadocTester { //Test information. - private static final String BUG_ID = "4034096-4764726-6235799"; - private static final String OUTPUT_DIR = "docs-" + BUG_ID; private static final SimpleDateFormat m_dateFormat = new SimpleDateFormat("yyyy-MM-dd"); //Javadoc arguments. @@ -63,65 +61,62 @@ public class MetaTag extends JavadocTester { //Input for string search tests. private static final String[][] TEST = { - { OUTPUT_DIR + "/p1/C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "/p1/C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "/p1/C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "/p1/C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "/p1/C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "/p1/package-summary.html", + { "p1/package-summary.html", "" }, - { OUTPUT_DIR + "/overview-summary.html", + { "overview-summary.html", "" }, //NOTE: Hopefully, this regression test is not run at midnight. If the output //was generated yesterday and this test is run today, the test will fail. - {OUTPUT_DIR + "/overview-summary.html", + { "overview-summary.html", ""}, }; - private static final String[][] NEGATED_TEST = NO_TEST; - - private static final String[][] TEST2 = NO_TEST; private static final String[][] NEGATED_TEST2 = { //No keywords when -keywords is not used. - { OUTPUT_DIR + "-2/p1/C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "-2/p1/C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "-2/p1/C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "-2/p1/C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "-2/p1/C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "-2/p1/package-summary.html", + { "p1/package-summary.html", "" }, - { OUTPUT_DIR + "-2/overview-summary.html", + { "overview-summary.html", "" }, //The date metatag should not show up when -notimestamp is used. //NOTE: Hopefully, this regression test is not run at midnight. If the output //was generated yesterday and this test is run today, the test will fail. - {OUTPUT_DIR + "-2/overview-summary.html", + { "overview-summary.html", ""}, }; @@ -132,22 +127,8 @@ public class MetaTag extends JavadocTester { */ public static void main(String[] args) { MetaTag tester = new MetaTag(); - run(tester, ARGS, TEST, NEGATED_TEST); - run(tester, ARGS_NO_TIMESTAMP_NO_KEYWORDS, TEST2, NEGATED_TEST2); + tester.run(ARGS, TEST, NO_TEST); + tester.run(ARGS_NO_TIMESTAMP_NO_KEYWORDS, NO_TEST, NEGATED_TEST2); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java b/langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java index 159797af0ee..aa7ba2dbb9e 100644 --- a/langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java +++ b/langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java @@ -37,12 +37,9 @@ public class PackagesHeader extends JavadocTester { //Test information. - private static final String BUG_ID = "4766385"; - private static final String OUTPUT_DIR = "docs-" + BUG_ID; - - private static final String OUTPUT_DIR1 = "docs1-" + BUG_ID + "/"; - private static final String OUTPUT_DIR2 = "docs2-" + BUG_ID + "/"; - private static final String OUTPUT_DIR3 = "docs3-" + BUG_ID + "/"; + private static final String OUTPUT_DIR1 = OUTPUT_DIR + "-1/"; + private static final String OUTPUT_DIR2 = OUTPUT_DIR + "-2/"; + private static final String OUTPUT_DIR3 = OUTPUT_DIR + "-3/"; /** * Assign value for [ fileToSearch, stringToFind ] @@ -50,7 +47,7 @@ public class PackagesHeader extends JavadocTester { private static final String[][] TESTARRAY1 = { // Test that the -header shows up in the packages frame - { OUTPUT_DIR1 + "overview-frame.html", + { "overview-frame.html", "Main Frame Header" } }; @@ -59,7 +56,7 @@ public class PackagesHeader extends JavadocTester { // Test that the -packagesheader string shows // up in the packages frame - { OUTPUT_DIR2 + "overview-frame.html", + { "overview-frame.html", "Packages Frame Header" } }; @@ -67,10 +64,10 @@ public class PackagesHeader extends JavadocTester { // Test that the both headers show up and are different - { OUTPUT_DIR3 + "overview-frame.html", + { "overview-frame.html", "Packages Frame Header" }, - { OUTPUT_DIR3 + "overview-summary.html", + { "overview-summary.html", "Main Frame Header" } }; @@ -97,9 +94,6 @@ public class PackagesHeader extends JavadocTester { "p1", "p2"}; - //Input for string search tests. - private static final String[][] NEGATED_TEST = NO_TEST; - /** * The entry point of the test. * @param args the array of command line arguments. @@ -107,24 +101,10 @@ public class PackagesHeader extends JavadocTester { public static void main(String[] args) { JavadocTester tester = new PackagesHeader(); - run(tester, JAVADOC_ARGS1, TESTARRAY1, NEGATED_TEST); - run(tester, JAVADOC_ARGS2, TESTARRAY2, NEGATED_TEST); - run(tester, JAVADOC_ARGS3, TESTARRAY3, NEGATED_TEST); + tester.run(JAVADOC_ARGS1, TESTARRAY1, NO_TEST); + tester.run(JAVADOC_ARGS2, TESTARRAY2, NO_TEST); + tester.run(JAVADOC_ARGS3, TESTARRAY3, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/T6735320/T6735320.java b/langtools/test/com/sun/javadoc/T6735320/T6735320.java index 21c82a99beb..531e4a64bba 100644 --- a/langtools/test/com/sun/javadoc/T6735320/T6735320.java +++ b/langtools/test/com/sun/javadoc/T6735320/T6735320.java @@ -31,20 +31,11 @@ */ public class T6735320 extends JavadocTester { - private static final String BUG_ID = "6735320"; private static final String[] ARGS = new String[]{ - "-d", BUG_ID + ".out", + "-d", OUTPUT_DIR + ".out", SRC_DIR + "/SerialFieldTest.java" }; - public String getBugId() { - return BUG_ID; - } - - public String getBugName() { - return getClass().getName(); - } - public static void main(String... args) { T6735320 tester = new T6735320(); if (tester.runJavadoc(ARGS) == 0) { diff --git a/langtools/test/com/sun/javadoc/_template/Template.java b/langtools/test/com/sun/javadoc/_template/Template.java index 484a1ad3d43..92a36f867df 100644 --- a/langtools/test/com/sun/javadoc/_template/Template.java +++ b/langtools/test/com/sun/javadoc/_template/Template.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -33,10 +33,6 @@ public class Template extends JavadocTester { - //Test information. - private static final String BUG_ID = ""; - private static final String OUTPUT_DIR = "docs-" + BUG_ID; - //Javadoc arguments. private static final String[] ARGS = new String[] { "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR @@ -52,21 +48,7 @@ public class Template extends JavadocTester { */ public static void main(String[] args) { Template tester = new Template(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/_template/TemplateComplete.java b/langtools/test/com/sun/javadoc/_template/TemplateComplete.java index 5c63487e977..cb15e989a35 100644 --- a/langtools/test/com/sun/javadoc/_template/TemplateComplete.java +++ b/langtools/test/com/sun/javadoc/_template/TemplateComplete.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -33,10 +33,6 @@ public class TemplateComplete extends JavadocTester { - //Test information. - private static final String BUG_ID = ""; - private static final String OUTPUT_DIR = "docs-" + BUG_ID; - //Javadoc arguments. private static final String[] ARGS = new String[] { "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR @@ -51,6 +47,8 @@ public class TemplateComplete extends JavadocTester { //Input for file diff test. + private static final String DIFFDIR1 = null; + private static final String DIFFDIR2 = null; private static final String[][] FILES_TO_DIFF = {}; /** @@ -59,23 +57,9 @@ public class TemplateComplete extends JavadocTester { */ public static void main(String[] args) { TemplateComplete tester = new TemplateComplete(); - int actualExitCode = run(tester, ARGS, TEST, NEGATED_TEST); + int actualExitCode = tester.run(ARGS, TEST, NEGATED_TEST); tester.checkExitCode(EXPECTED_EXIT_CODE, actualExitCode); - tester.runDiffs(FILES_TO_DIFF, false); + tester.runDiffs(DIFFDIR1, DIFFDIR2, FILES_TO_DIFF, false); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/constantValues/TestConstantValuesDriver.java b/langtools/test/com/sun/javadoc/constantValues/TestConstantValuesDriver.java index 23ffb0d27d0..5c17d7ede6f 100644 --- a/langtools/test/com/sun/javadoc/constantValues/TestConstantValuesDriver.java +++ b/langtools/test/com/sun/javadoc/constantValues/TestConstantValuesDriver.java @@ -33,9 +33,8 @@ */ public class TestConstantValuesDriver extends JavadocTester { - private static final String BUG_ID = "4504730-4526070-5077317"; private static final String[] ARGS = new String[] { - "-d", BUG_ID, SRC_DIR + "/TestConstantValues.java", + "-d", OUTPUT_DIR, SRC_DIR + "/TestConstantValues.java", SRC_DIR + "/TestConstantValues2.java", SRC_DIR + "/A.java" }; @@ -47,30 +46,16 @@ public class TestConstantValuesDriver extends JavadocTester { public static void main(String[] args) { String[][] tests = new String[5][2]; for (int i = 0; i < tests.length-1; i++) { - tests[i][0] = BUG_ID + "/constant-values.html"; + tests[i][0] = "constant-values.html"; tests[i][1] = "TEST"+(i+1)+"PASSES"; } - tests[tests.length-1][0] = BUG_ID + "/constant-values.html"; + tests[tests.length-1][0] = "constant-values.html"; tests[tests.length-1][1] = "\"<Hello World>\""; TestConstantValuesDriver tester = new TestConstantValuesDriver(); - run(tester, ARGS, tests, NO_TEST); + tester.run(ARGS, tests, NO_TEST); tester.printSummary(); } - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } - /** * @throws java.io.IOException Test 1 passes * @throws java.io.IOException Test 2 passes diff --git a/langtools/test/com/sun/javadoc/dupThrowsTags/TestDupThrowsTags.java b/langtools/test/com/sun/javadoc/dupThrowsTags/TestDupThrowsTags.java index b5c63a37f98..b186e6165d8 100644 --- a/langtools/test/com/sun/javadoc/dupThrowsTags/TestDupThrowsTags.java +++ b/langtools/test/com/sun/javadoc/dupThrowsTags/TestDupThrowsTags.java @@ -33,9 +33,8 @@ */ public class TestDupThrowsTags extends JavadocTester { - private static final String BUG_ID = "4525364"; private static final String[] ARGS = new String[] { - "-d", BUG_ID, SRC_DIR + "/TestDupThrowsTags.java" + "-d", OUTPUT_DIR, SRC_DIR + "/TestDupThrowsTags.java" }; /** @@ -45,28 +44,14 @@ public class TestDupThrowsTags extends JavadocTester { public static void main(String[] args) { String[][] tests = new String[4][2]; for (int i = 0; i < tests.length; i++) { - tests[i][0] = BUG_ID + "/TestDupThrowsTags.html"; + tests[i][0] = "TestDupThrowsTags.html"; tests[i][1] = "Test "+(i+1)+" passes"; } TestDupThrowsTags tester = new TestDupThrowsTags(); - run(tester, ARGS, tests, NO_TEST); + tester.run(ARGS, tests, NO_TEST); tester.printSummary(); } - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } - /** * @throws java.io.IOException Test 1 passes * @throws java.io.IOException Test 2 passes diff --git a/langtools/test/com/sun/javadoc/lib/JavadocTester.java b/langtools/test/com/sun/javadoc/lib/JavadocTester.java index c7b6ab2e939..5149d9301fc 100644 --- a/langtools/test/com/sun/javadoc/lib/JavadocTester.java +++ b/langtools/test/com/sun/javadoc/lib/JavadocTester.java @@ -21,8 +21,6 @@ * questions. */ -import com.sun.javadoc.*; -import java.util.*; import java.io.*; @@ -56,6 +54,7 @@ public abstract class JavadocTester { protected static final String SRC_DIR = System.getProperty("test.src", "."); protected static final String JAVA_VERSION = System.getProperty("java.version"); + protected static final String OUTPUT_DIR = "out"; protected static final String[][] NO_TEST = new String[][] {}; protected static final String[] NO_FILE_TEST = new String[] {}; @@ -105,10 +104,15 @@ public abstract class JavadocTester { public StringWriter warnings; /** - * The buffer of warning output.. + * The buffer of warning output. */ public StringBuffer standardOut; + /** + * The output directory. + */ + private File outputDir; + /** * The current subtest number. */ @@ -130,38 +134,24 @@ public abstract class JavadocTester { public JavadocTester() { } - /** - * Return the bug id. - * @return the bug id - */ - public abstract String getBugId(); - - /** - * Return the name of the bug. - * @return the name of the bug - */ - public abstract String getBugName(); - /** * Execute the tests. * - * @param tester the tester to execute * @param args the arguments to pass to Javadoc * @param testArray the array of tests * @param negatedTestArray the array of negated tests * @return the return code for the execution of Javadoc */ - public static int run(JavadocTester tester, String[] args, + public int run(String[] args, String[][] testArray, String[][] negatedTestArray) { - int returnCode = tester.runJavadoc(args); - tester.runTestsOnHTML(testArray, negatedTestArray); + int returnCode = runJavadoc(args); + runTestsOnHTML(testArray, negatedTestArray); return returnCode; } /** * Execute the tests. * - * @param tester the tester to execute * @param args the arguments to pass to Javadoc * @param testArray the array of tests * @param negatedTestArray the array of negated tests @@ -169,12 +159,12 @@ public abstract class JavadocTester { * @param negatedFileTestArray the array of negated file tests * @return the return code for the execution of Javadoc */ - public static int run(JavadocTester tester, String[] args, - String[][] testArray, String[][] negatedTestArray, String[] fileTestArray, - String[] negatedFileTestArray) { - int returnCode = tester.runJavadoc(args); - tester.runTestsOnHTML(testArray, negatedTestArray); - tester.runTestsOnFile(fileTestArray, negatedFileTestArray); + public int run(String[] args, + String[][] testArray, String[][] negatedTestArray, + String[] fileTestArray, String[] negatedFileTestArray) { + int returnCode = runJavadoc(args); + runTestsOnHTML(testArray, negatedTestArray); + runTestsOnFile(fileTestArray, negatedFileTestArray); return returnCode; } @@ -208,6 +198,13 @@ public abstract class JavadocTester { + javadocRunNum + ")..."); } initOutputBuffers(); + outputDir = new File("."); + for (int i = 0; i < args.length - 2; i++) { + if (args[i].equals("-d")) { + outputDir = new File(args[++i]); + break; + } + } ByteArrayOutputStream stdout = new ByteArrayOutputStream(); PrintStream prevOut = System.out; @@ -218,7 +215,7 @@ public abstract class JavadocTester { System.setErr(new PrintStream(stderr)); int returnCode = com.sun.tools.javadoc.Main.execute( - getBugName(), + "javadoc", new PrintWriter(errors, true), new PrintWriter(warnings, true), new PrintWriter(notices, true), @@ -260,60 +257,53 @@ public abstract class JavadocTester { * Run array of tests on the generated files. * This method accepts a fileTestArray for testing if a file is generated * and a negatedFileTestArray for testing if a file is not found. + * The files are relative to the most recent output directory specified + * with -d. * - * @param testArray the array of file tests - * @param negatedTestArray the array of negated file tests + * @param fileTestArray the array of file tests + * @param negatedFileTestArray the array of negated file tests */ public void runTestsOnFile(String[] fileTestArray, String[] negatedFileTestArray) { - runTestsOnFile(fileTestArray, false); - runTestsOnFile(negatedFileTestArray, true); + runTestsOnFile(outputDir, fileTestArray, false); + runTestsOnFile(outputDir, negatedFileTestArray, true); } /** * Run the array of tests on the resulting HTML. + * The files are relative to the most recent output directory specified + * with -d. * * @param testArray the array of tests * @param isNegated true if test is negated; false otherwise */ private void runTestsOnHTML(String[][] testArray , boolean isNegated) { - for (int i = 0; i < testArray.length; i++) { - + for (String[] test : testArray) { numTestsRun++; - System.out.print("Running subtest #" + numTestsRun + "... "); - // Get string to find - String stringToFind = testArray[i][1]; - + String stringToFind = test[1]; // Read contents of file into a string String fileString; try { - fileString = readFileToString(testArray[i][0]); + fileString = readFileToString(outputDir, test[0]); } catch (Error e) { if (isNegated) { - System.out.println( "FAILED" + "\n" - + "for bug " + getBugId() - + " (" + getBugName() + ") " - + "due to " - + e + "\n"); - continue; + System.out.println( "FAILED, due to " + e + "\n"); + continue; } throw e; } // Find string in file's contents boolean isFound = findString(fileString, stringToFind); - if ((isNegated && !isFound) || (!isNegated && isFound) ) { + if ((isNegated && !isFound) || (!isNegated && isFound)) { numTestsPassed += 1; - System.out.println( "Passed" + "\n" - + (isNegated ? "not found:" : "found:") + "\n" - + stringToFind + " in " + testArray[i][0] + "\n"); + System.out.println("Passed" + "\n" + + (isNegated ? "not found:" : "found:") + "\n" + + stringToFind + " in " + test[0] + "\n"); } else { - System.out.println( "FAILED" + "\n" - + "for bug " + getBugId() - + " (" + getBugName() + ")" + "\n" - + "when searching for:" + "\n" - + stringToFind - + " in " + testArray[i][0] + "\n"); + System.out.println("FAILED, when searching for:" + "\n" + + stringToFind + + " in " + test[0] + "\n"); } } } @@ -324,21 +314,15 @@ public abstract class JavadocTester { * @param testArray the array of file tests * @param isNegated true if test is negated; false otherwise */ - private void runTestsOnFile(String[] testArray, boolean isNegated) { - String fileName; - String failedString; - String passedString; - for (int i = 0; i < testArray.length; i++) { + private void runTestsOnFile(File baseDir, String[] testArray, boolean isNegated) { + for (String fileName : testArray) { numTestsRun++; - fileName = testArray[i]; - failedString = "FAILED" + "\n" - + "for bug " + getBugId() + " (" + getBugName() + ") " - + "file (" + fileName + ") found" + "\n"; - passedString = "Passed" + "\n" + - "file (" + fileName + ") not found" + "\n"; + String failedString = "FAILED: file (" + fileName + ") found" + "\n"; + String passedString = "Passed" + "\n" + + "file (" + fileName + ") not found" + "\n"; System.out.print("Running subtest #" + numTestsRun + "... "); try { - File file = new File(fileName); + File file = new File(baseDir, fileName); if ((file.exists() && !isNegated) || (!file.exists() && isNegated)) { numTestsPassed += 1; System.out.println(passedString); @@ -354,27 +338,33 @@ public abstract class JavadocTester { /** * Iterate through the list of given file pairs and diff each file. * - * @param filePairs the pairs of files to diff. - * @throws an Error is thrown if any differences are found between + * @param baseDir1 the directory containing the first set of files + * @param baseDir2 the directory containing the second set of files + * @param files the set of files to be compared + * @throws Error if any differences are found between * file pairs. */ - public void runDiffs(String[][] filePairs) throws Error { - runDiffs(filePairs, true); + public void runDiffs(String baseDir1, String baseDir2, String[] files) throws Error { + runDiffs(baseDir1, baseDir2, files, true); } /** * Iterate through the list of given file pairs and diff each file. * - * @param filePairs the pairs of files to diff. - * @param throwErrorIFNoMatch flag to indicate whether or not to throw + * @param baseDir1 the directory containing the first set of files + * @param baseDir2 the directory containing the second set of files + * @param files the set of files to be compared + * @param throwErrorIfNoMatch flag to indicate whether or not to throw * an error if the files do not match. * - * @throws an Error is thrown if any differences are found between - * file pairs and throwErrorIFNoMatch is true. + * @throws Error if any differences are found between + * file pairs and throwErrorIfNoMatch is true. */ - public void runDiffs(String[][] filePairs, boolean throwErrorIfNoMatch) throws Error { - for (int i = 0; i < filePairs.length; i++) { - diff(filePairs[i][0], filePairs[i][1], throwErrorIfNoMatch); + public void runDiffs(String baseDir1, String baseDir2, String[] files, boolean throwErrorIfNoMatch) throws Error { + File bd1 = new File(baseDir1); + File bd2 = new File(baseDir2); + for (String file : files) { + diff(bd1, bd2, file, throwErrorIfNoMatch); } } @@ -394,8 +384,7 @@ public abstract class JavadocTester { actualExitCode); numTestsPassed++; } else { - System.out.println( "FAILED" + "\n" + "for bug " + getBugId() - + " (" + getBugName() + ")" + "\n" + "Expected return code " + + System.out.println( "FAILED: expected return code " + expectedExitCode + " but got " + actualExitCode); } } @@ -412,8 +401,7 @@ public abstract class JavadocTester { // Test failed throw new Error("\n" + (numTestsRun - numTestsPassed) + " of " + (numTestsRun) - + " subtests failed for bug " + getBugId() - + " (" + getBugName() + ")" + "\n"); + + " subtests failed\n"); } } @@ -434,28 +422,39 @@ public abstract class JavadocTester { * @return the file in string format */ public String readFileToString(String fileName) throws Error { - if (fileName.equals(ERROR_OUTPUT)) { - return getErrorOutput(); - } else if (fileName.equals(NOTICE_OUTPUT)) { - return getNoticeOutput(); - } else if (fileName.equals(WARNING_OUTPUT)) { - return getWarningOutput(); - } else if (fileName.equals(STANDARD_OUTPUT)) { - return getStandardOutput(); + return readFileToString(outputDir, fileName); + } + + /** + * Read the file and return it as a string. + * + * @param baseDir the directory in which to locate the file + * @param fileName the name of the file to read + * @return the file in string format + */ + private String readFileToString(File baseDir, String fileName) throws Error { + switch (fileName) { + case ERROR_OUTPUT: + return getErrorOutput(); + case NOTICE_OUTPUT: + return getNoticeOutput(); + case WARNING_OUTPUT: + return getWarningOutput(); + case STANDARD_OUTPUT: + return getStandardOutput(); } try { - File file = new File(fileName); + File file = new File(baseDir, fileName); if ( !file.exists() ) { System.out.println("\n" + "FILE DOES NOT EXIST: " + fileName); } - BufferedReader in = new BufferedReader(new FileReader(file)); - - // Create an array of characters the size of the file - char[] allChars = new char[(int)file.length()]; - - // Read the characters into the allChars array - in.read(allChars, 0, (int)file.length()); - in.close(); + char[] allChars; + try (BufferedReader in = new BufferedReader(new FileReader(file))) { + // Create an array of characters the size of the file + allChars = new char[(int)file.length()]; + // Read the characters into the allChars array + in.read(allChars, 0, (int)file.length()); + } // Convert to a string String allCharsString = new String(allChars); @@ -472,22 +471,24 @@ public abstract class JavadocTester { /** * Compare the two given files. * - * @param file1 the first file to compare. - * @param file2 the second file to compare. + * @param baseDir1 the directory in which to locate the first file + * @param baseDir2 the directory in which to locate the second file + * @param file the file to compare in the two base directories * @param throwErrorIFNoMatch flag to indicate whether or not to throw * an error if the files do not match. * @return true if the files are the same and false otherwise. */ - public boolean diff(String file1, String file2, boolean throwErrorIFNoMatch) throws Error { - String file1Contents = readFileToString(file1); - String file2Contents = readFileToString(file2); + private boolean diff(File baseDir1, File baseDir2, String file, + boolean throwErrorIFNoMatch) throws Error { + String file1Contents = readFileToString(baseDir1, file); + String file2Contents = readFileToString(baseDir2, file); numTestsRun++; if (file1Contents.trim().compareTo(file2Contents.trim()) == 0) { - System.out.println("Diff successful: " + file1 + ", " + file2); + System.out.println("Diff successful: " + new File(baseDir1, file) + ", " + new File(baseDir2, file)); numTestsPassed++; return true; } else if (throwErrorIFNoMatch) { - throw new Error("Diff failed: " + file1 + ", " + file2); + throw new Error("Diff failed: " + new File(baseDir1, file) + ", " + new File(baseDir2, file)); } else { return false; } @@ -561,12 +562,12 @@ public abstract class JavadocTester { destDirObj.mkdir(); } String[] files = targetDirObj.list(); - for (int i = 0; i < files.length; i++) { - File srcFile = new File(targetDirObj, files[i]); - File destFile = new File(destDirObj, files[i]); + for (String file : files) { + File srcFile = new File(targetDirObj, file); + File destFile = new File(destDirObj, file); if (srcFile.isFile()) { System.out.println("Copying " + srcFile + " to " + destFile); - copyFile(destFile, srcFile); + copyFile(destFile, srcFile); } else if(srcFile.isDirectory()) { copyDir(srcFile.getAbsolutePath(), destDirObj.getAbsolutePath()); } @@ -579,13 +580,15 @@ public abstract class JavadocTester { /** * Copy source file to destination file. * + * @param destfile the destination file + * @param srcfile the source file * @throws SecurityException * @throws IOException */ public static void copyFile(File destfile, File srcfile) throws IOException { byte[] bytearr = new byte[512]; - int len = 0; + int len; FileInputStream input = new FileInputStream(srcfile); File destDir = destfile.getParentFile(); destDir.mkdirs(); @@ -594,8 +597,7 @@ public abstract class JavadocTester { while ((len = input.read(bytearr)) != -1) { output.write(bytearr, 0, len); } - } catch (FileNotFoundException exc) { - } catch (SecurityException exc) { + } catch (FileNotFoundException | SecurityException exc) { } finally { input.close(); output.close(); diff --git a/langtools/test/com/sun/javadoc/testAbsLinkPath/TestAbsLinkPath.java b/langtools/test/com/sun/javadoc/testAbsLinkPath/TestAbsLinkPath.java index e76b86e5e66..292f571a185 100644 --- a/langtools/test/com/sun/javadoc/testAbsLinkPath/TestAbsLinkPath.java +++ b/langtools/test/com/sun/javadoc/testAbsLinkPath/TestAbsLinkPath.java @@ -34,10 +34,8 @@ public class TestAbsLinkPath extends JavadocTester { - private static final String BUG_ID = "4640745"; private static final String[][] TEST = { - {"tmp/pkg1/C1.html", "C2.html"}}; - private static final String[][] NEGATED_TEST = NO_TEST; + { "pkg1/C1.html", "C2.html"}}; private static final String[] ARGS1 = new String[] { @@ -53,22 +51,8 @@ public class TestAbsLinkPath extends JavadocTester { */ public static void main(String[] args) { TestAbsLinkPath tester = new TestAbsLinkPath(); - run(tester, ARGS1, NO_TEST, NO_TEST); - run(tester, ARGS2, TEST, NEGATED_TEST); + tester.run(ARGS1, NO_TEST, NO_TEST); + tester.run(ARGS2, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testAbstractMethod/TestAbstractMethod.java b/langtools/test/com/sun/javadoc/testAbstractMethod/TestAbstractMethod.java index 1c5c9152518..600affee6d2 100644 --- a/langtools/test/com/sun/javadoc/testAbstractMethod/TestAbstractMethod.java +++ b/langtools/test/com/sun/javadoc/testAbstractMethod/TestAbstractMethod.java @@ -35,18 +35,17 @@ public class TestAbstractMethod extends JavadocTester { //Test information. - private static final String BUG_ID = "8004891"; //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + "/pkg/A.html", + { "pkg/A.html", "default void"}, - {BUG_ID + "/pkg/A.html", + { "pkg/A.html", "" + "All Methods " + "" + @@ -57,7 +56,7 @@ public class TestAbstractMethod extends JavadocTester { "" + "Default Methods" + " "}, - {BUG_ID + "/pkg/B.html", + { "pkg/B.html", "" + "All Methods " + "" + @@ -68,9 +67,9 @@ public class TestAbstractMethod extends JavadocTester { "" + "Concrete Methods" + " "}, - {BUG_ID + "/pkg/B.html", + { "pkg/B.html", "abstract void"}, - {BUG_ID + "/pkg/C.html", + { "pkg/C.html", "" + "All Methods " + "" + @@ -79,18 +78,18 @@ public class TestAbstractMethod extends JavadocTester { "" + "Default Methods" + " "}, - {BUG_ID + "/pkg/C.html", + { "pkg/C.html", "default void"} }; private static final String[][] NEGATED_TEST = { - {BUG_ID + "/pkg/A.html", + { "pkg/A.html", "abstract void"}, - {BUG_ID + "/pkg/B.html", + { "pkg/B.html", "Default Methods" + " "}, - {BUG_ID + "/pkg/B.html", + { "pkg/B.html", "default void"}, - {BUG_ID + "/pkg/C.html", + { "pkg/C.html", "Abstract Methods" + " "} }; @@ -101,21 +100,7 @@ public class TestAbstractMethod extends JavadocTester { */ public static void main(String[] args) { TestAbstractMethod tester = new TestAbstractMethod(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java b/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java index f4b69c897d1..af2472924fb 100644 --- a/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java +++ b/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java @@ -33,41 +33,40 @@ public class TestAnchorNames extends JavadocTester { - private static final String BUG_ID = "8025633"; //Input for string search tests. private static final String[][] TEST = { //Test some section markers and links to these markers - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, @@ -75,170 +74,170 @@ public class TestAnchorNames extends JavadocTester { //The marker for this appears in the serialized-form.html which we will //test below - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, //Test some fields - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/DeprMemClass.html", + { "pkg1/DeprMemClass.html", "" }, - {BUG_ID + "/pkg1/DeprMemClass.html", + { "pkg1/DeprMemClass.html", "" }, //Test constructor - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, //Test some methods - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", "" }, - {BUG_ID + "/pkg1/DeprMemClass.html", + { "pkg1/DeprMemClass.html", "" }, - {BUG_ID + "/pkg1/DeprMemClass.html", + { "pkg1/DeprMemClass.html", "" }, //Test enum - {BUG_ID + "/pkg1/RegClass.Te$t_Enum.html", + { "pkg1/RegClass.Te$t_Enum.html", "" }, - {BUG_ID + "/pkg1/RegClass.Te$t_Enum.html", + { "pkg1/RegClass.Te$t_Enum.html", "" }, //Test nested class - {BUG_ID + "/pkg1/RegClass._NestedClas$.html", + { "pkg1/RegClass._NestedClas$.html", "" }, - {BUG_ID + "/pkg1/RegClass._NestedClas$.html", + { "pkg1/RegClass._NestedClas$.html", "" }, //Test class use page - {BUG_ID + "/pkg1/class-use/DeprMemClass.html", + { "pkg1/class-use/DeprMemClass.html", "" }, //Test deprecated list page - {BUG_ID + "/deprecated-list.html", + { "deprecated-list.html", "" }, - {BUG_ID + "/deprecated-list.html", + { "deprecated-list.html", "" }, //Test constant values page - {BUG_ID + "/constant-values.html", + { "constant-values.html", "" }, //Test serialized form page //This is the marker for the link that appears in the pkg1.RegClass.html page - {BUG_ID + "/serialized-form.html", + { "serialized-form.html", "" }, //Test member name index page - {BUG_ID + "/index-all.html", + { "index-all.html", "" }, - {BUG_ID + "/index-all.html", + { "index-all.html", "$" }, - {BUG_ID + "/index-all.html", + { "index-all.html", "_" } }; @@ -246,22 +245,22 @@ public class TestAnchorNames extends JavadocTester { private static final String[][] NEGATED_TEST = { //The marker name conversion should only affect HTML anchors. It should not //affect the lables. - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", " Z:Z_" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", " Z:Z:Dfield" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", " Z:Z_field_In_Class" }, - {BUG_ID + "/pkg1/RegClass.html", + { "pkg1/RegClass.html", " S_:D:D:D:D:DINT" }, }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-use", "pkg1" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-use", "pkg1" }; /** @@ -270,21 +269,7 @@ public class TestAnchorNames extends JavadocTester { */ public static void main(String[] args) throws Exception { TestAnchorNames tester = new TestAnchorNames(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java b/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java index 0808937137a..d2d5108356d 100644 --- a/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java +++ b/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java @@ -35,44 +35,24 @@ public class TestAnnotationOptional extends JavadocTester { - //Test information. - private static final String BUG_ID = "NO_BUG_ID_YET"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + "/pkg/AnnotationOptional.html", + { "pkg/AnnotationOptional.html", "" } }; - - private static final String[][] NEGATED_TEST = NO_TEST; - /** * The entry point of the test. * @param args the array of command line arguments. */ public static void main(String[] args) { TestAnnotationOptional tester = new TestAnnotationOptional(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java b/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java index 470536fec07..b870b2618a7 100644 --- a/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java +++ b/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java @@ -34,47 +34,44 @@ public class TestAnnotationTypes extends JavadocTester { - //Test information. - private static final String BUG_ID = "4973609-8015249"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + "/pkg/AnnotationTypeField.html", + { "pkg/AnnotationTypeField.html", "

  • Summary: 
  • \n" + "
  • Field | 
  • "}, - {BUG_ID + "/pkg/AnnotationTypeField.html", + { "pkg/AnnotationTypeField.html", "
  • Detail: 
  • \n" + "
  • Field | 
  • "}, - {BUG_ID + "/pkg/AnnotationTypeField.html", + { "pkg/AnnotationTypeField.html", ""}, - {BUG_ID + "/pkg/AnnotationTypeField.html", + { "pkg/AnnotationTypeField.html", "

    Field Summary

    "}, - {BUG_ID + "/pkg/AnnotationTypeField.html", + { "pkg/AnnotationTypeField.html", "DEFAULT_NAME" + " "}, - {BUG_ID + "/pkg/AnnotationTypeField.html", + { "pkg/AnnotationTypeField.html", ""}, - {BUG_ID + "/pkg/AnnotationTypeField.html", + { "pkg/AnnotationTypeField.html", "

    DEFAULT_NAME

    \n" + "
    public static final java." +
                 "lang.String DEFAULT_NAME
    "}, - {BUG_ID + "/pkg/AnnotationType.html", + { "pkg/AnnotationType.html", "
  • Summary: 
  • \n" + "
  • Field | 
  • "}, - {BUG_ID + "/pkg/AnnotationType.html", + { "pkg/AnnotationType.html", "
  • Detail: 
  • \n" + "
  • Field | 
  • "}, }; private static final String[][] NEGATED_TEST = { - {BUG_ID + "/pkg/AnnotationType.html", + { "pkg/AnnotationType.html", "
    \n\n" + "

    \n\n" + "

    " + @@ -87,21 +84,7 @@ public class TestAnnotationTypes extends JavadocTester { */ public static void main(String[] args) { TestAnnotationTypes tester = new TestAnnotationTypes(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java b/langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java index 0db22bb2e7d..f7973439012 100644 --- a/langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java +++ b/langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java @@ -35,13 +35,11 @@ public class TestBackSlashInLink extends JavadocTester { - private static final String BUG_ID = "4511110"; private static final String[][] TEST = { - {BUG_ID + "/C.html", "src-html/C.html#line.7"}}; - private static final String[][] NEGATED_TEST = NO_TEST; + { "C.html", "src-html/C.html#line.7"}}; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-linksource", SRC_DIR + "/C.java"}; /** @@ -50,21 +48,7 @@ public class TestBackSlashInLink extends JavadocTester { */ public static void main(String[] args) { TestBackSlashInLink tester = new TestBackSlashInLink(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java b/langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java index 0e57e3d5622..32bca3224a2 100644 --- a/langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java +++ b/langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java @@ -35,10 +35,6 @@ public class TestBadPackageFileInJar extends JavadocTester { - protected static final String FS = System.getProperty("file.separator"); - - private static final String BUG_ID = "4691095"; - private static final String[][] TEST = new String[][] { {ERROR_OUTPUT, @@ -47,7 +43,7 @@ public class TestBadPackageFileInJar extends JavadocTester { private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-classpath", + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-classpath", SRC_DIR + "/badPackageFileInJar.jar", "pkg"}; @@ -57,21 +53,7 @@ public class TestBadPackageFileInJar extends JavadocTester { */ public static void main(String[] args) { TestBadPackageFileInJar tester = new TestBadPackageFileInJar(); - run(tester, ARGS, TEST, NO_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java b/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java index 8e0cf93dad2..cf60a9f6edb 100644 --- a/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java +++ b/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java @@ -35,40 +35,19 @@ public class TestBadSourceFile extends JavadocTester { - //Test information. - private static final String BUG_ID = "4835749"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + "/C2.java" + "-Xdoclint:none", "-d", OUTPUT_DIR, SRC_DIR + "/C2.java" }; - //Input for string search tests. - private static final String[][] TEST = NO_TEST; - private static final String[][] NEGATED_TEST = NO_TEST; - /** * The entry point of the test. * @param args the array of command line arguments. */ public static void main(String[] args) { TestBadSourceFile tester = new TestBadSourceFile(); - int exitCode = run(tester, ARGS, TEST, NEGATED_TEST); + int exitCode = tester.run(ARGS, NO_TEST, NO_TEST); tester.checkExitCode(0, exitCode); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java b/langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java index dfb455a736c..d25e8e06b30 100644 --- a/langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java +++ b/langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java @@ -35,9 +35,6 @@ public class TestBaseClass extends JavadocTester { - private static final String BUG_ID = "4197513"; - private static final String[][] TEST = NO_TEST; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { "-sourcepath", SRC_DIR, @@ -50,22 +47,8 @@ public class TestBaseClass extends JavadocTester { */ public static void main(String[] args) { TestBaseClass tester = new TestBaseClass(); - if (run(tester, ARGS, TEST, NEGATED_TEST) != 0) { + if (tester.run(ARGS, NO_TEST, NO_TEST) != 0) { throw new Error("Javadoc failed to execute."); } } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java b/langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java index 2640223c835..f0dd06e3feb 100644 --- a/langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java +++ b/langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java @@ -37,14 +37,12 @@ public class TestBreakIterator extends JavadocTester { - private static final String BUG_ID = "4165985"; private static final String[][] TEST = { - {BUG_ID + "/pkg/BreakIteratorTest.html", + { "pkg/BreakIteratorTest.html", "The class is empty (i.e. it has no members)."}}; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-breakiterator", "pkg"}; /** @@ -53,21 +51,7 @@ public class TestBreakIterator extends JavadocTester { */ public static void main(String[] args) { TestBreakIterator tester = new TestBreakIterator(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java b/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java index 0de67d21a7a..5bac9a6f553 100644 --- a/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java +++ b/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java @@ -37,21 +37,17 @@ import java.util.*; public class TestCRLineSeparator extends JavadocTester { - //Test information. - private static final String BUG_ID = "4979486-8014636"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", ".", "pkg" + "-d", OUTPUT_DIR, "-sourcepath", ".", "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + "/pkg/MyClass.html", "Line 1\n" + + { "pkg/MyClass.html", "Line 1\n" + " Line 2"} }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -60,24 +56,10 @@ public class TestCRLineSeparator extends JavadocTester { public static void main(String[] args) throws Exception { initFiles(new File(SRC_DIR), new File("."), "pkg"); TestCRLineSeparator tester = new TestCRLineSeparator(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } - // recursively copy files from fromDir to toDir, replacing newlines // with \r static void initFiles(File fromDir, File toDir, String f) throws IOException { diff --git a/langtools/test/com/sun/javadoc/testCharset/TestCharset.java b/langtools/test/com/sun/javadoc/testCharset/TestCharset.java index 4d5174f1e6b..d851a659c98 100644 --- a/langtools/test/com/sun/javadoc/testCharset/TestCharset.java +++ b/langtools/test/com/sun/javadoc/testCharset/TestCharset.java @@ -34,25 +34,22 @@ public class TestCharset extends JavadocTester { - //Test information. - private static final String BUG_ID = "7052170"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-charset", "UTF-8", "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-charset", "UTF-8", "-sourcepath", SRC_DIR, "pkg" }; private static final String[][] TEST = { - {BUG_ID + "/index.html", + { "index.html", ""}, - {BUG_ID + "/pkg/Foo.html", + { "pkg/Foo.html", ""} }; private static final String[][] NEGATED_TEST = { - {BUG_ID + "/index.html", + { "index.html", ""}, - {BUG_ID + "/pkg/Foo.html", + { "pkg/Foo.html", ""} }; @@ -62,21 +59,7 @@ public class TestCharset extends JavadocTester { */ public static void main(String[] args) { TestCharset tester = new TestCharset(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java b/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java index f06dfc81a2a..6617c6e61ec 100644 --- a/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java +++ b/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java @@ -34,29 +34,27 @@ public class TestClassCrossReferences extends JavadocTester { - private static final String BUG_ID = "4652655-4857717"; private static final String[][] TEST = { - {BUG_ID + "/C.html", + { "C.html", "Link to math package"}, - {BUG_ID + "/C.html", + { "C.html", "Link to AttributeContext innerclass"}, - {BUG_ID + "/C.html", + { "C.html", "Link to external class BigDecimal"}, - {BUG_ID + "/C.html", + { "C.html", "Link to external member gcd"}, - {BUG_ID + "/C.html", + { "C.html", "

    \n" + "
    Overrides:
    \n" + "
    toString in class java.lang.Object
    \n" + "
    "} }; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-linkoffline", "http://java.sun.com/j2se/1.4/docs/api/", SRC_DIR, SRC_DIR + "/C.java"}; @@ -66,21 +64,7 @@ public class TestClassCrossReferences extends JavadocTester { */ public static void main(String[] args) { TestClassCrossReferences tester = new TestClassCrossReferences(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java b/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java index e033e03f2d0..9215c4e54fc 100644 --- a/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java +++ b/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java @@ -37,22 +37,19 @@ public class TestClassTree extends JavadocTester { - //Test information. - private static final String BUG_ID = "4632553-4973607"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + "/pkg/package-tree.html", + { "pkg/package-tree.html", "