This commit is contained in:
Lana Steuck 2017-01-20 19:10:00 +00:00
commit f0bbed0c96
115 changed files with 4726 additions and 515 deletions

View File

@ -68,8 +68,8 @@ import javax.lang.model.type.TypeMirror;
* javax.lang.model.*} packages bundled in Java SE 8 were required to
* also be runnable on Java SE 7. Therefore, default methods
* were <em>not</em> used when extending {@code javax.lang.model.*}
* to cover Java SE 8 language features. However, default methods may
* be used in subsequent revisions of the {@code javax.lang.model.*}
* to cover Java SE 8 language features. However, default methods
* are used in subsequent revisions of the {@code javax.lang.model.*}
* packages that are only required to run on Java SE 8 and higher
* platform versions.
*
@ -90,11 +90,16 @@ public interface AnnotationValueVisitor<R, P> {
R visit(AnnotationValue av, P p);
/**
* A convenience method equivalent to {@code v.visit(av, null)}.
* A convenience method equivalent to {@code visit(av, null)}.
*
* @implSpec The default implementation is {@code visit(av, null)}.
*
* @param av the value to visit
* @return a visitor-specified result
*/
R visit(AnnotationValue av);
default R visit(AnnotationValue av) {
return visit(av, null);
}
/**
* Visits a {@code boolean} value in an annotation.

View File

@ -59,8 +59,8 @@ import javax.lang.model.util.*;
* javax.lang.model.*} packages bundled in Java SE 8 were required to
* also be runnable on Java SE 7. Therefore, default methods
* were <em>not</em> used when extending {@code javax.lang.model.*}
* to cover Java SE 8 language features. However, default methods may
* be used in subsequent revisions of the {@code javax.lang.model.*}
* to cover Java SE 8 language features. However, default methods
* are used in subsequent revisions of the {@code javax.lang.model.*}
* packages that are only required to run on Java SE 8 and higher
* platform versions.
*
@ -85,11 +85,16 @@ public interface ElementVisitor<R, P> {
R visit(Element e, P p);
/**
* A convenience method equivalent to {@code v.visit(e, null)}.
* A convenience method equivalent to {@code visit(e, null)}.
*
* @implSpec The default implementation is {@code visit(e, null)}.
*
* @param e the element to visit
* @return a visitor-specified result
*/
R visit(Element e);
default R visit(Element e) {
return visit(e, null);
}
/**
* Visits a package element.
@ -146,10 +151,16 @@ public interface ElementVisitor<R, P> {
/**
* Visits a module element.
*
* @implSpec Visits a {@code ModuleElement} by calling {@code
* visitUnknown(e, p)}.
*
* @param e the element to visit
* @param p a visitor-specified parameter
* @return a visitor-specified result
* @since 9
*/
R visitModule(ModuleElement e, P p);
default R visitModule(ModuleElement e, P p) {
return visitUnknown(e, p);
}
}

View File

@ -59,8 +59,8 @@ import javax.lang.model.element.*;
* javax.lang.model.*} packages bundled in Java SE 8 were required to
* also be runnable on Java SE 7. Therefore, default methods
* were <em>not</em> used when extending {@code javax.lang.model.*}
* to cover Java SE 8 language features. However, default methods may
* be used in subsequent revisions of the {@code javax.lang.model.*}
* to cover Java SE 8 language features. However, default methods
* are used in subsequent revisions of the {@code javax.lang.model.*}
* packages that are only required to run on Java SE 8 and higher
* platform versions.
*
@ -85,11 +85,16 @@ public interface TypeVisitor<R, P> {
R visit(TypeMirror t, P p);
/**
* A convenience method equivalent to {@code v.visit(t, null)}.
* A convenience method equivalent to {@code visit(t, null)}.
*
* @implSpec The default implementation is {@code visit(t, null)}.
*
* @param t the element to visit
* @return a visitor-specified result
*/
R visit(TypeMirror t);
default R visit(TypeMirror t) {
return visit(t, null);
}
/**
* Visits a primitive type.

View File

@ -65,17 +65,17 @@ import javax.annotation.processing.SupportedSourceVersion;
* @see AbstractAnnotationValueVisitor8
* @see AbstractAnnotationValueVisitor9
* @since 1.6
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
@SupportedSourceVersion(RELEASE_6)
public abstract class AbstractAnnotationValueVisitor6<R, P>
implements AnnotationValueVisitor<R, P> {
/**
* Constructor for concrete subclasses to call.
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected AbstractAnnotationValueVisitor6() {}
/**

View File

@ -59,13 +59,13 @@ import javax.annotation.processing.SupportedSourceVersion;
* @see AbstractAnnotationValueVisitor9
* @since 1.7
*/
@SuppressWarnings("deprecation") // Superclass deprecated
@SupportedSourceVersion(RELEASE_7)
public abstract class AbstractAnnotationValueVisitor7<R, P> extends AbstractAnnotationValueVisitor6<R, P> {
/**
* Constructor for concrete subclasses to call.
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected AbstractAnnotationValueVisitor7() {
super();
}

View File

@ -67,15 +67,15 @@ import static javax.lang.model.SourceVersion.*;
* @see AbstractElementVisitor8
* @see AbstractElementVisitor9
* @since 1.6
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
@SupportedSourceVersion(RELEASE_6)
public abstract class AbstractElementVisitor6<R, P> implements ElementVisitor<R, P> {
/**
* Constructor for concrete subclasses to call.
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected AbstractElementVisitor6(){}
/**
@ -139,6 +139,7 @@ public abstract class AbstractElementVisitor6<R, P> implements ElementVisitor<R,
*/
@Override
public R visitModule(ModuleElement e, P p) {
return visitUnknown(e, p);
// Use implementation from interface default method
return ElementVisitor.super.visitModule(e, p);
}
}

View File

@ -63,12 +63,12 @@ import static javax.lang.model.SourceVersion.*;
* @see AbstractElementVisitor9
* @since 1.7
*/
@SuppressWarnings("deprecation") // Superclass deprecated
@SupportedSourceVersion(RELEASE_7)
public abstract class AbstractElementVisitor7<R, P> extends AbstractElementVisitor6<R, P> {
/**
* Constructor for concrete subclasses to call.
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected AbstractElementVisitor7(){
super();
}

View File

@ -66,15 +66,15 @@ import static javax.lang.model.SourceVersion.*;
* @see AbstractTypeVisitor8
* @see AbstractTypeVisitor9
* @since 1.6
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
@SupportedSourceVersion(RELEASE_6)
public abstract class AbstractTypeVisitor6<R, P> implements TypeVisitor<R, P> {
/**
* Constructor for concrete subclasses to call.
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected AbstractTypeVisitor6() {}
/**

View File

@ -63,12 +63,12 @@ import static javax.lang.model.SourceVersion.*;
* @see AbstractTypeVisitor9
* @since 1.7
*/
@SuppressWarnings("deprecation") // Superclass deprecated
@SupportedSourceVersion(RELEASE_7)
public abstract class AbstractTypeVisitor7<R, P> extends AbstractTypeVisitor6<R, P> {
/**
* Constructor for concrete subclasses to call.
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected AbstractTypeVisitor7() {
super();
}

View File

@ -81,17 +81,17 @@ import javax.lang.model.SourceVersion;
* @see ElementKindVisitor8
* @see ElementKindVisitor9
* @since 1.6
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
@SupportedSourceVersion(RELEASE_6)
public class ElementKindVisitor6<R, P>
extends SimpleElementVisitor6<R, P> {
/**
* Constructor for concrete subclasses; uses {@code null} for the
* default value.
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected ElementKindVisitor6() {
super(null);
}
@ -101,7 +101,10 @@ public class ElementKindVisitor6<R, P>
* default value.
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected ElementKindVisitor6(R defaultValue) {
super(defaultValue);
}

View File

@ -76,13 +76,13 @@ import static javax.lang.model.SourceVersion.*;
* @see ElementKindVisitor9
* @since 1.7
*/
@SuppressWarnings("deprecation") // Superclass deprecated
@SupportedSourceVersion(RELEASE_7)
public class ElementKindVisitor7<R, P> extends ElementKindVisitor6<R, P> {
/**
* Constructor for concrete subclasses; uses {@code null} for the
* default value.
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected ElementKindVisitor7() {
super(null);
}
@ -93,6 +93,7 @@ public class ElementKindVisitor7<R, P> extends ElementKindVisitor6<R, P> {
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected ElementKindVisitor7(R defaultValue) {
super(defaultValue);
}

View File

@ -92,10 +92,7 @@ import static javax.lang.model.SourceVersion.*;
* @see ElementScanner8
* @see ElementScanner9
* @since 1.6
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
@SupportedSourceVersion(RELEASE_6)
public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
/**
@ -106,7 +103,10 @@ public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
/**
* Constructor for concrete subclasses; uses {@code null} for the
* default value.
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected ElementScanner6(){
DEFAULT_VALUE = null;
}
@ -116,7 +116,10 @@ public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
* default value.
*
* @param defaultValue the default value
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected ElementScanner6(R defaultValue){
DEFAULT_VALUE = defaultValue;
}

View File

@ -89,13 +89,13 @@ import static javax.lang.model.SourceVersion.*;
* @see ElementScanner9
* @since 1.7
*/
@SuppressWarnings("deprecation") // Superclass deprecated
@SupportedSourceVersion(RELEASE_7)
public class ElementScanner7<R, P> extends ElementScanner6<R, P> {
/**
* Constructor for concrete subclasses; uses {@code null} for the
* default value.
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected ElementScanner7(){
super(null);
}
@ -106,6 +106,7 @@ public class ElementScanner7<R, P> extends ElementScanner6<R, P> {
*
* @param defaultValue the default value
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected ElementScanner7(R defaultValue){
super(defaultValue);
}

View File

@ -74,10 +74,7 @@ import javax.annotation.processing.SupportedSourceVersion;
* @see SimpleAnnotationValueVisitor8
* @see SimpleAnnotationValueVisitor9
* @since 1.6
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
@SupportedSourceVersion(RELEASE_6)
public class SimpleAnnotationValueVisitor6<R, P>
extends AbstractAnnotationValueVisitor6<R, P> {
@ -92,7 +89,10 @@ public class SimpleAnnotationValueVisitor6<R, P>
/**
* Constructor for concrete subclasses; uses {@code null} for the
* default value.
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected SimpleAnnotationValueVisitor6() {
super();
DEFAULT_VALUE = null;
@ -103,7 +103,10 @@ public class SimpleAnnotationValueVisitor6<R, P>
* default value.
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected SimpleAnnotationValueVisitor6(R defaultValue) {
super();
DEFAULT_VALUE = defaultValue;

View File

@ -66,13 +66,13 @@ import static javax.lang.model.SourceVersion.*;
* @see SimpleAnnotationValueVisitor9
* @since 1.7
*/
@SuppressWarnings("deprecation") // Superclass deprecated
@SupportedSourceVersion(RELEASE_7)
public class SimpleAnnotationValueVisitor7<R, P> extends SimpleAnnotationValueVisitor6<R, P> {
/**
* Constructor for concrete subclasses; uses {@code null} for the
* default value.
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected SimpleAnnotationValueVisitor7() {
super(null);
}
@ -83,6 +83,7 @@ public class SimpleAnnotationValueVisitor7<R, P> extends SimpleAnnotationValueVi
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected SimpleAnnotationValueVisitor7(R defaultValue) {
super(defaultValue);
}

View File

@ -78,10 +78,7 @@ import static javax.lang.model.SourceVersion.*;
* @see SimpleElementVisitor8
* @see SimpleElementVisitor9
* @since 1.6
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
@SupportedSourceVersion(RELEASE_6)
public class SimpleElementVisitor6<R, P> extends AbstractElementVisitor6<R, P> {
/**
@ -94,7 +91,10 @@ public class SimpleElementVisitor6<R, P> extends AbstractElementVisitor6<R, P> {
/**
* Constructor for concrete subclasses; uses {@code null} for the
* default value.
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected SimpleElementVisitor6(){
DEFAULT_VALUE = null;
}
@ -104,7 +104,10 @@ public class SimpleElementVisitor6<R, P> extends AbstractElementVisitor6<R, P> {
* default value.
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected SimpleElementVisitor6(R defaultValue){
DEFAULT_VALUE = defaultValue;
}

View File

@ -72,13 +72,13 @@ import static javax.lang.model.SourceVersion.*;
* @see SimpleElementVisitor9
* @since 1.7
*/
@SuppressWarnings("deprecation") // Superclass deprecated
@SupportedSourceVersion(RELEASE_7)
public class SimpleElementVisitor7<R, P> extends SimpleElementVisitor6<R, P> {
/**
* Constructor for concrete subclasses; uses {@code null} for the
* default value.
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected SimpleElementVisitor7(){
super(null);
}
@ -89,6 +89,7 @@ public class SimpleElementVisitor7<R, P> extends SimpleElementVisitor6<R, P> {
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected SimpleElementVisitor7(R defaultValue){
super(defaultValue);
}

View File

@ -78,10 +78,7 @@ import static javax.lang.model.SourceVersion.*;
* @see SimpleTypeVisitor8
* @see SimpleTypeVisitor9
* @since 1.6
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
@SupportedSourceVersion(RELEASE_6)
public class SimpleTypeVisitor6<R, P> extends AbstractTypeVisitor6<R, P> {
/**
@ -94,7 +91,10 @@ public class SimpleTypeVisitor6<R, P> extends AbstractTypeVisitor6<R, P> {
/**
* Constructor for concrete subclasses; uses {@code null} for the
* default value.
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected SimpleTypeVisitor6(){
DEFAULT_VALUE = null;
}
@ -104,7 +104,10 @@ public class SimpleTypeVisitor6<R, P> extends AbstractTypeVisitor6<R, P> {
* default value.
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected SimpleTypeVisitor6(R defaultValue){
DEFAULT_VALUE = defaultValue;
}

View File

@ -72,13 +72,13 @@ import static javax.lang.model.SourceVersion.*;
* @see SimpleTypeVisitor9
* @since 1.7
*/
@SuppressWarnings("deprecation") // Superclass deprecated
@SupportedSourceVersion(RELEASE_7)
public class SimpleTypeVisitor7<R, P> extends SimpleTypeVisitor6<R, P> {
/**
* Constructor for concrete subclasses; uses {@code null} for the
* default value.
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected SimpleTypeVisitor7(){
super(null);
}
@ -89,6 +89,7 @@ public class SimpleTypeVisitor7<R, P> extends SimpleTypeVisitor6<R, P> {
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected SimpleTypeVisitor7(R defaultValue){
super(defaultValue);
}

View File

@ -76,16 +76,16 @@ import static javax.lang.model.SourceVersion.*;
* @see TypeKindVisitor7
* @see TypeKindVisitor8
* @since 1.6
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
@SupportedSourceVersion(RELEASE_6)
public class TypeKindVisitor6<R, P> extends SimpleTypeVisitor6<R, P> {
/**
* Constructor for concrete subclasses to call; uses {@code null}
* for the default value.
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected TypeKindVisitor6() {
super(null);
}
@ -96,7 +96,10 @@ public class TypeKindVisitor6<R, P> extends SimpleTypeVisitor6<R, P> {
* for the default value.
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
* @deprecated Release 6 is obsolete; update to a visitor for a newer
* release level.
*/
@Deprecated
protected TypeKindVisitor6(R defaultValue) {
super(defaultValue);
}

View File

@ -73,13 +73,13 @@ import javax.lang.model.SourceVersion;
* @see TypeKindVisitor8
* @since 1.7
*/
@SuppressWarnings("deprecation") // Superclass deprecated
@SupportedSourceVersion(RELEASE_7)
public class TypeKindVisitor7<R, P> extends TypeKindVisitor6<R, P> {
/**
* Constructor for concrete subclasses to call; uses {@code null}
* for the default value.
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected TypeKindVisitor7() {
super(null);
}
@ -90,6 +90,7 @@ public class TypeKindVisitor7<R, P> extends TypeKindVisitor6<R, P> {
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
*/
@SuppressWarnings("deprecation") // Superclass constructor deprecated
protected TypeKindVisitor7(R defaultValue) {
super(defaultValue);
}

View File

@ -98,7 +98,7 @@ public class DocTreePath implements Iterable<DocTree> {
* @param t the DocCommentTree to create the path for.
*/
public DocTreePath(TreePath treePath, DocCommentTree t) {
this.treePath = Objects.requireNonNull(treePath);
this.treePath = treePath;
this.docComment = Objects.requireNonNull(t);
this.parent = null;
this.leaf = t;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, 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,7 @@ import java.util.List;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.JavaCompiler.CompilationTask;
@ -127,17 +128,22 @@ public abstract class DocTrees extends Trees {
/**
* Returns a doc tree path containing the doc comment tree of the given file.
* The file must be an HTML file, in which case the doc comment tree represents the
* contents of the &lt;body&gt; tag, and any enclosing tags are ignored.
* The file must be an HTML file, in which case the doc comment tree represents
* the contents of the {@code <body>} tag, and any enclosing tags are ignored.
* Any references to source code elements contained in {@code @see} and
* {@code {@link}} tags in the doc comment tree will be evaluated in the
* context of the given package element.
* Returns {@code null} if no doc comment was found.
* Future releases may support additional file types.
*
* @param fileObject the content container
* @return a doc tree path containing the doc comment read from the given file.
* @param fileObject a file object encapsulating the HTML content
* @param packageElement a package element to associate with the given file object
* representing a legacy package.html, null otherwise
* @return a doc tree path containing the doc comment parsed from the given file
* @throws IllegalArgumentException if the fileObject is not an HTML file
*
* @since 9
*/
public abstract DocTreePath getDocTreePath(FileObject fileObject);
public abstract DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement);
/**
* Returns the language model element referred to by the leaf node of the given

View File

@ -423,7 +423,16 @@ public class Checker extends DocTreePathScanner<Void, Void> {
break;
case OTHER:
env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
switch (t) {
case SCRIPT:
// <script> may or may not be allowed, depending on --allow-script-in-comments
// but we allow it here, and rely on a separate scanner to detect all uses
// of JavaScript, including <script> tags, and use in attributes, etc.
break;
default:
env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
}
return;
}
@ -552,15 +561,19 @@ public class Checker extends DocTreePathScanner<Void, Void> {
if (!first)
env.messages.error(HTML, tree, "dc.attr.repeated", name);
}
AttrKind k = currTag.getAttrKind(name);
switch (env.htmlVersion) {
case HTML4:
validateHtml4Attrs(tree, name, k);
break;
// for now, doclint allows all attribute names beginning with "on" as event handler names,
// without checking the validity or applicability of the name
if (!name.toString().startsWith("on")) {
AttrKind k = currTag.getAttrKind(name);
switch (env.htmlVersion) {
case HTML4:
validateHtml4Attrs(tree, name, k);
break;
case HTML5:
validateHtml5Attrs(tree, name, k);
break;
case HTML5:
validateHtml5Attrs(tree, name, k);
break;
}
}
if (attr != null) {
@ -722,6 +735,9 @@ public class Checker extends DocTreePathScanner<Void, Void> {
}
private void checkURI(AttributeTree tree, String uri) {
// allow URIs beginning with javascript:, which would otherwise be rejected by the URI API.
if (uri.startsWith("javascript:"))
return;
try {
URI u = new URI(uri);
} catch (URISyntaxException e) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2016, 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
@ -287,7 +287,8 @@ public enum HtmlTag {
SAMP(BlockType.INLINE, EndKind.REQUIRED,
EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
SCRIPT(BlockType.OTHER, EndKind.REQUIRED),
SCRIPT(BlockType.OTHER, EndKind.REQUIRED,
attrs(AttrKind.ALL, SRC)),
SECTION(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED,
EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),

View File

@ -174,7 +174,6 @@ public class JavacTrees extends DocTrees {
private JavaFileManager fileManager;
private ParserFactory parser;
private Symtab syms;
private Map<JavaFileObject, PackageSymbol> javaFileObjectToPackageMap;
// called reflectively from Trees.instance(CompilationTask task)
public static JavacTrees instance(JavaCompiler.CompilationTask task) {
@ -198,7 +197,6 @@ public class JavacTrees extends DocTrees {
}
protected JavacTrees(Context context) {
javaFileObjectToPackageMap = new HashMap<>();
this.breakIterator = null;
context.put(JavacTrees.class, this);
init(context);
@ -1039,10 +1037,11 @@ public class JavacTrees extends DocTrees {
}
@Override @DefinedBy(Api.COMPILER_TREE)
public DocTreePath getDocTreePath(FileObject fileObject) {
public DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement) {
JavaFileObject jfo = asJavaFileObject(fileObject);
DocCommentTree docCommentTree = getDocCommentTree(jfo);
return new DocTreePath(makeTreePath(jfo, docCommentTree), docCommentTree);
TreePath treePath = makeTreePath((PackageSymbol)packageElement, jfo, docCommentTree);
return new DocTreePath(treePath, docCommentTree);
}
@Override @DefinedBy(Api.COMPILER_TREE)
@ -1160,17 +1159,8 @@ public class JavacTrees extends DocTrees {
}
}
/**
* Register a file object, such as for a package.html, that provides
* doc comments for a package.
* @param psym the PackageSymbol representing the package.
* @param jfo the JavaFileObject for the given package.
*/
public void putJavaFileObject(PackageSymbol psym, JavaFileObject jfo) {
javaFileObjectToPackageMap.putIfAbsent(jfo, psym);
}
private TreePath makeTreePath(final JavaFileObject jfo, DocCommentTree dcTree) {
private TreePath makeTreePath(final PackageSymbol psym, final JavaFileObject jfo,
DocCommentTree dcTree) {
JCCompilationUnit jcCompilationUnit = new JCCompilationUnit(List.nil()) {
public int getPos() {
return Position.FIRSTPOS;
@ -1191,9 +1181,6 @@ public class JavacTrees extends DocTrees {
}
};
PackageSymbol psym = javaFileObjectToPackageMap.getOrDefault(jfo,
syms.unnamedModule.unnamedPackage);
jcCompilationUnit.docComments = new DocCommentTable() {
@Override
public boolean hasComment(JCTree tree) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -1045,7 +1045,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
DO_NOT_RESOLVE_BY_DEFAULT(0x0001),
WARN_DEPRECATED(0x0002),
WARN_DEPRECATED_REMOVAL(0x0004),
WARN_INCUBATOR(0x0008);
WARN_INCUBATING(0x0008);
public static int value(Set<ModuleResolutionFlags> s) {
int v = 0;
@ -1070,6 +1070,8 @@ public abstract class Symbol extends AnnoConstruct implements Element {
public Name fullname;
public ClassSymbol package_info; // see bug 6443073
public ModuleSymbol modle;
// the file containing the documentation comments for the package
public JavaFileObject sourcefile;
public PackageSymbol(Name name, Type type, Symbol owner) {
super(PCK, 0, name, type, owner);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -818,4 +818,12 @@ public class Symtab {
public Collection<ModuleSymbol> getAllModules() {
return modules.values();
}
public Iterable<ClassSymbol> getClassesForName(Name candidate) {
return classes.getOrDefault(candidate, Collections.emptyMap()).values();
}
public Iterable<PackageSymbol> getPackagesForName(Name candidate) {
return packages.getOrDefault(candidate, Collections.emptyMap()).values();
}
}

View File

@ -118,6 +118,8 @@ public class Annotate {
Source source = Source.instance(context);
allowRepeatedAnnos = source.allowRepeatedAnnotations();
sourceName = source.name;
blockCount = 1;
}
/** Semaphore to delay annotation processing */
@ -144,6 +146,10 @@ public class Annotate {
/** are we blocking annotation processing? */
public boolean annotationsBlocked() {return blockCount > 0; }
public void enterDone() {
unblockAnnotations();
}
public List<TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
if (annotations.isEmpty()) {
return List.nil();
@ -1316,4 +1322,8 @@ public class Annotate {
}
};
}
public void newRound() {
blockCount = 1;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2017, 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
@ -41,6 +41,7 @@ import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.lang.model.SourceVersion;
@ -114,6 +115,7 @@ import static com.sun.tools.javac.code.Flags.UNATTRIBUTED;
import static com.sun.tools.javac.code.Kinds.Kind.ERR;
import static com.sun.tools.javac.code.Kinds.Kind.MDL;
import static com.sun.tools.javac.code.Kinds.Kind.MTH;
import com.sun.tools.javac.code.Symbol.ModuleResolutionFlags;
import static com.sun.tools.javac.code.TypeTag.CLASS;
/**
@ -374,6 +376,9 @@ public class Modules extends JCTree.Visitor {
log.error(decl.qualId, Errors.ModuleNameMismatch(msym.name, name));
}
} else {
if (tree.getPackage() == null) {
log.error(tree.pos(), Errors.UnnamedPkgNotAllowedNamedModules);
}
msym = syms.enterModule(name);
}
if (msym.sourceLocation == null) {
@ -388,7 +393,11 @@ public class Modules extends JCTree.Visitor {
} else if (c != null && c.packge().modle == syms.unnamedModule) {
tree.modle = syms.unnamedModule;
} else {
log.error(tree.pos(), Errors.UnnamedPkgNotAllowedNamedModules);
if (tree.getModuleDecl() != null) {
log.error(tree.pos(), Errors.ModuleNotFoundOnModuleSourcePath);
} else {
log.error(tree.pos(), Errors.NotInModuleOnModuleSourcePath);
}
tree.modle = syms.errModule;
}
} catch (IOException e) {
@ -457,19 +466,27 @@ public class Modules extends JCTree.Visitor {
}
}
/**
* Determine the location for the module on the module source path
* or source output directory which contains a given CompilationUnit.
* If the source output directory is unset, the class output directory
* will be checked instead.
* {@code null} is returned if no such module can be found.
* @param tree the compilation unit tree
* @return the location for the enclosing module
* @throws IOException if there is a problem while searching for the module.
*/
private Location getModuleLocation(JCCompilationUnit tree) throws IOException {
Name pkgName;
if (tree.getModuleDecl() != null) {
return getModuleLocation(tree.sourcefile, null);
} else if (tree.getPackage() != null) {
JCPackageDecl pkg = tree.getPackage();
return getModuleLocation(tree.sourcefile, TreeInfo.fullName(pkg.pid));
pkgName = null;
} else {
// code in unnamed module
return null;
JCPackageDecl pkg = tree.getPackage();
pkgName = (pkg == null) ? names.empty : TreeInfo.fullName(pkg.pid);
}
}
private Location getModuleLocation(JavaFileObject fo, Name pkgName) throws IOException {
JavaFileObject fo = tree.sourcefile;
// For now, just check module source path.
// We may want to check source path as well.
Location loc =
@ -482,7 +499,6 @@ public class Modules extends JCTree.Visitor {
fileManager.getLocationForModule(sourceOutput,
fo, (pkgName == null) ? null : pkgName.toString());
}
return loc;
}
@ -962,7 +978,7 @@ public class Modules extends JCTree.Visitor {
@Override
public void visitRequires(JCRequires tree) {
if (tree.directive != null) {
if (tree.directive != null && allModules().contains(tree.directive.module)) {
chk.checkDeprecated(tree.moduleName.pos(), msym, tree.directive.module);
msym.directives = msym.directives.prepend(tree.directive);
}
@ -1076,6 +1092,10 @@ public class Modules extends JCTree.Visitor {
Predicate<ModuleSymbol> observablePred = sym ->
(observable == null) ? (moduleFinder.findModule(sym).kind != ERR) : observable.contains(sym);
Predicate<ModuleSymbol> systemModulePred = sym -> (sym.flags() & Flags.SYSTEM_MODULE) != 0;
Predicate<ModuleSymbol> noIncubatorPred = sym -> {
sym.complete();
return !sym.resolutionFlags.contains(ModuleResolutionFlags.DO_NOT_RESOLVE_BY_DEFAULT);
};
Set<ModuleSymbol> enabledRoot = new LinkedHashSet<>();
if (rootModules.contains(syms.unnamedModule)) {
@ -1094,7 +1114,7 @@ public class Modules extends JCTree.Visitor {
}
for (ModuleSymbol sym : new HashSet<>(syms.getAllModules())) {
if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym)) {
if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym) && noIncubatorPred.test(sym)) {
enabledRoot.add(sym);
}
}
@ -1114,14 +1134,14 @@ public class Modules extends JCTree.Visitor {
Stream<ModuleSymbol> modules;
switch (added) {
case ALL_SYSTEM:
modules = syms.getAllModules()
.stream()
.filter(systemModulePred.and(observablePred));
modules = new HashSet<>(syms.getAllModules())
.stream()
.filter(systemModulePred.and(observablePred).and(noIncubatorPred));
break;
case ALL_MODULE_PATH:
modules = syms.getAllModules()
.stream()
.filter(systemModulePred.negate().and(observablePred));
modules = new HashSet<>(syms.getAllModules())
.stream()
.filter(systemModulePred.negate().and(observablePred));
break;
default:
if (!isValidName(added))
@ -1141,6 +1161,15 @@ public class Modules extends JCTree.Visitor {
result.add(syms.unnamedModule);
String incubatingModules = result.stream()
.filter(msym -> msym.resolutionFlags.contains(ModuleResolutionFlags.WARN_INCUBATING))
.map(msym -> msym.name.toString())
.collect(Collectors.joining(","));
if (!incubatingModules.isEmpty()) {
log.warning(Warnings.IncubatingModules(incubatingModules));
}
allModules = result;
//add module versions from options, if any:
@ -1234,7 +1263,6 @@ public class Modules extends JCTree.Visitor {
msym.requires = msym.requires.appendList(List.from(addReads.getOrDefault(msym, Collections.emptySet())));
List<RequiresDirective> requires = msym.requires;
List<RequiresDirective> previous = null;
while (requires.nonEmpty()) {
if (!allModules().contains(requires.head.module)) {
@ -1249,13 +1277,7 @@ public class Modules extends JCTree.Visitor {
} else {
Assert.check((msym.flags() & Flags.AUTOMATIC_MODULE) == 0);
}
if (previous != null) {
previous.tail = requires.tail;
} else {
msym.requires.tail = requires.tail;
}
} else {
previous = requires;
msym.requires = List.filter(msym.requires, requires.head);
}
requires = requires.tail;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -41,6 +41,7 @@ import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
@ -61,12 +62,12 @@ import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.lang.model.element.ElementVisitor;
import com.sun.tools.javac.code.Directive.ExportsDirective;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Flags.BLOCK;
import static com.sun.tools.javac.code.Flags.STATIC;
@ -74,9 +75,8 @@ import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
import static com.sun.tools.javac.util.Iterators.createCompoundIterator;
/** Helper class for name resolution, used mostly by the attribution phase.
*
@ -1970,7 +1970,7 @@ public class Resolve {
* @param env The current environment.
* @param name The fully qualified name of the class to be loaded.
*/
Symbol loadClass(Env<AttrContext> env, Name name) {
Symbol loadClass(Env<AttrContext> env, Name name, RecoveryLoadClass recoveryLoadClass) {
try {
ClassSymbol c = finder.loadClass(env.toplevel.modle, name);
return isAccessible(env, c) ? c : new AccessError(env, null, c);
@ -1987,40 +1987,60 @@ public class Resolve {
}
}
public static interface RecoveryLoadClass {
public interface RecoveryLoadClass {
Symbol loadClass(Env<AttrContext> env, Name name);
}
private RecoveryLoadClass recoveryLoadClass = new RecoveryLoadClass() {
@Override
public Symbol loadClass(Env<AttrContext> env, Name name) {
if (allowModules) {
Scope importScope = env.toplevel.namedImportScope;
Symbol existing = importScope.findFirst(Convert.shortName(name),
sym -> sym.kind == TYP && sym.flatName() == name);
private final RecoveryLoadClass noRecovery = (env, name) -> null;
if (existing != null) {
return new InvisibleSymbolError(env, true, existing);
}
return lookupInvisibleSymbol(env, name, syms::getClass, (ms, n) -> {
private final RecoveryLoadClass doRecoveryLoadClass = new RecoveryLoadClass() {
@Override public Symbol loadClass(Env<AttrContext> env, Name name) {
List<Name> candidates = Convert.classCandidates(name);
return lookupInvisibleSymbol(env, name,
n -> () -> createCompoundIterator(candidates,
c -> syms.getClassesForName(c)
.iterator()),
(ms, n) -> {
for (Name candidate : candidates) {
try {
return finder.loadClass(ms, n);
return finder.loadClass(ms, candidate);
} catch (CompletionFailure cf) {
//ignore
return null;
}
}, sym -> sym.kind == Kind.TYP, false, typeNotFound);
}
return null;
}
return null;
}, sym -> sym.kind == Kind.TYP, false, typeNotFound);
}
};
public RecoveryLoadClass setRecoveryLoadClass(RecoveryLoadClass recovery) {
RecoveryLoadClass prev = recoveryLoadClass;
recoveryLoadClass = recovery;
return prev;
}
private final RecoveryLoadClass namedImportScopeRecovery = (env, name) -> {
Scope importScope = env.toplevel.namedImportScope;
Symbol existing = importScope.findFirst(Convert.shortName(name),
sym -> sym.kind == TYP && sym.flatName() == name);
if (existing != null) {
return new InvisibleSymbolError(env, true, existing);
}
return null;
};
private final RecoveryLoadClass starImportScopeRecovery = (env, name) -> {
Scope importScope = env.toplevel.starImportScope;
Symbol existing = importScope.findFirst(Convert.shortName(name),
sym -> sym.kind == TYP && sym.flatName() == name);
if (existing != null) {
try {
existing = finder.loadClass(existing.packge().modle, name);
return new InvisibleSymbolError(env, true, existing);
} catch (CompletionFailure cf) {
//ignore
}
}
return null;
};
Symbol lookupPackage(Env<AttrContext> env, Name name) {
PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, name);
@ -2034,7 +2054,7 @@ public class Resolve {
.stream()
.anyMatch(p -> p.fullname.startsWith(nameAndDot));
return lookupInvisibleSymbol(env, name, syms::getPackage, syms::enterPackage, sym -> {
return lookupInvisibleSymbol(env, name, syms::getPackagesForName, syms::enterPackage, sym -> {
sym.complete();
return sym.exists();
}, prefixOfKnown, pack);
@ -2059,42 +2079,44 @@ public class Resolve {
return TreeInfo.fullName(((JCFieldAccess) qualid).selected) == name;
}
private Symbol lookupInvisibleSymbol(Env<AttrContext> env,
Name name,
BiFunction<ModuleSymbol, Name, Symbol> get,
BiFunction<ModuleSymbol, Name, Symbol> load,
Predicate<Symbol> validate,
boolean suppressError,
Symbol defaultResult) {
private <S extends Symbol> Symbol lookupInvisibleSymbol(Env<AttrContext> env,
Name name,
Function<Name, Iterable<S>> get,
BiFunction<ModuleSymbol, Name, S> load,
Predicate<S> validate,
boolean suppressError,
Symbol defaultResult) {
//even if a class/package cannot be found in the current module and among packages in modules
//it depends on that are exported for any or this module, the class/package may exist internally
//in some of these modules, or may exist in a module on which this module does not depend.
//Provide better diagnostic in such cases by looking for the class in any module:
Iterable<? extends S> candidates = get.apply(name);
for (S sym : candidates) {
if (validate.test(sym))
return new InvisibleSymbolError(env, suppressError, sym);
}
Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
recoverableModules.remove(env.toplevel.modle);
for (ModuleSymbol ms : recoverableModules) {
Symbol sym = get.apply(ms, name);
//avoid overly eager completing classes from source-based modules, as those
//may not be completable with the current compiler settings:
if (sym == null && (ms.sourceLocation == null)) {
if (ms.sourceLocation == null) {
if (ms.classLocation == null) {
ms = moduleFinder.findModule(ms);
}
if (ms.kind != ERR) {
sym = load.apply(ms, name);
S sym = load.apply(ms, name);
if (sym != null && validate.test(sym)) {
return new InvisibleSymbolError(env, suppressError, sym);
}
}
}
if (sym == null)
continue;
if (validate.test(sym)) {
return new InvisibleSymbolError(env, suppressError, sym);
}
}
return defaultResult;
@ -2186,10 +2208,10 @@ public class Resolve {
* @param scope The scope in which to look for the type.
* @param name The type's name.
*/
Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name, RecoveryLoadClass recoveryLoadClass) {
Symbol bestSoFar = typeNotFound;
for (Symbol s : scope.getSymbolsByName(name)) {
Symbol sym = loadClass(env, s.flatName());
Symbol sym = loadClass(env, s.flatName(), recoveryLoadClass);
if (bestSoFar.kind == TYP && sym.kind == TYP &&
bestSoFar != sym)
return new AmbiguityError(bestSoFar, sym);
@ -2260,15 +2282,15 @@ public class Resolve {
}
if (!env.tree.hasTag(IMPORT)) {
sym = findGlobalType(env, env.toplevel.namedImportScope, name);
sym = findGlobalType(env, env.toplevel.namedImportScope, name, namedImportScopeRecovery);
if (sym.exists()) return sym;
else bestSoFar = bestOf(bestSoFar, sym);
sym = findGlobalType(env, env.toplevel.packge.members(), name);
sym = findGlobalType(env, env.toplevel.packge.members(), name, noRecovery);
if (sym.exists()) return sym;
else bestSoFar = bestOf(bestSoFar, sym);
sym = findGlobalType(env, env.toplevel.starImportScope, name);
sym = findGlobalType(env, env.toplevel.starImportScope, name, starImportScopeRecovery);
if (sym.exists()) return sym;
else bestSoFar = bestOf(bestSoFar, sym);
}
@ -2315,7 +2337,11 @@ public class Resolve {
Name fullname = TypeSymbol.formFullName(name, pck);
Symbol bestSoFar = typeNotFound;
if (kind.contains(KindSelector.TYP)) {
Symbol sym = loadClass(env, fullname);
RecoveryLoadClass recoveryLoadClass =
allowModules && !kind.contains(KindSelector.PCK) &&
!pck.exists() && !env.info.isSpeculative ?
doRecoveryLoadClass : noRecovery;
Symbol sym = loadClass(env, fullname, recoveryLoadClass);
if (sym.exists()) {
// don't allow programs to use flatnames
if (name == sym.name) return sym;
@ -4136,11 +4162,21 @@ public class Resolve {
JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
if (pos.getTree() != null && pos.getTree().hasTag(SELECT) && sym.owner.kind == PCK) {
pos = ((JCFieldAccess) pos.getTree()).selected.pos();
if (pos.getTree() != null) {
Symbol o = sym;
JCTree tree = pos.getTree();
return diags.create(dkind, log.currentSource(),
pos, "package.not.visible", sym.packge(), details);
while (o.kind != PCK && tree.hasTag(SELECT)) {
o = o.owner;
tree = ((JCFieldAccess) tree).selected;
}
if (o.kind == PCK) {
pos = tree.pos();
return diags.create(dkind, log.currentSource(),
pos, "package.not.visible", o, details);
}
}
return diags.create(dkind, log.currentSource(),

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, 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
@ -553,7 +553,7 @@ public class Locations {
@Override
Location getLocationForModule(Path dir) {
return pathLocations.get(dir);
return (pathLocations == null) ? null : pathLocations.get(dir);
}
private boolean listed;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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,6 +29,7 @@ import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.CharBuffer;
import java.nio.file.ClosedFileSystemException;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
@ -2756,8 +2757,8 @@ public class ClassReader {
currentModule.provides = List.nil();
}
}
} catch (IOException ex) {
throw badClassFile("unable.to.access.file", ex.getMessage());
} catch (IOException | ClosedFileSystemException ex) {
throw badClassFile("unable.to.access.file", ex.toString());
} catch (ArrayIndexOutOfBoundsException ex) {
throw badClassFile("bad.class.file", c.flatname);
} finally {

View File

@ -588,7 +588,9 @@ public class Arguments {
checkOptionAllowed(t.compareTo(Target.JDK1_9) >= 0,
option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name),
Option.MODULE_SOURCE_PATH, Option.UPGRADE_MODULE_PATH,
Option.SYSTEM, Option.MODULE_PATH, Option.ADD_MODULES, Option.LIMIT_MODULES,
Option.SYSTEM, Option.MODULE_PATH, Option.ADD_MODULES,
Option.ADD_EXPORTS, Option.ADD_OPENS, Option.ADD_READS,
Option.LIMIT_MODULES,
Option.PATCH_MODULE);
if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -363,7 +363,7 @@ public class JavaCompiler {
**/
protected boolean implicitSourceFilesRead;
protected boolean enterDone;
private boolean enterDone;
protected CompileStates compileStates;
@ -1042,7 +1042,7 @@ public class JavaCompiler {
public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
modules.initModules(roots);
if (roots.isEmpty()) {
enterDone = true;
enterDone();
}
return roots;
}
@ -1063,7 +1063,7 @@ public class JavaCompiler {
enter.main(roots);
enterDone = true;
enterDone();
if (!taskListener.isEmpty()) {
for (JCCompilationUnit unit: roots) {
@ -1725,6 +1725,11 @@ public class JavaCompiler {
}
}
public void enterDone() {
enterDone = true;
annotate.enterDone();
}
public boolean isEnterDone() {
return enterDone;
}

View File

@ -184,39 +184,34 @@ public class JavacElements implements Elements {
return nameToSymbol(syms.noModule, nameStr, clazz);
}
RecoveryLoadClass prevRecoveryLoadClass = resolve.setRecoveryLoadClass((env, name) -> null);
try {
Set<S> found = new LinkedHashSet<>();
Set<S> found = new LinkedHashSet<>();
for (ModuleSymbol msym : modules.allModules()) {
S sym = nameToSymbol(msym, nameStr, clazz);
for (ModuleSymbol msym : modules.allModules()) {
S sym = nameToSymbol(msym, nameStr, clazz);
if (sym != null) {
if (!allowModules || clazz == ClassSymbol.class || !sym.members().isEmpty()) {
//do not add packages without members:
found.add(sym);
}
if (sym != null) {
if (!allowModules || clazz == ClassSymbol.class || !sym.members().isEmpty()) {
//do not add packages without members:
found.add(sym);
}
}
}
if (found.size() == 1) {
return found.iterator().next();
} else if (found.size() > 1) {
//more than one element found, produce a note:
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
String moduleNames = found.stream()
.map(s -> s.packge().modle)
.map(m -> m.toString())
.collect(Collectors.joining(", "));
log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
}
return null;
} else {
//not found, or more than one element found:
return null;
if (found.size() == 1) {
return found.iterator().next();
} else if (found.size() > 1) {
//more than one element found, produce a note:
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
String moduleNames = found.stream()
.map(s -> s.packge().modle)
.map(m -> m.toString())
.collect(Collectors.joining(", "));
log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
}
} finally {
resolve.setRecoveryLoadClass(prevRecoveryLoadClass);
return null;
} else {
//not found, or more than one element found:
return null;
}
}

View File

@ -30,7 +30,6 @@ import java.util.HashMap;
import java.util.Map;
import com.sun.source.doctree.AttributeTree.ValueKind;
import com.sun.source.doctree.DocTree;
import com.sun.tools.javac.parser.DocCommentParser.TagParser.Kind;
import com.sun.tools.javac.parser.Tokens.Comment;
import com.sun.tools.javac.parser.Tokens.TokenKind;

View File

@ -588,7 +588,7 @@ public class JavacParser implements Parser {
/**
* Ident = IDENTIFIER
*/
protected Name ident() {
public Name ident() {
return ident(false);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2017, 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
@ -92,6 +92,7 @@ import com.sun.tools.javac.util.Options;
import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import com.sun.tools.javac.comp.Annotate;
import static com.sun.tools.javac.comp.CompileStates.CompileState;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
@ -123,6 +124,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
private final JavaCompiler compiler;
private final Modules modules;
private final Types types;
private final Annotate annotate;
/**
* Holds relevant state history of which processors have been
@ -219,6 +221,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
typeUtils = JavacTypes.instance(context);
modules = Modules.instance(context);
types = Types.instance(context);
annotate = Annotate.instance(context);
processorOptions = initProcessorOptions();
unmatchedProcessorOptions = initUnmatchedProcessorOptions();
messages = JavacMessages.instance(context);
@ -1256,6 +1259,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
compiler.newRound();
modules.newRound();
types.newRound();
annotate.newRound();
boolean foundError = false;

View File

@ -1535,6 +1535,10 @@ compiler.warn.finally.cannot.complete=\
compiler.warn.poor.choice.for.module.name=\
module name {0} should avoid terminal digits
# 0: string
compiler.warn.incubating.modules=\
using incubating module(s): {0}
# 0: symbol, 1: symbol
compiler.warn.has.been.deprecated=\
{0} in {1} has been deprecated
@ -2845,6 +2849,12 @@ compiler.warn.module.not.found=\
compiler.err.too.many.modules=\
too many module declarations found
compiler.err.module.not.found.on.module.source.path=\
module not found on module source path
compiler.err.not.in.module.on.module.source.path=\
not in a module on the module source path
# 0: symbol
compiler.err.duplicate.module=\
duplicate module: {0}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -335,4 +335,16 @@ public class Convert {
}
return names;
}
public static List<Name> classCandidates(Name name) {
List<Name> names = List.nil();
String nameStr = name.toString();
int index = -1;
while ((index = nameStr.indexOf('.', index + 1)) > 0) {
String pack = nameStr.substring(0, index + 1);
String clz = nameStr.substring(index + 1).replace('.', '$');
names = names.prepend(name.table.names.fromString(pack + clz));
}
return names.reverse();
}
}

View File

@ -40,6 +40,7 @@ import com.sun.tools.doclint.DocLint;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.StringUtils;
import com.sun.tools.javadoc.main.JavaScriptScanner;
import com.sun.tools.javadoc.main.RootDocImpl;
/**
@ -188,6 +189,11 @@ public class ConfigurationImpl extends Configuration {
*/
public Set<String> doclintOpts = new LinkedHashSet<>();
/**
* Whether or not to check for JavaScript in doc comments.
*/
private boolean allowScriptInComments;
/**
* Unique Resource Handler for this package.
*/
@ -309,8 +315,11 @@ public class ConfigurationImpl extends Configuration {
doclintOpts.add(DocLint.XMSGS_CUSTOM_PREFIX + opt.substring(opt.indexOf(":") + 1));
} else if (opt.startsWith("-xdoclint/package:")) {
doclintOpts.add(DocLint.XCHECK_PACKAGE + opt.substring(opt.indexOf(":") + 1));
} else if (opt.equals("--allow-script-in-comments")) {
allowScriptInComments = true;
}
}
if (root.specifiedClasses().length > 0) {
Map<String,PackageDoc> map = new HashMap<>();
PackageDoc pd;
@ -322,15 +331,37 @@ public class ConfigurationImpl extends Configuration {
}
}
}
setCreateOverview();
setTopFile(root);
if (root instanceof RootDocImpl) {
((RootDocImpl) root).initDocLint(doclintOpts, tagletManager.getCustomTagNames(),
StringUtils.toLowerCase(htmlVersion.name()));
JavaScriptScanner jss = ((RootDocImpl) root).initJavaScriptScanner(isAllowScriptInComments());
if (jss != null) {
// In a more object-oriented world, this would be done by methods on the Option objects.
// Note that -windowtitle silently removes any and all HTML elements, and so does not need
// to be handled here.
checkJavaScript(jss, "-header", header);
checkJavaScript(jss, "-footer", footer);
checkJavaScript(jss, "-top", top);
checkJavaScript(jss, "-bottom", bottom);
checkJavaScript(jss, "-doctitle", doctitle);
checkJavaScript(jss, "-packagesheader", packagesheader);
}
}
}
private void checkJavaScript(JavaScriptScanner jss, final String opt, String value) {
jss.parse(value, new JavaScriptScanner.Reporter() {
public void report() {
root.printError(getText("doclet.JavaScript_in_option", opt));
throw new FatalError();
}
});
}
/**
* Returns the "length" of a given option. If an option takes no
* arguments, its length is one. If it takes one argument, it's
@ -366,7 +397,8 @@ public class ConfigurationImpl extends Configuration {
option.equals("-html5") ||
option.equals("-xdoclint") ||
option.startsWith("-xdoclint:") ||
option.startsWith("-xdoclint/package:")) {
option.startsWith("-xdoclint/package:") ||
option.startsWith("--allow-script-in-comments")) {
return 1;
} else if (option.equals("-help")) {
// Uugh: first, this should not be hidden inside optionLength,
@ -666,4 +698,13 @@ public class ConfigurationImpl extends Configuration {
}
tagSearchIndexKeys = tagSearchIndexMap.keySet();
}
/**
* Returns whether or not to allow JavaScript in comments.
* Default is off; can be set true from a command line option.
* @return the allowScriptInComments
*/
public boolean isAllowScriptInComments() {
return allowScriptInComments;
}
}

View File

@ -237,6 +237,8 @@ public class HtmlDoclet extends AbstractDoclet {
}
} catch (IOException e) {
throw new DocletAbortException(e);
} catch (FatalError fe) {
throw fe;
} catch (DocletAbortException de) {
de.printStackTrace();
throw de;

View File

@ -148,7 +148,9 @@ public class HtmlWriter {
public final Content descfrmInterfaceLabel;
private final Writer writer;
private final DocFile file;
private Writer writer;
protected Content script;
@ -164,7 +166,7 @@ public class HtmlWriter {
*/
public HtmlWriter(Configuration configuration, DocPath path)
throws IOException, UnsupportedEncodingException {
writer = DocFile.createFileForOutput(configuration, path).openWriter();
file = DocFile.createFileForOutput(configuration, path);
this.configuration = configuration;
this.memberDetailsListPrinted = false;
packageTableHeader = new String[] {
@ -214,6 +216,7 @@ public class HtmlWriter {
}
public void write(Content c) throws IOException {
writer = file.openWriter();
c.write(writer, true);
}

View File

@ -90,6 +90,8 @@ public abstract class AbstractDoclet {
} catch (Configuration.Fault f) {
root.printError(f.getMessage());
return false;
} catch (FatalError fe) {
return false;
} catch (DocletAbortException e) {
e.printStackTrace();
Throwable cause = e.getCause();

View File

@ -145,7 +145,14 @@ public abstract class AbstractBuilder {
configuration.root.printError("Unknown element: " + component);
throw new DocletAbortException(e);
} catch (InvocationTargetException e) {
throw new DocletAbortException(e.getCause());
Throwable cause = e.getCause();
if (cause instanceof FatalError) {
throw (FatalError) cause;
} else if (cause instanceof DocletAbortException) {
throw (DocletAbortException) cause;
} else {
throw new DocletAbortException(cause);
}
} catch (Exception e) {
e.printStackTrace();
configuration.root.printError("Exception " +

View File

@ -29,6 +29,8 @@ doclet.Encoding_not_supported=Encoding not supported: {0}
doclet.Building_Tree=Building tree for all the packages and classes...
doclet.Building_Index=Building index for all the packages and classes...
doclet.Building_Index_For_All_Classes=Building index for all classes...
doclet.JavaScript_in_option=Argument for {0} contains JavaScript.\n\
Use --allow-script-in-comments to allow use of JavaScript.
doclet.sourcetab_warning=The argument for -sourcetab must be an integer greater than 0.
doclet.Packages=Packages
doclet.Other_Packages=Other Packages

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2016, 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.doclets.internal.toolkit.util;
/**
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
@Deprecated
public class FatalError extends Error {
private static final long serialVersionUID = -9131058909576418984L;
public FatalError() { }
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2016, 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
@ -97,7 +97,7 @@ public class DocEnv {
final Enter enter;
/** The name table. */
private Names names;
private final Names names;
/** The encoding name. */
private String encoding;
@ -120,6 +120,7 @@ public class DocEnv {
JavaFileManager fileManager;
Context context;
DocLint doclint;
JavaScriptScanner javaScriptScanner;
WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
@ -858,6 +859,15 @@ public class DocEnv {
doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false);
}
JavaScriptScanner initJavaScriptScanner(boolean allowScriptInComments) {
if (allowScriptInComments) {
javaScriptScanner = null;
} else {
javaScriptScanner = new JavaScriptScanner();
}
return javaScriptScanner;
}
boolean showTagMessages() {
return (doclint == null);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -36,6 +36,8 @@ import javax.tools.FileObject;
import com.sun.javadoc.*;
import com.sun.source.util.TreePath;
import com.sun.tools.doclets.internal.toolkit.util.DocletAbortException;
import com.sun.tools.doclets.internal.toolkit.util.FatalError;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Position;
@ -128,6 +130,15 @@ public abstract class DocImpl implements Doc, Comparable<Object> {
Comment comment() {
if (comment == null) {
String d = documentation();
if (env.javaScriptScanner != null) {
env.javaScriptScanner.parse(d, new JavaScriptScanner.Reporter() {
@Override
public void report() {
env.error(DocImpl.this, "javadoc.JavaScript_in_comment");
throw new FatalError();
}
});
}
if (env.doclint != null
&& treePath != null
&& env.shouldCheck(treePath.getCompilationUnit())

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2017, 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
@ -36,6 +36,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import com.sun.tools.javac.main.JavaCompiler;
/**
* Javadoc's own enter phase does a few things above and beyond that
@ -65,16 +66,19 @@ public class JavadocEnter extends Enter {
super(context);
messager = Messager.instance0(context);
docenv = DocEnv.instance(context);
compiler = JavaCompiler.instance(context);
}
final Messager messager;
final DocEnv docenv;
final JavaCompiler compiler;
@Override
public void main(List<JCCompilationUnit> trees) {
// count all Enter errors as warnings.
int nerrors = messager.nerrors;
super.main(trees);
compiler.enterDone();
messager.nwarnings += (messager.nerrors - nerrors);
messager.nerrors = nerrors;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2017, 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
@ -219,7 +219,6 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
// Enter symbols for all files
docenv.notice("main.Building_tree");
javadocEnter.main(classTrees.toList().appendList(packageTrees.toList()));
enterDone = true;
} catch (Abort ex) {}
if (messager.nerrors() != 0)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -383,6 +383,10 @@ public class RootDocImpl extends DocImpl implements RootDoc {
env.initDoclint(opts, customTagNames, htmlVersion);
}
public JavaScriptScanner initJavaScriptScanner(boolean allowScriptInComments) {
return env.initJavaScriptScanner(allowScriptInComments);
}
public boolean isFunctionalInterface(AnnotationDesc annotationDesc) {
return env.source.allowLambda()
&& annotationDesc.annotationType().qualifiedName().equals(

View File

@ -145,6 +145,8 @@ javadoc.File_Read_Error=Error while reading file {0}
javadoc.Body_missing_from_html_file=Body tag missing from HTML file
javadoc.End_body_missing_from_html_file=Close body tag missing from HTML file
javadoc.Multiple_package_comments=Multiple sources of package comments found for package "{0}"
javadoc.JavaScript_in_comment=JavaScript found in documentation comment.\n\
Use --allow-script-in-comments to allow use of JavaScript.
javadoc.class_not_found=Class {0} not found.
javadoc.error=error
javadoc.warning=warning

View File

@ -296,9 +296,21 @@ public class ConfigurationImpl extends Configuration {
return false;
}
}
// In a more object-oriented world, this would be done by methods on the Option objects.
// Note that -windowtitle silently removes any and all HTML elements, and so does not need
// to be handled here.
utils.checkJavaScriptInOption("-header", header);
utils.checkJavaScriptInOption("-footer", footer);
utils.checkJavaScriptInOption("-top", top);
utils.checkJavaScriptInOption("-bottom", bottom);
utils.checkJavaScriptInOption("-doctitle", doctitle);
utils.checkJavaScriptInOption("-packagesheader", packagesheader);
return true;
}
@Override
public boolean finishOptionSettings() {
if (!validateOptions()) {

View File

@ -363,6 +363,9 @@ doclet.usage.frames.description=\
doclet.usage.no-frames.description=\
Disable the use of frames in the generated output
doclet.usage.allow-script-in-comments.description=\
Allow JavaScript in options and comments
doclet.usage.xdocrootparent.parameters=\
<url>
doclet.usage.xdocrootparent.description=\

View File

@ -40,6 +40,7 @@ import jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder;
import jdk.javadoc.internal.doclets.toolkit.builders.BuilderFactory;
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.UncheckedDocletException;
import jdk.javadoc.internal.doclets.toolkit.util.InternalException;
import jdk.javadoc.internal.doclets.toolkit.util.PackageListWriter;
import jdk.javadoc.internal.doclets.toolkit.util.ResourceIOException;
@ -112,8 +113,12 @@ public abstract class AbstractDoclet implements Doclet {
}
try {
startGeneration(docEnv);
return true;
try {
startGeneration(docEnv);
return true;
} catch (UncheckedDocletException e) {
throw (DocletException) e.getCause();
}
} catch (DocFileIOException e) {
switch (e.mode) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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
@ -34,6 +34,21 @@
package jdk.javadoc.internal.doclets.toolkit;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.Elements;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.IdentifierTree;
@ -43,17 +58,8 @@ import com.sun.source.util.DocTreeFactory;
import com.sun.source.util.DocTreePath;
import com.sun.source.util.DocTrees;
import com.sun.source.util.TreePath;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.Elements;
import javax.tools.FileObject;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
public class CommentUtils {
@ -168,10 +174,18 @@ public class CommentUtils {
*/
public DocCommentDuo getHtmlCommentDuo(Element e) {
FileObject fo = null;
if (e.getKind().equals(ElementKind.OTHER)) {
fo = configuration.getOverviewPath();
} else if (e.getKind().equals(ElementKind.PACKAGE)) {
fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
PackageElement pe = null;
switch (e.getKind()) {
case OTHER:
fo = configuration.getOverviewPath();
pe = configuration.workArounds.getUnnamedPackage();
break;
case PACKAGE:
fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
pe = (PackageElement)e;
break;
default:
return null;
}
if (fo == null) {
return null;
@ -181,10 +195,20 @@ public class CommentUtils {
if (dcTree == null) {
return null;
}
DocTreePath treePath = trees.getDocTreePath(fo);
DocTreePath treePath = trees.getDocTreePath(fo, pe);
return new DocCommentDuo(treePath.getTreePath(), dcTree);
}
public DocCommentTree parse(URI uri, String text) {
return trees.getDocCommentTree(new SimpleJavaFileObject(
uri, JavaFileObject.Kind.SOURCE) {
@Override @DefinedBy(Api.COMPILER)
public CharSequence getCharContent(boolean ignoreEncoding) {
return text;
}
});
}
public void setDocCommentTree(Element element, List<DocTree> fullBody,
List<DocTree> blockTags, Utils utils) {
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, blockTags);

View File

@ -227,6 +227,11 @@ public abstract class Configuration {
*/
public boolean showversion = false;
/**
* Allow JavaScript in doc comments.
*/
private boolean allowScriptInComments = false;
/**
* Sourcepath from where to read the source files. Default is classpath.
*
@ -646,6 +651,13 @@ public abstract class Configuration {
dumpOnError = true;
return true;
}
},
new Option(resources, "--allow-script-in-comments") {
@Override
public boolean process(String opt, List<String> args) {
allowScriptInComments = true;
return true;
}
}
};
Set<Doclet.Option> set = new TreeSet<>();
@ -1054,7 +1066,7 @@ public abstract class Configuration {
private final int argCount;
protected Option(Resources resources, String name, int argCount) {
this(resources, "doclet.usage." + name.toLowerCase().replaceAll("^-*", ""), name, argCount);
this(resources, "doclet.usage." + name.toLowerCase().replaceAll("^-+", ""), name, argCount);
}
protected Option(Resources resources, String keyBase, String name, int argCount) {
@ -1228,4 +1240,13 @@ public abstract class Configuration {
}
}
}
/**
* Returns whether or not to allow JavaScript in comments.
* Default is off; can be set true from a command line option.
* @return the allowScriptInComments
*/
public boolean isAllowScriptInComments() {
return allowScriptInComments;
}
}

View File

@ -44,6 +44,7 @@ import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.tools.FileObject;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
@ -59,7 +60,9 @@ import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.model.JavacElements;
@ -192,11 +195,24 @@ public class WorkArounds {
return ((VarSymbol)ve).getConstValue();
}
//TODO: DocTrees: Trees.getPath(Element e) is slow a factor 4-5 times.
// TODO: DocTrees: Trees.getPath(Element e) is slow a factor 4-5 times.
public Map<Element, TreePath> getElementToTreePath() {
return toolEnv.elementToTreePath;
}
// TODO: we need ElementUtils.getPackage to cope with input strings
// to return the proper unnamedPackage for all supported releases.
PackageElement getUnnamedPackage() {
return (toolEnv.source.allowModules())
? toolEnv.syms.unnamedModule.unnamedPackage
: toolEnv.syms.noModule.unnamedPackage;
}
// TODO: implement in either jx.l.m API (preferred) or DocletEnvironment.
FileObject getJavaFileObject(PackageElement packageElement) {
return ((PackageSymbol)packageElement).sourcefile;
}
// TODO: needs to ported to jx.l.m.
public TypeElement searchClass(TypeElement klass, String className) {
// search by qualified name first
@ -530,12 +546,6 @@ public class WorkArounds {
}
}
// TODO: this is a fast way to get the JavaFileObject for
// a package.html file, however we need to eliminate this.
public JavaFileObject getJavaFileObject(PackageElement pe) {
return toolEnv.pkgToJavaFOMap.get(pe);
}
// TODO: we need to eliminate this, as it is hacky.
/**
* Returns a representation of the package truncated to two levels.

View File

@ -35,6 +35,7 @@ import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.DocletException;
import jdk.javadoc.internal.doclets.toolkit.Messages;
import jdk.javadoc.internal.doclets.toolkit.Resources;
import jdk.javadoc.internal.doclets.toolkit.util.UncheckedDocletException;
import jdk.javadoc.internal.doclets.toolkit.util.InternalException;
import jdk.javadoc.internal.doclets.toolkit.util.SimpleDocletException;
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
@ -167,6 +168,8 @@ public abstract class AbstractBuilder {
Throwable cause = e.getCause();
if (cause instanceof DocletException) {
throw (DocletException) cause;
} else if (cause instanceof UncheckedDocletException) {
throw (DocletException) cause.getCause();
} else {
// use InternalException, so that a stacktrace showing the position of
// the internal exception is generated

View File

@ -42,6 +42,10 @@ doclet.Building_Tree=Building tree for all the packages and classes...
doclet.Building_Index=Building index for all the packages and classes...
doclet.Building_Index_For_All_Classes=Building index for all classes...
doclet.sourcetab_warning=The argument for -sourcetab must be an integer greater than 0.
doclet.JavaScript_in_comment=JavaScript found in documentation comment.\n\
Use --allow-script-in-comments to allow use of JavaScript.
doclet.JavaScript_in_option=option {0} contains JavaScript.\n\
Use --allow-script-in-comments to allow use of JavaScript.
doclet.Packages=Packages
doclet.Modules=Modules
doclet.Other_Packages=Other Packages

View File

@ -250,17 +250,19 @@ Page header and footer styles
padding:5px 0 0 0;
}
.indexNav {
margin:10px;
position:relative;
font-size:12px;
background-color:#dee3e9;
}
.indexNav ul {
padding:0;
margin:0;
margin-top:0;
padding:5px;
}
.indexNav ul li {
display:inline;
list-style-type:none;
padding-right:10px;
text-transform:uppercase;
}
.indexNav h1 {
font-size:13px;

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2016, 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 jdk.javadoc.internal.doclets.toolkit.util;
import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;
import com.sun.source.doctree.AttributeTree;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.DocTree.Kind;
import com.sun.source.doctree.StartElementTree;
import com.sun.source.util.DocTreePath;
import com.sun.source.util.DocTreePathScanner;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
/**
* A DocTree scanner to detect use of JavaScript in a doc comment tree.
*/
public class JavaScriptScanner extends DocTreePathScanner<Void, Consumer<DocTreePath>> {
public Void scan(DocCommentTree tree, TreePath p, Consumer<DocTreePath> f) {
return scan(new DocTreePath(p, tree), f);
}
@Override @DefinedBy(Api.COMPILER_TREE)
public Void visitStartElement(StartElementTree tree, Consumer<DocTreePath> f) {
String name = tree.getName().toString();
if (name.equalsIgnoreCase("script"))
f.accept(getCurrentPath());
return super.visitStartElement(tree, f);
}
@Override @DefinedBy(Api.COMPILER_TREE)
public Void visitAttribute(AttributeTree tree, Consumer<DocTreePath> f) {
String name = tree.getName().toString().toLowerCase(Locale.ENGLISH);
switch (name) {
// See https://www.w3.org/TR/html-markup/global-attributes.html#common.attrs.event-handler
case "onabort": case "onblur": case "oncanplay": case "oncanplaythrough":
case "onchange": case "onclick": case "oncontextmenu": case "ondblclick":
case "ondrag": case "ondragend": case "ondragenter": case "ondragleave":
case "ondragover": case "ondragstart": case "ondrop": case "ondurationchange":
case "onemptied": case "onended": case "onerror": case "onfocus": case "oninput":
case "oninvalid": case "onkeydown": case "onkeypress": case "onkeyup":
case "onload": case "onloadeddata": case "onloadedmetadata": case "onloadstart":
case "onmousedown": case "onmousemove": case "onmouseout": case "onmouseover":
case "onmouseup": case "onmousewheel": case "onpause": case "onplay":
case "onplaying": case "onprogress": case "onratechange": case "onreadystatechange":
case "onreset": case "onscroll": case "onseeked": case "onseeking":
case "onselect": case "onshow": case "onstalled": case "onsubmit": case "onsuspend":
case "ontimeupdate": case "onvolumechange": case "onwaiting":
// See https://www.w3.org/TR/html4/sgml/dtd.html
// Most of the attributes that take a %Script are also defined as event handlers
// in HTML 5. The one exception is onunload.
// case "onchange": case "onclick": case "ondblclick": case "onfocus":
// case "onkeydown": case "onkeypress": case "onkeyup": case "onload":
// case "onmousedown": case "onmousemove": case "onmouseout": case "onmouseover":
// case "onmouseup": case "onreset": case "onselect": case "onsubmit":
case "onunload":
f.accept(getCurrentPath());
break;
// See https://www.w3.org/TR/html4/sgml/dtd.html
// https://www.w3.org/TR/html5/
// These are all the attributes that take a %URI or a valid URL potentially surrounded
// by spaces
case "action": case "cite": case "classid": case "codebase": case "data":
case "datasrc": case "for": case "href": case "longdesc": case "profile":
case "src": case "usemap":
List<? extends DocTree> value = tree.getValue();
if (!value.isEmpty() && value.get(0).getKind() == Kind.TEXT) {
String v = value.get(0).toString().trim().toLowerCase(Locale.ENGLISH);
if (v.startsWith("javascript:")) {
f.accept(getCurrentPath());
}
}
break;
}
return super.visitAttribute(tree, f);
}
/**
* Used to indicate a fault when parsing, typically used in
* lambda methods.
*/
public static class Fault extends RuntimeException {
private static final long serialVersionUID = 0L;
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2016, 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 jdk.javadoc.internal.doclets.toolkit.util;
import jdk.javadoc.internal.doclets.toolkit.DocletException;
/**
* An unchecked exception that wraps a DocletException.
* It can be used in places where a checked exception
* is not permitted, such as in lambda expressions.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class UncheckedDocletException extends Error {
private static final long serialVersionUID = -9131058909576418984L;
public UncheckedDocletException(DocletException de) {
super(de);
}
@Override
public synchronized Throwable getCause() {
return super.getCause();
}
@Override
public synchronized Throwable initCause(Throwable cause) {
throw new UnsupportedOperationException();
}
}

View File

@ -27,6 +27,7 @@ package jdk.javadoc.internal.doclets.toolkit.util;
import java.lang.annotation.Documented;
import java.lang.ref.SoftReference;
import java.net.URI;
import java.text.CollationKey;
import java.text.Collator;
import java.util.*;
@ -108,6 +109,7 @@ public class Utils {
public final DocTrees docTrees;
public final Elements elementUtils;
public final Types typeUtils;
public final JavaScriptScanner javaScriptScanner;
public Utils(Configuration c) {
configuration = c;
@ -115,6 +117,7 @@ public class Utils {
elementUtils = c.docEnv.getElementUtils();
typeUtils = c.docEnv.getTypeUtils();
docTrees = c.docEnv.getDocTrees();
javaScriptScanner = c.isAllowScriptInComments() ? null : new JavaScriptScanner();
}
// our own little symbol table
@ -3025,6 +3028,16 @@ public class Utils {
TreePath path = isValidDuo(duo) ? duo.treePath : null;
if (!dcTreeCache.containsKey(element)) {
if (docCommentTree != null && path != null) {
if (!configuration.isAllowScriptInComments()) {
try {
javaScriptScanner.scan(docCommentTree, path, p -> {
throw new JavaScriptScanner.Fault();
});
} catch (JavaScriptScanner.Fault jsf) {
String text = configuration.getText("doclet.JavaScript_in_comment");
throw new UncheckedDocletException(new SimpleDocletException(text, jsf));
}
}
configuration.workArounds.runDocLint(path);
}
dcTreeCache.put(element, duo);
@ -3044,6 +3057,21 @@ public class Utils {
return null;
}
public void checkJavaScriptInOption(String name, String value) {
if (!configuration.isAllowScriptInComments()) {
DocCommentTree dct = configuration.cmtUtils.parse(
URI.create("option://" + name.replace("-", "")), "<body>" + value + "</body>");
try {
javaScriptScanner.scan(dct, null, p -> {
throw new JavaScriptScanner.Fault();
});
} catch (JavaScriptScanner.Fault jsf) {
String text = configuration.getText("doclet.JavaScript_in_option", name);
throw new UncheckedDocletException(new SimpleDocletException(text, jsf));
}
}
}
boolean isValidDuo(DocCommentDuo duo) {
return duo != null && duo.dcTree != null;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2017, 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
@ -39,14 +39,12 @@ import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.ModuleElement.ExportsDirective;
import javax.lang.model.element.ModuleElement.RequiresDirective;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleElementVisitor9;
import javax.tools.JavaFileManager;
@ -54,15 +52,12 @@ import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.comp.Modules;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
@ -75,9 +70,11 @@ import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static javax.tools.JavaFileObject.Kind.*;
import static jdk.javadoc.internal.tool.Main.Result.*;
import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
/**
* This class manages elements specified on the command line, and
* produces "specified" and "included" data sets, needed by the
@ -864,7 +861,7 @@ public class ElementsTable {
}
private boolean isTypeElementSelected(TypeElement te) {
return (xclasses || toolEnv.isFromSource(te)) && isSelected(te);
return (xclasses || toolEnv.getFileKind(te) == SOURCE) && isSelected(te);
}
SimpleElementVisitor9<Boolean, Void> visibleElementVisitor = null;

View File

@ -88,8 +88,7 @@ public class JavadocClassFinder extends ClassFinder {
@Override
protected void extraFileActions(PackageSymbol pack, JavaFileObject fo) {
if (fo.isNameCompatible("package", JavaFileObject.Kind.HTML)) {
toolEnv.pkgToJavaFOMap.put(pack, fo);
trees.putJavaFileObject(pack, fo);
pack.sourcefile = fo;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2017, 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
@ -36,6 +36,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import com.sun.tools.javac.main.JavaCompiler;
/**
* Javadoc's own enter phase does a few things above and beyond that
@ -64,16 +65,19 @@ public class JavadocEnter extends Enter {
super(context);
messager = Messager.instance0(context);
toolEnv = ToolEnvironment.instance(context);
compiler = JavaCompiler.instance(context);
}
final Messager messager;
final ToolEnvironment toolEnv;
final JavaCompiler compiler;
@Override
public void main(List<JCCompilationUnit> trees) {
// count all Enter errors as warnings.
int nerrors = messager.nerrors;
super.main(trees);
compiler.enterDone();
messager.nwarnings += (messager.nerrors - nerrors);
messager.nerrors = nerrors;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2017, 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
@ -202,7 +202,6 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
javadocEnter.main(classTrees.toList().appendList(packageTrees));
etable.setClassDeclList(listClasses(classTrees.toList()));
enterDone = true;
etable.analyze();
} catch (CompletionFailure cf) {
throw new ToolException(ABNORMAL, cf.getMessage(), cf);

View File

@ -182,7 +182,7 @@ public class Messager extends Log implements Reporter {
}
private String getDiagSource(DocTreePath path) {
if (path == null) {
if (path == null || path.getTreePath() == null) {
return programName;
}
JavacTrees trees = JavacTrees.instance(context);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2017, 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,7 +29,6 @@ package jdk.javadoc.internal.tool;
import java.util.*;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.JavaFileManager;
@ -116,8 +115,6 @@ public class ToolEnvironment {
WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
public final HashMap<PackageElement, JavaFileObject> pkgToJavaFOMap = new HashMap<>();
/** Allow documenting from class files? */
boolean docClasses = false;
@ -193,21 +190,11 @@ public class ToolEnvironment {
elementToTreePath.put(e, tree);
}
/**
* Returns true if the type element originates from source.
* Primarily used to disambiguate a type element associated with a source
* file versus a class file.
* @param te the type element
* @return true if the symbol is from source
*/
public boolean isFromSource(TypeElement te) {
return getFileKind(te) == Kind.SOURCE;
}
public Kind getFileKind(TypeElement te) {
JavaFileObject jfo = ((ClassSymbol)te).outermostClass().classfile;
return jfo == null ? Kind.SOURCE : jfo.getKind();
}
/**
* Print a notice, iff <em>quiet</em> is not specified.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, 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
@ -50,7 +50,7 @@ public class ModuleResolution_attribute extends Attribute {
public ModuleResolution_attribute(ConstantPool constant_pool,
int resolution_flags)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.ModulePackages),
this(constant_pool.getUTF8Index(Attribute.ModuleResolution),
resolution_flags);
}

View File

@ -128,9 +128,8 @@ import static jdk.internal.jshell.tool.ContinuousCompletionProvider.STARTSWITH_M
*/
public class JShellTool implements MessageHandler {
private static final String LINE_SEP = System.getProperty("line.separator");
private static final Pattern LINEBREAK = Pattern.compile("\\R");
private static final String RECORD_SEPARATOR = "\u241E";
static final String RECORD_SEPARATOR = "\u241E";
private static final String RB_NAME_PREFIX = "jdk.internal.jshell.tool.resources";
private static final String VERSION_RB_NAME = RB_NAME_PREFIX + ".version";
private static final String L10N_RB_NAME = RB_NAME_PREFIX + ".l10n";
@ -199,7 +198,7 @@ public class JShellTool implements MessageHandler {
private boolean debug = false;
public boolean testPrompt = false;
private String defaultStartup = null;
private String startup = null;
private Startup startup = null;
private String executionControlSpec = null;
private EditorSetting editor = BUILT_IN_EDITOR;
@ -216,7 +215,6 @@ public class JShellTool implements MessageHandler {
static final String MODE_KEY = "MODE";
static final String REPLAY_RESTORE_KEY = "REPLAY_RESTORE";
static final String DEFAULT_STARTUP_NAME = "DEFAULT";
static final Pattern BUILTIN_FILE_PATTERN = Pattern.compile("\\w+");
static final String BUILTIN_FILE_PATH_FORMAT = "/jdk/jshell/tool/resources/%s.jsh";
@ -431,13 +429,13 @@ public class JShellTool implements MessageHandler {
private final OptionSpecBuilder argX = parser.accepts("X");
private String feedbackMode = null;
private String initialStartup = null;
private Startup initialStartup = null;
String feedbackMode() {
return feedbackMode;
}
String startup() {
Startup startup() {
return initialStartup;
}
@ -485,22 +483,15 @@ public class JShellTool implements MessageHandler {
startmsg("jshell.err.opt.startup.conflict");
return null;
}
StringBuilder sb = new StringBuilder();
for (String fn : sts) {
String s = readFile(fn, "--startup");
if (s == null) {
return null;
}
sb.append(s);
}
initialStartup = sb.toString();
} else if (options.has(argNoStart)) {
initialStartup = "";
} else {
initialStartup = prefs.get(STARTUP_KEY);
initialStartup = Startup.fromFileList(sts, "--startup", new InitMessageHandler());
if (initialStartup == null) {
initialStartup = defaultStartup();
return null;
}
} else if (options.has(argNoStart)) {
initialStartup = Startup.noStartup();
} else {
String packedStartup = prefs.get(STARTUP_KEY);
initialStartup = Startup.unpack(packedStartup, new InitMessageHandler());
}
if (options.has(argExecution)) {
executionControlSpec = options.valueOf(argExecution);
@ -639,6 +630,11 @@ public class JShellTool implements MessageHandler {
return "";
}
String pp = s.replaceAll("\\R", post + pre);
if (pp.endsWith(post + pre)) {
// prevent an extra prefix char and blank line when the string
// already terminates with newline
pp = pp.substring(0, pp.length() - (post + pre).length());
}
return pre + pp + post;
}
@ -893,7 +889,7 @@ public class JShellTool implements MessageHandler {
analysis = state.sourceCodeAnalysis();
live = true;
startUpRun(startup);
startUpRun(startup.toString());
currentNameSpace = mainNamespace;
}
@ -1077,7 +1073,7 @@ public class JShellTool implements MessageHandler {
.toArray(Command[]::new);
}
private static Path toPathResolvingUserHome(String pathString) {
static Path toPathResolvingUserHome(String pathString) {
if (pathString.replace(File.separatorChar, '/').startsWith("~/"))
return Paths.get(System.getProperty("user.home"), pathString.substring(2));
else
@ -1838,48 +1834,43 @@ public class JShellTool implements MessageHandler {
return true;
}
if (hasFile) {
StringBuilder sb = new StringBuilder();
for (String fn : fns) {
String s = readFile(fn, "/set start");
if (s == null) {
return false;
}
sb.append(s);
startup = Startup.fromFileList(fns, "/set start", this);
if (startup == null) {
return false;
}
startup = sb.toString();
} else if (defaultOption) {
startup = defaultStartup();
startup = Startup.defaultStartup(this);
} else if (noneOption) {
startup = "";
startup = Startup.noStartup();
}
if (retainOption) {
// retain startup setting
prefs.put(STARTUP_KEY, startup);
prefs.put(STARTUP_KEY, startup.storedForm());
}
return true;
}
// show the "/set start" settings (retained and, if different, current)
// as commands (and file contents). All commands first, then contents.
void showSetStart() {
StringBuilder sb = new StringBuilder();
String retained = prefs.get(STARTUP_KEY);
if (retained != null) {
showSetStart(true, retained);
}
if (retained == null || !startup.equals(retained)) {
showSetStart(false, startup);
}
}
void showSetStart(boolean isRetained, String start) {
String cmd = "/set start" + (isRetained ? " -retain " : " ");
String stset;
if (start.equals(defaultStartup())) {
stset = cmd + "-default";
} else if (start.isEmpty()) {
stset = cmd + "-none";
Startup retainedStart = Startup.unpack(retained, this);
boolean currentDifferent = !startup.equals(retainedStart);
sb.append(retainedStart.show(true));
if (currentDifferent) {
sb.append(startup.show(false));
}
sb.append(retainedStart.showDetail());
if (currentDifferent) {
sb.append(startup.showDetail());
}
} else {
stset = "startup.jsh:\n" + start + "\n" + cmd + "startup.jsh";
sb.append(startup.show(false));
sb.append(startup.showDetail());
}
hard(stset);
hard(sb.toString());
}
boolean cmdDebug(String arg) {
@ -2200,13 +2191,22 @@ public class JShellTool implements MessageHandler {
case ASSIGNMENT_SUBKIND:
case OTHER_EXPRESSION_SUBKIND:
case TEMP_VAR_EXPRESSION_SUBKIND:
case STATEMENT_SUBKIND:
case UNKNOWN_SUBKIND:
if (!src.endsWith(";")) {
src = src + ";";
}
srcSet.add(src);
break;
case STATEMENT_SUBKIND:
if (src.endsWith("}")) {
// Could end with block or, for example, new Foo() {...}
// so, we need deeper analysis to know if it needs a semicolon
src = analysis.analyzeCompletion(src).source();
} else if (!src.endsWith(";")) {
src = src + ";";
}
srcSet.add(src);
break;
default:
srcSet.add(src);
break;
@ -2380,38 +2380,7 @@ public class JShellTool implements MessageHandler {
return false;
}
/**
* Read an external file. Error messages accessed via keyPrefix
*
* @param filename file to access or null
* @param context printable non-natural language context for errors
* @return contents of file as string
*/
String readFile(String filename, String context) {
if (filename != null) {
try {
byte[] encoded = Files.readAllBytes(toPathResolvingUserHome(filename));
return new String(encoded);
} catch (AccessDeniedException e) {
errormsg("jshell.err.file.not.accessible", context, filename, e.getMessage());
} catch (NoSuchFileException e) {
String resource = getResource(filename);
if (resource != null) {
// Not found as file, but found as resource
return resource;
}
errormsg("jshell.err.file.not.found", context, filename);
} catch (Exception e) {
errormsg("jshell.err.file.exception", context, filename, e);
}
} else {
errormsg("jshell.err.file.filename", context);
}
return null;
}
String getResource(String name) {
static String getResource(String name) {
if (BUILTIN_FILE_PATTERN.matcher(name).matches()) {
try {
return readResource(name);
@ -2423,33 +2392,16 @@ public class JShellTool implements MessageHandler {
}
// Read a built-in file from resources
String readResource(String name) throws IOException {
static String readResource(String name) throws IOException {
// Attempt to find the file as a resource
String spec = String.format(BUILTIN_FILE_PATH_FORMAT, name);
try (InputStream in = JShellTool.class.getResourceAsStream(spec);
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
return reader.lines().collect(Collectors.joining("\n"));
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
return reader.lines().collect(Collectors.joining("\n", "", "\n"));
}
}
// retrieve the default startup string
String defaultStartup() {
if (defaultStartup == null) {
defaultStartup = ""; // failure case
try {
defaultStartup = readResource(DEFAULT_STARTUP_NAME);
} catch (AccessDeniedException e) {
errormsg("jshell.err.file.not.accessible", "jshell", DEFAULT_STARTUP_NAME, e.getMessage());
} catch (NoSuchFileException e) {
errormsg("jshell.err.file.not.found", "jshell", DEFAULT_STARTUP_NAME);
} catch (Exception e) {
errormsg("jshell.err.file.exception", "jshell", DEFAULT_STARTUP_NAME, e);
}
}
return defaultStartup;
}
private boolean cmdReset(String rawargs) {
if (!parseCommandLineLikeFlags(rawargs, new OptionParserBase())) {
return false;
@ -2551,7 +2503,7 @@ public class JShellTool implements MessageHandler {
writer.write("\n");
}
} else if (at.hasOption("-start")) {
writer.append(startup);
writer.append(startup.toString());
} else {
String sources = (at.hasOption("-all")
? state.snippets()

View File

@ -0,0 +1,352 @@
/*
* Copyright (c) 2016, 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 jdk.internal.jshell.tool;
import java.nio.file.AccessDeniedException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static jdk.internal.jshell.tool.JShellTool.RECORD_SEPARATOR;
import static jdk.internal.jshell.tool.JShellTool.getResource;
import static jdk.internal.jshell.tool.JShellTool.readResource;
import static jdk.internal.jshell.tool.JShellTool.toPathResolvingUserHome;
/**
* Processing start-up "script" information. The startup may consist of several
* entries, each of which may have been read from a user file or be a built-in
* resource. The startup may also be empty ("-none"); Which is stored as the
* empty string different from unset (null). Built-in resources come from
* resource files. Startup is stored as named elements rather than concatenated
* text, for display purposes but also importantly so that when resources update
* with new releases the built-in will update.
* @author Robert Field
*/
class Startup {
// Store one entry in the start-up list
private static class StartupEntry {
// is this a JShell built-in?
private final boolean isBuiltIn;
// the file or resource name
private final String name;
// the commands/snippets as text
private final String content;
// for files, the date/time read in -- makes clear it is a snapshot
private final String timeStamp;
StartupEntry(boolean isBuiltIn, String name, String content) {
this(isBuiltIn, name, content, "");
}
StartupEntry(boolean isBuiltIn, String name, String content, String timeStamp) {
this.isBuiltIn = isBuiltIn;
this.name = name;
this.content = content;
this.timeStamp = timeStamp;
}
// string form to store in storage (e.g. Preferences)
String storedForm() {
return (isBuiltIn ? "*" : "-") + RECORD_SEPARATOR +
name + RECORD_SEPARATOR +
timeStamp + RECORD_SEPARATOR +
content + RECORD_SEPARATOR;
}
// the content
@Override
public String toString() {
return content;
}
@Override
public int hashCode() {
int hash = 7;
hash = 41 * hash + (this.isBuiltIn ? 1 : 0);
hash = 41 * hash + Objects.hashCode(this.name);
if (!isBuiltIn) {
hash = 41 * hash + Objects.hashCode(this.content);
}
return hash;
}
// built-ins match on name only. Time stamp isn't considered
@Override
public boolean equals(Object o) {
if (!(o instanceof StartupEntry)) {
return false;
}
StartupEntry sue = (StartupEntry) o;
return isBuiltIn == sue.isBuiltIn &&
name.equals(sue.name) &&
(isBuiltIn || content.equals(sue.content));
}
}
private static final String DEFAULT_STARTUP_NAME = "DEFAULT";
// cached DEFAULT start-up
private static Startup defaultStartup = null;
// the list of entries
private List<StartupEntry> entries;
// the concatenated content of the list of entries
private String content;
// created only with factory methods (below)
private Startup(List<StartupEntry> entries) {
this.entries = entries;
this.content = entries.stream()
.map(sue -> sue.toString())
.collect(joining());
}
private Startup(StartupEntry entry) {
this(Collections.singletonList(entry));
}
// retrieve the content
@Override
public String toString() {
return content;
}
@Override
public int hashCode() {
return 9 + Objects.hashCode(this.entries);
}
@Override
public boolean equals(Object o) {
return (o instanceof Startup)
&& entries.equals(((Startup) o).entries);
}
// are there no entries ("-none")?
boolean isEmpty() {
return entries.isEmpty();
}
// is this the "-default" setting -- one entry which is DEFAULT
boolean isDefault() {
if (entries.size() == 1) {
StartupEntry sue = entries.get(0);
if (sue.isBuiltIn && sue.name.equals(DEFAULT_STARTUP_NAME)) {
return true;
}
}
return false;
}
// string form to store in storage (e.g. Preferences)
String storedForm() {
return entries.stream()
.map(sue -> sue.storedForm())
.collect(joining());
}
// show commands to re-create
String show(boolean isRetained) {
String cmd = "/set start " + (isRetained ? "-retain " : "");
if (isDefault()) {
return cmd + "-default\n";
} else if (isEmpty()) {
return cmd + "-none\n";
} else {
return entries.stream()
.map(sue -> sue.name)
.collect(joining(" ", cmd, "\n"));
}
}
// show corresponding contents for show()
String showDetail() {
if (isDefault() || isEmpty()) {
return "";
} else {
return entries.stream()
.map(sue -> "---- " + sue.name
+ (sue.timeStamp.isEmpty()
? ""
: " @ " + sue.timeStamp)
+ " ----\n" + sue.content)
.collect(joining());
}
}
/**
* Factory method: Unpack from stored form.
*
* @param storedForm the Startup in the form as stored on persistent
* storage (e.g. Preferences)
* @param mh handler for error messages
* @return Startup, or default startup when error (message has been printed)
*/
static Startup unpack(String storedForm, MessageHandler mh) {
if (storedForm != null) {
if (storedForm.isEmpty()) {
return noStartup();
}
try {
String[] all = storedForm.split(RECORD_SEPARATOR);
if (all.length == 1) {
// legacy (content only)
return new Startup(new StartupEntry(false, "user.jsh", storedForm));
} else if (all.length % 4 == 0) {
List<StartupEntry> e = new ArrayList<>(all.length / 4);
for (int i = 0; i < all.length; i += 4) {
final boolean isBuiltIn;
switch (all[i]) {
case "*":
isBuiltIn = true;
break;
case "-":
isBuiltIn = false;
break;
default:
throw new IllegalArgumentException("Unexpected StartupEntry kind: " + all[i]);
}
String name = all[i + 1];
String timeStamp = all[i + 2];
String content = all[i + 3];
if (isBuiltIn) {
// update to current definition, use stored if removed/error
String resource = getResource(name);
if (resource != null) {
content = resource;
}
}
e.add(new StartupEntry(isBuiltIn, name, content, timeStamp));
}
return new Startup(e);
} else {
throw new IllegalArgumentException("Unexpected StartupEntry entry count: " + all.length);
}
} catch (Exception ex) {
mh.errormsg("jshell.err.corrupted.stored.startup", ex.getMessage());
}
}
return defaultStartup(mh);
}
/**
* Factory method: Read Startup from a list of external files or resources.
*
* @param fns list of file/resource names to access
* @param context printable non-natural language context for errors
* @param mh handler for error messages
* @return files as Startup, or null when error (message has been printed)
*/
static Startup fromFileList(List<String> fns, String context, MessageHandler mh) {
List<StartupEntry> entries = fns.stream()
.map(fn -> readFile(fn, context, mh))
.collect(toList());
if (entries.stream().anyMatch(sue -> sue == null)) {
return null;
}
return new Startup(entries);
}
/**
* Read a external file or a resource.
*
* @param filename file/resource to access
* @param context printable non-natural language context for errors
* @param mh handler for error messages
* @return file as startup entry, or null when error (message has been printed)
*/
private static StartupEntry readFile(String filename, String context, MessageHandler mh) {
if (filename != null) {
try {
byte[] encoded = Files.readAllBytes(toPathResolvingUserHome(filename));
return new StartupEntry(false, filename, new String(encoded),
LocalDateTime.now().format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)));
} catch (AccessDeniedException e) {
mh.errormsg("jshell.err.file.not.accessible", context, filename, e.getMessage());
} catch (NoSuchFileException e) {
String resource = getResource(filename);
if (resource != null) {
// Not found as file, but found as resource
return new StartupEntry(true, filename, resource);
}
mh.errormsg("jshell.err.file.not.found", context, filename);
} catch (Exception e) {
mh.errormsg("jshell.err.file.exception", context, filename, e);
}
} else {
mh.errormsg("jshell.err.file.filename", context);
}
return null;
}
/**
* Factory method: The empty Startup ("-none").
*
* @return the empty Startup
*/
static Startup noStartup() {
return new Startup(Collections.emptyList());
}
/**
* Factory method: The default Startup ("-default.").
*
* @param mh handler for error messages
* @return The default Startup, or empty startup when error (message has been printed)
*/
static Startup defaultStartup(MessageHandler mh) {
if (defaultStartup != null) {
return defaultStartup;
}
try {
String content = readResource(DEFAULT_STARTUP_NAME);
return defaultStartup = new Startup(
new StartupEntry(true, DEFAULT_STARTUP_NAME, content));
} catch (AccessDeniedException e) {
mh.errormsg("jshell.err.file.not.accessible", "jshell", DEFAULT_STARTUP_NAME, e.getMessage());
} catch (NoSuchFileException e) {
mh.errormsg("jshell.err.file.not.found", "jshell", DEFAULT_STARTUP_NAME);
} catch (Exception e) {
mh.errormsg("jshell.err.file.exception", "jshell", DEFAULT_STARTUP_NAME, e);
}
return defaultStartup = noStartup();
}
}

View File

@ -148,6 +148,8 @@ jshell.err.no.such.snippets = No such snippet: {0}
jshell.err.the.snippet.cannot.be.used.with.this.command = This command does not accept the snippet ''{0}'' : {1}
jshell.err.retained.mode.failure = Failure in retained modes (modes cleared) -- {0} {1}
jshell.err.corrupted.stored.startup = Corrupted stored startup, using default -- {0}
jshell.console.see.more = <press tab to see more>
jshell.console.see.javadoc = <press shift-tab again to see javadoc>
jshell.console.see.help = <press shift-tab again to see detailed help>

View File

@ -8,4 +8,3 @@ import java.util.function.*;
import java.util.prefs.*;
import java.util.regex.*;
import java.util.stream.*;

View File

@ -378,7 +378,7 @@ jck-compiler-tests: check-jck FRC
@rm -f -r $(JCK_COMPILER_OUTPUT_DIR)/work $(JCK_COMPILER_OUTPUT_DIR)/report \
$(JCK_COMPILER_OUTPUT_DIR)/diff.html $(JCK_COMPILER_OUTPUT_DIR)/status.txt
@mkdir -p $(JCK_COMPILER_OUTPUT_DIR)
$(JT_JAVA)/bin/java -Xmx512m \
$(JT_JAVA)/bin/java -Xmx1024m \
-jar $(JCK_HOME)/JCK-compiler-9/lib/jtjck.jar \
$(if $(JCK_VERBOSE),$(if $(filter $(JCK_VERBOSE),summary),-v,-v:$(JCK_VERBOSE))) \
-r:$(JCK_COMPILER_OUTPUT_DIR)/report \
@ -429,7 +429,7 @@ jck-runtime-tests: check-jck FRC
@rm -f -r $(JCK_RUNTIME_OUTPUT_DIR)/work $(JCK_RUNTIME_OUTPUT_DIR)/report \
$(JCK_RUNTIME_OUTPUT_DIR)/diff.html $(JCK_RUNTIME_OUTPUT_DIR)/status.txt
@mkdir -p $(JCK_RUNTIME_OUTPUT_DIR)
$(JT_JAVA)/bin/java -Xmx512m \
$(JT_JAVA)/bin/java -Xmx1024m \
-jar $(JCK_HOME)/JCK-runtime-9/lib/jtjck.jar \
$(if $(JCK_VERBOSE),$(if $(filter $(JCK_VERBOSE),summary),-v,-v:$(JCK_VERBOSE))) \
-r:$(JCK_RUNTIME_OUTPUT_DIR)/report \

View File

@ -14,8 +14,8 @@ keys=intermittent randomness
# Group definitions
groups=TEST.groups
# Tests using jtreg 4.2 b04 features
requiredVersion=4.2 b04
# Tests using jtreg 4.2 b05 features
requiredVersion=4.2 b05
# Use new module options
useNewOptions=true

View File

@ -0,0 +1,313 @@
/*
* Copyright (c) 2016, 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.
*/
/**
* @test
* @bug 8138725
* @summary test --allow-script-in-comments
* @modules jdk.javadoc/jdk.javadoc.internal.tool
*/
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Combo-style test, exercising combinations of different HTML fragments that may contain
* JavaScript, different places to place those fragments, and whether or not to allow the use
* of JavaScript.
*/
public class TestScriptInComment {
public static void main(String... args) throws Exception {
new TestScriptInComment().run();
}
/**
* Representative samples of different fragments of HTML that may contain JavaScript.
* To facilitate checking the output manually in a browser, the text "#ALERT" will be
* replaced by a JavaScript call of "alert(msg)", using a message string that is specific
* to the test case.
*/
enum Comment {
LC("<script>#ALERT</script>", true), // script tag in Lower Case
UC("<SCRIPT>#ALERT</script>", true), // script tag in Upper Case
WS("< script >#ALERT</script>", false, "-Xdoclint:none"), // script tag with invalid white space
SP("<script src=\"file\"> #ALERT </script>", true), // script tag with an attribute
ON("<a onclick='#ALERT'>x</a>", true), // event handler attribute
URI("<a href='javascript:#ALERT'>x</a>", true); // javascript URI
/**
* Creates an HTML fragment to be injected into a template.
* @param text the HTML fragment to put into a doc comment or option.
* @param hasScript whether or not this fragment does contain legal JavaScript
* @param opts any additional options to be specified when javadoc is run
*/
Comment(String text, boolean hasScript, String... opts) {
this.text = text;
this.hasScript = hasScript;
this.opts = Arrays.asList(opts);
}
final String text;
final boolean hasScript;
final List<String> opts;
};
/**
* Representative samples of positions in which javadoc may find JavaScript.
* Each template contains a series of strings, which are written to files or inferred as options.
* The first source file implies a corresponding output file which should not be written
* if the comment contains JavaScript and JavaScript is not allowed.
*/
enum Template {
OVR("<html><body> overview #COMMENT </body></html>", "package p; public class C { }"),
PKGINFO("#COMMENT package p;", "package p; public class C { }"),
PKGHTML("<html><body>#COMMENT package p;</body></html>", "package p; public class C { }"),
CLS("package p; #COMMENT public class C { }"),
CON("package p; public class C { #COMMENT public C() { } }"),
FLD("package p; public class C { #COMMENT public int f; }"),
MTH("package p; public class C { #COMMENT public void m() { } }"),
TOP("-top", "lorem #COMMENT ipsum", "package p; public class C { }"),
HDR("-header", "lorem #COMMENT ipsum", "package p; public class C { }"),
FTR("-footer", "lorem #COMMENT ipsum", "package p; public class C { }"),
BTM("-bottom", "lorem #COMMENT ipsum", "package p; public class C { }"),
DTTL("-doctitle", "lorem #COMMENT ipsum", "package p; public class C { }"),
PHDR("-packagesheader", "lorem #COMMENT ipsum", "package p; public class C { }");
Template(String... args) {
opts = new ArrayList<String>();
sources = new ArrayList<String>();
int i = 0;
while (args[i].startsWith("-")) {
// all options being tested have a single argument that follow the option
opts.add(args[i++]);
opts.add(args[i++]);
}
while(i < args.length) {
sources.add(args[i++]);
}
}
// groups: 1 <html> or not; 2: package name; 3: class name
private final Pattern pat =
Pattern.compile("(?i)(<html>)?.*?(?:package ([a-z]+);.*?(?:class ([a-z]+).*)?)?");
/**
* Infer the file in which to write the given source.
* @param dir the base source directory
* @param src the source text
* @return the file in which the source should be written
*/
File getSrcFile(File srcDir, String src) {
String f;
Matcher m = pat.matcher(src);
if (!m.matches())
throw new Error("match failed");
if (m.group(3) != null) {
f = m.group(2) + "/" + m.group(3) + ".java";
} else if (m.group(2) != null) {
f = m.group(2) + "/" + (m.group(1) == null ? "package-info.java" : "package.html");
} else {
f = "overview.html";
}
return new File(srcDir, f);
}
/**
* Get the options to give to javadoc.
* @param srcDir the srcDir to use -overview is needed
* @return
*/
List<String> getOpts(File srcDir) {
if (!opts.isEmpty()) {
return opts;
} else if (sources.get(0).contains("overview")) {
return Arrays.asList("-overview", getSrcFile(srcDir, sources.get(0)).getPath());
} else {
return Collections.emptyList();
}
}
/**
* Gets the output file corresponding to the first source file.
* This file should not be written if the comment contains JavaScript and JavaScripot is
* not allowed.
* @param dir the base output directory
* @return the output file
*/
File getOutFile(File outDir) {
String f;
Matcher m = pat.matcher(sources.get(0));
if (!m.matches())
throw new Error("match failed");
if (m.group(3) != null) {
f = m.group(2) + "/" + m.group(3) + ".html";
} else if (m.group(2) != null) {
f = m.group(2) + "/package-summary.html";
} else {
f = "overview-summary.html";
}
return new File(outDir, f);
}
final List<String> opts;
final List<String> sources;
};
enum Option {
OFF(null),
ON("--allow-script-in-comments");
Option(String text) {
this.text = text;
}
final String text;
};
private PrintStream out = System.err;
public void run() throws Exception {
int count = 0;
for (Template template: Template.values()) {
for (Comment comment: Comment.values()) {
for (Option option: Option.values()) {
if (test(template, comment, option)) {
count++;
}
}
}
}
out.println(count + " test cases run");
if (errors > 0) {
throw new Exception(errors + " errors occurred");
}
}
boolean test(Template template, Comment comment, Option option) throws IOException {
if (option == Option.ON && !comment.hasScript) {
// skip --allowScriptInComments if comment does not contain JavaScript
return false;
}
String test = template + "-" + comment + "-" + option;
out.println("Test: " + test);
File dir = new File(test);
dir.mkdirs();
File srcDir = new File(dir, "src");
File outDir = new File(dir, "out");
String alert = "alert(\"" + test + "\");";
for (String src: template.sources) {
writeFile(template.getSrcFile(srcDir, src),
src.replace("#COMMENT",
"/** " + comment.text.replace("#ALERT", alert) + " **/"));
}
List<String> opts = new ArrayList<String>();
opts.add("-sourcepath");
opts.add(srcDir.getPath());
opts.add("-d");
opts.add(outDir.getPath());
if (option.text != null)
opts.add(option.text);
for (String opt: template.getOpts(srcDir)) {
opts.add(opt.replace("#COMMENT", comment.text.replace("#ALERT", alert)));
}
opts.addAll(comment.opts);
opts.add("-noindex"); // index not required; save time/space writing files
opts.add("p");
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
int rc = javadoc(opts, pw);
pw.close();
String log = sw.toString();
writeFile(new File(dir, "log.txt"), log);
out.println("opts: " + opts);
out.println(" rc: " + rc);
out.println(" log:");
out.println(log);
String ERROR = "Use --allow-script-in-comment";
File outFile = template.getOutFile(outDir);
boolean expectErrors = comment.hasScript && (option == Option.OFF);
if (expectErrors) {
check(rc != 0, "unexpected exit code: " + rc);
check(log.contains(ERROR), "expected error message not found");
check(!outFile.exists(), "output file found unexpectedly");
} else {
check(rc == 0, "unexpected exit code: " + rc);
check(!log.contains(ERROR), "error message found");
check(outFile.exists(), "output file not found");
}
out.println();
return true;
}
int javadoc(List<String> opts, PrintWriter pw) {
return jdk.javadoc.internal.tool.Main.execute(opts.toArray(new String[opts.size()]), pw);
}
File writeFile(File f, String text) throws IOException {
f.getParentFile().mkdirs();
FileWriter fw = new FileWriter(f);
try {
fw.write(text);
} finally {
fw.close();
}
return f;
}
void check(boolean cond, String errMessage) {
if (!cond) {
error(errMessage);
}
}
void error(String message) {
out.println("Error: " + message);
errors++;
}
int errors = 0;
}

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2016, 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.
*
* 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.
*/
/*
* @test
* @bug 8157611
* @summary test DocTrees is working correctly relative to HTML access
* @modules
* jdk.javadoc/jdk.javadoc.internal.api
* jdk.javadoc/jdk.javadoc.internal.tool
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* @library /tools/lib
* @build toolbox.ToolBox toolbox.TestRunner
* @run main TestDocTrees
*/
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import toolbox.*;
import toolbox.Task.Expect;
import static toolbox.Task.OutputKind.*;
/**
* This class is used to test DocTrees functionality relating to
* package and overview HTML files.
*/
public class TestDocTrees extends TestRunner {
final ToolBox tb;
final File testFile;
final File testSrc;
final File overviewFile;
TestDocTrees() throws IOException {
super(System.err);
tb = new ToolBox();
testSrc = new File(System.getProperty("test.src"));
testFile = new File(testSrc, "TestDocTrees.java");
overviewFile = new File(testSrc, "overview.html");
}
protected void runTests() throws Exception {
runTests(m -> new Object[]{Paths.get(m.getName())});
}
public static void main(String... args) throws Exception {
new TestDocTrees().runTests();
}
@Test
public void testOverviewWithRelease8(Path out) {
execTask("-d", out.toString(),
"--release", "8",
"-Xdoclint:all",
"-Xdoclint:-missing",
"-sourcepath", testSrc.getAbsolutePath(),
testFile.getAbsolutePath(),
"-overview", overviewFile.getAbsolutePath());
}
@Test
public void testOverviewWithoutRelease(Path out) throws Exception {
execTask("-d", out.toString(),
"-Xdoclint:all",
"-Xdoclint:-missing",
"-sourcepath", testSrc.getAbsolutePath(),
testFile.getAbsolutePath(),
"-overview", overviewFile.getAbsolutePath());
}
private Task.Result execTask(String... args) {
JavadocTask et = new JavadocTask(tb, Task.Mode.CMDLINE);
//args.forEach((a -> System.err.println("arg: " + a)));
return et.options(args).run();
}
}

View File

@ -0,0 +1,27 @@
<!--
Copyright (c) 2016, 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.
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
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.
-->
<html>
<body>
<b>{@link omg.what.gives}</b>
</body>
</html>

View File

@ -24,7 +24,7 @@
/*
* @test
* @summary Testing external editor.
* @bug 8143955 8080843 8163816 8143006 8169828
* @bug 8143955 8080843 8163816 8143006 8169828 8171130
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build ReplToolTesting CustomEditor EditorTestBase
* @run testng ExternalEditorTest
@ -50,6 +50,7 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
public class ExternalEditorTest extends EditorTestBase {
@ -119,6 +120,28 @@ public class ExternalEditorTest extends EditorTestBase {
super.testEditor(defaultStartup, args, t);
}
@Test
public void testStatementSemicolonAddition() {
testEditor(
a -> assertCommand(a, "if (true) {}", ""),
a -> assertCommand(a, "if (true) {} else {}", ""),
a -> assertCommand(a, "Object o", "o ==> null"),
a -> assertCommand(a, "if (true) o = new Object() { int x; }", ""),
a -> assertCommand(a, "if (true) o = new Object() { int y; }", ""),
a -> assertCommand(a, "System.err.flush()", ""), // test still ; for expression statement
a -> assertEditOutput(a, "/ed", "", () -> {
assertEquals(getSource(),
"if (true) {}\n" +
"if (true) {} else {}\n" +
"Object o;\n" +
"if (true) o = new Object() { int x; };\n" +
"if (true) o = new Object() { int y; };\n" +
"System.err.flush();\n");
exit();
})
);
}
private static boolean isWindows() {
return System.getProperty("os.name").startsWith("Windows");
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8157395 8157393 8157517 8158738 8167128 8163840 8167637 8170368 8172102
* @bug 8157395 8157393 8157517 8158738 8167128 8163840 8167637 8170368 8172102 8172179
* @summary Tests of jshell comand options, and undoing operations
* @modules jdk.jshell/jdk.internal.jshell.tool
* jdk.compiler/com.sun.tools.javac.api
@ -273,14 +273,13 @@ public class ToolCommandOptionTest extends ReplToolTesting {
(a) -> assertCommand(a, "/set start DEFAULT PRINTING",
""),
(a) -> assertCommandOutputContains(a, "/set start",
"void println", "import java.util.*"),
"/set start DEFAULT PRINTING", "void println", "import java.util.*"),
(a) -> assertCommand(a, "/set start " + startup.toString(),
""),
(a) -> assertCommand(a, "/set start",
"| startup.jsh:\n" +
"| int iAmHere = 1234;\n" +
"| \n" +
"| /set start startup.jsh"),
(a) -> assertCommandOutputContains(a, "/set start",
"| /set start " + startup + "\n" +
"| ---- " + startup + " @ ", " ----\n" +
"| int iAmHere = 1234;\n"),
(a) -> assertCommand(a, "/se sta -no",
""),
(a) -> assertCommand(a, "/set start",
@ -322,11 +321,18 @@ public class ToolCommandOptionTest extends ReplToolTesting {
"| /set start -retain -none"),
(a) -> assertCommand(a, "/set start -retain " + startup.toString(),
""),
(a) -> assertCommand(a, "/set start",
"| startup.jsh:\n" +
"| int iAmHere = 1234;\n" +
"| \n" +
"| /set start -retain startup.jsh")
(a) -> assertCommand(a, "/set start DEFAULT PRINTING",
""),
(a) -> assertCommandOutputStartsWith(a, "/set start",
"| /set start -retain " + startup.toString() + "\n" +
"| /set start DEFAULT PRINTING\n" +
"| ---- " + startup.toString() + " @ "),
(a) -> assertCommandOutputContains(a, "/set start",
"| ---- DEFAULT ----\n",
"| ---- PRINTING ----\n",
"| int iAmHere = 1234;\n",
"| void println(String s)",
"| import java.io.*;")
);
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840 8166637 8161969
* @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840 8166637 8161969 8173007
* @summary Tests for output customization
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@ -38,8 +38,6 @@ import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
@ -140,6 +138,66 @@ public class ToolFormatTest extends ReplToolTesting {
);
}
public void testSetFormatSelectorSample() {
test(
(a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet",
"| Created new feedback mode: ate"),
(a) -> assertCommand(a, "/set feedback ate", ""),
(a) -> assertCommand(a, "/set format ate display '---replaced,modified,added-primary---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++replaced,modified,added-primary+++' replaced,modified,added-primary", ""),
(a) -> assertCommand(a, "\"replaced,modified,added-primary\"", "+++replaced,modified,added-primary+++"),
(a) -> assertCommand(a, "/set format ate display '---added-primary,update---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++added-primary,update+++' added-primary,update", ""),
(a) -> assertCommand(a, "\"added-primary,update\"", "+++added-primary,update+++"),
(a) -> assertCommand(a, "/set format ate display '---method-replaced-primary---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++method-replaced-primary+++' method-replaced-primary", ""),
(a) -> assertCommand(a, "\"method-replaced-primary\"", "---method-replaced-primary---"),
(a) -> assertCommand(a, "/set format ate display '---method-replaced-update---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++method-replaced-update+++' method-replaced-update", ""),
(a) -> assertCommand(a, "\"method-replaced-update\"", "---method-replaced-update---"),
(a) -> assertCommand(a, "/set format ate display '---method-added-update---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++method-added-update+++' method-added-update", ""),
(a) -> assertCommand(a, "\"method-added-update\"", "---method-added-update---"),
(a) -> assertCommand(a, "/set format ate display '---method-added---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++method-added+++' method-added", ""),
(a) -> assertCommand(a, "\"method-added\"", "---method-added---"),
(a) -> assertCommand(a, "/set format ate display '---class-modified,added-primary,update---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++class-modified,added-primary,update+++' class-modified,added-primary,update", ""),
(a) -> assertCommand(a, "\"class-modified,added-primary,update\"", "---class-modified,added-primary,update---"),
(a) -> assertCommand(a, "/set format ate display '---class-modified,added-primary---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++class-modified,added-primary+++' class-modified,added-primary", ""),
(a) -> assertCommand(a, "\"class-modified,added-primary\"", "---class-modified,added-primary---"),
(a) -> assertCommand(a, "/set format ate display '---class-modified,added-update---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++class-modified,added-update+++' class-modified,added-update", ""),
(a) -> assertCommand(a, "\"class-modified,added-update\"", "---class-modified,added-update---"),
(a) -> assertCommand(a, "/set format ate display '---replaced,added---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++replaced,added+++' replaced,added", ""),
(a) -> assertCommand(a, "\"replaced,added\"", "+++replaced,added+++"),
(a) -> assertCommand(a, "/set format ate display '---replaced-primary,update---'", ""),
(a) -> assertCommand(a, "/set format ate display '+++replaced-primary,update+++' replaced-primary,update", ""),
(a) -> assertCommand(a, "\"replaced-primary,update\"", "---replaced-primary,update---"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal")
);
}
// This test is exhaustive and takes to long for routine testing -- disabled.
// A sampling of these has been added (above: testSetFormatSelectorSample).
// See 8173007
// Save for possible future deep testing or debugging
@Test(enabled = false)
public void testSetFormatSelector() {
List<ReplTest> tests = new ArrayList<>();
tests.add((a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet",
@ -202,6 +260,11 @@ public class ToolFormatTest extends ReplToolTesting {
tests.add((a) -> assertCommand(a, "/set format ate display '" + no + "'", ""));
tests.add((a) -> assertCommand(a, "/set format ate display '" + yes + "' " + select, ""));
tests.add((a) -> assertCommand(a, "\"" + select + "\"", expect));
/**** for sample generation ****
System.err.println(" (a) -> assertCommand(a, \"/set format ate display '" + no + "'\", \"\"),");
System.err.println(" (a) -> assertCommand(a, \"/set format ate display '" + yes + "' " + select + "\", \"\"),");
System.err.println(" (a) -> assertCommand(a, \"\\\"" + select + "\\\"\", \"" + expect + "\"),\n");
****/
}
}
}

View File

@ -19,10 +19,7 @@ OtherTagsTest.java:20: error: element not allowed in documentation comments: <me
OtherTagsTest.java:21: error: element not allowed in documentation comments: <noframes>
* <noframes> </noframes>
^
OtherTagsTest.java:22: error: element not allowed in documentation comments: <script>
* <script> </script>
^
OtherTagsTest.java:23: error: element not allowed in documentation comments: <title>
* <title> </title>
^
9 errors
8 errors

View File

@ -143,6 +143,7 @@ public class ParameterNamesAreNotCopiedToAnonymousInitTest {
Arrays.asList(new File(System.getProperty("test.src"),
this.getClass().getName() + ".java")));
java.util.List<String> options = Arrays.asList(
"--add-modules", "jdk.jdeps",
"--add-exports", "jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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
@ -24,7 +24,7 @@
/*
* @test
* @summary Module attribute tests
* @bug 8080878 8161906 8162713
* @bug 8080878 8161906 8162713 8170250
* @modules java.compiler
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@ -52,6 +52,28 @@ public class ModuleTest extends ModuleTestBase {
testModuleAttribute(base, moduleDescriptor);
}
@Test
public void testOpenEmptyModule(Path base) throws Exception {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m", ModuleFlag.OPEN)
.write(base);
compile(base);
testModuleAttribute(base, moduleDescriptor);
}
@Test
public void testModuleName(Path base) throws Exception {
testName("module.name", base.resolve("dot"));
testName("module.exports.component.subcomponent.more.dots", base.resolve("dots"));
testName("moduleName", base.resolve("noDots"));
}
private void testName(String name, Path path) throws Exception{
ModuleDescriptor moduleDescriptor = new ModuleDescriptor(name)
.write(path);
compile(path);
testModuleAttribute(path, moduleDescriptor);
}
@Test
public void testExports(Path base) throws Exception {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
@ -91,16 +113,6 @@ public class ModuleTest extends ModuleTestBase {
testModuleAttribute(base, moduleDescriptor);
}
@Test
public void testQualifiedDynamicExports(Path base) throws Exception {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
.exportsTo("pack", "jdk.compiler")
.write(base);
tb.writeJavaFiles(base, "package pack; public class A { }");
compile(base);
testModuleAttribute(base, moduleDescriptor);
}
@Test
public void testSeveralQualifiedExports(Path base) throws Exception {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
@ -120,6 +132,47 @@ public class ModuleTest extends ModuleTestBase {
testModuleAttribute(base, moduleDescriptor);
}
@Test
public void testOpens(Path base) throws Exception {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("module.name")
.opens("pack")
.write(base);
tb.writeJavaFiles(base, "package pack; public class C extends java.util.ArrayList{ }");
compile(base);
testModuleAttribute(base, moduleDescriptor);
}
@Test
public void testQualifiedOpens(Path base) throws Exception {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
.opensTo("pack", "jdk.compiler")
.write(base);
tb.writeJavaFiles(base, "package pack; public class A { }");
compile(base);
testModuleAttribute(base, moduleDescriptor);
}
@Test
public void testSeveralOpens(Path base) throws Exception {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("module.m1.name")
.opensTo("pack", "jdk.compiler, jdk.jdeps")
.opensTo("pack2", "jdk.jdeps")
.opensTo("pack3", "jdk.compiler")
.opensTo("pack4", "jdk.compiler, jdk.jdeps")
.opensTo("pack5", "jdk.compiler")
.opens("pack6")
.write(base);
tb.writeJavaFiles(base,
"package pack; public class A {}",
"package pack2; public class B {}",
"package pack3; public class C {}",
"package pack4; public class C {}",
"package pack5; public class C {}",
"package pack6; public class C {}");
compile(base);
testModuleAttribute(base, moduleDescriptor);
}
@Test
public void testRequires(Path base) throws Exception {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
@ -182,10 +235,12 @@ public class ModuleTest extends ModuleTestBase {
.provides("java.util.Collection", "pack2.D")
.provides("java.util.List", "pack2.D")
.requires("jdk.compiler")
.provides("javax.tools.FileObject", "pack2.E")
.provides("com.sun.tools.javac.Main", "pack2.C")
.write(base);
tb.writeJavaFiles(base, "package pack2; public class D extends java.util.ArrayList{ }",
"package pack2; public class C extends com.sun.tools.javac.Main{ }");
"package pack2; public class C extends com.sun.tools.javac.Main{ }",
"package pack2; public class E extends javax.tools.SimpleJavaFileObject{ public E(){ super(null,null); } }");
compile(base);
testModuleAttribute(base, moduleDescriptor);
}
@ -203,9 +258,10 @@ public class ModuleTest extends ModuleTestBase {
public void testSeveralUses(Path base) throws Exception {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
.uses("java.util.List")
.uses("java.util.Collection")
.uses("java.util.Collection") // from java.base
.requires("jdk.compiler")
.uses("javax.tools.JavaCompiler")
.uses("javax.tools.JavaCompiler") // from java.compiler
.uses("com.sun.tools.javac.Main") // from jdk.compiler
.write(base);
compile(base);
testModuleAttribute(base, moduleDescriptor);
@ -216,9 +272,52 @@ public class ModuleTest extends ModuleTestBase {
Path m1 = base.resolve("m1x");
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m1x")
.exports("pack1")
.exports("pack3")
.opens("pack3")
.exportsTo("packTo1", "m2x")
.opensTo("packTo1", "m2x") // the same as exportsTo
.opensTo("packTo3", "m3x")
.requires("jdk.compiler")
.requires("m2x", RequiresFlag.TRANSITIVE)
.requires("m3x", RequiresFlag.STATIC)
.requires("m4x", RequiresFlag.TRANSITIVE, RequiresFlag.STATIC)
.provides("java.util.List", "pack1.C", "pack2.D")
.uses("java.util.List")
.uses("java.nio.file.Path")
.requires("jdk.jdeps", RequiresFlag.STATIC, RequiresFlag.TRANSITIVE)
.requires("m5x", RequiresFlag.STATIC)
.requires("m6x", RequiresFlag.TRANSITIVE)
.requires("java.compiler")
.opensTo("packTo4", "java.compiler")
.exportsTo("packTo2", "java.compiler")
.opens("pack2") // same as exports
.opens("pack4")
.exports("pack2")
.write(m1);
tb.writeJavaFiles(m1, "package pack1; public class C extends java.util.ArrayList{ }",
"package pack2; public class D extends java.util.ArrayList{ }",
"package pack3; public class D extends java.util.ArrayList{ }",
"package pack4; public class D extends java.util.ArrayList{ }");
tb.writeJavaFiles(m1,
"package packTo1; public class T1 {}",
"package packTo2; public class T2 {}",
"package packTo3; public class T3 {}",
"package packTo4; public class T4 {}");
tb.writeJavaFiles(base.resolve("m2x"), "module m2x { }");
tb.writeJavaFiles(base.resolve("m3x"), "module m3x { }");
tb.writeJavaFiles(base.resolve("m4x"), "module m4x { }");
tb.writeJavaFiles(base.resolve("m5x"), "module m5x { }");
tb.writeJavaFiles(base.resolve("m6x"), "module m6x { }");
compile(base, "--module-source-path", base.toString(),
"-d", base.toString());
testModuleAttribute(m1, moduleDescriptor);
}
@Test
public void testOpenComplexModule(Path base) throws Exception {
Path m1 = base.resolve("m1x");
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m1x", ModuleFlag.OPEN)
.exports("pack1")
.exportsTo("packTo1", "m2x")
.exportsTo("packTo3", "m3x")
.requires("jdk.compiler")
.requires("m2x", RequiresFlag.TRANSITIVE)
.requires("m3x", RequiresFlag.STATIC)
@ -230,9 +329,7 @@ public class ModuleTest extends ModuleTestBase {
.requires("m5x", RequiresFlag.STATIC)
.requires("m6x", RequiresFlag.TRANSITIVE)
.requires("java.compiler")
.exportsTo("packTo4", "java.compiler")
.exportsTo("packTo2", "java.compiler")
.exports("pack4")
.exports("pack2")
.write(m1);
tb.writeJavaFiles(m1, "package pack1; public class C extends java.util.ArrayList{ }",

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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,6 @@ import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Module_attribute;
import com.sun.tools.javac.util.Pair;
import java.io.IOException;
import java.lang.annotation.Retention;
@ -36,11 +35,11 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -74,20 +73,30 @@ public class ModuleTestBase {
ClassFile classFile = ClassFile.read(modulePath.resolve("module-info.class"));
Module_attribute moduleAttribute = (Module_attribute) classFile.getAttribute("Module");
ConstantPool constantPool = classFile.constant_pool;
testModuleName(moduleDescriptor, moduleAttribute, constantPool);
testModuleFlags(moduleDescriptor, moduleAttribute);
testRequires(moduleDescriptor, moduleAttribute, constantPool);
testExports(moduleDescriptor, moduleAttribute, constantPool);
testOpens(moduleDescriptor, moduleAttribute, constantPool);
testProvides(moduleDescriptor, moduleAttribute, constantPool);
testUses(moduleDescriptor, moduleAttribute, constantPool);
}
private void testModuleName(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
tr.checkEquals(constantPool.getModuleInfo(module.module_name).getName(), moduleDescriptor.name, "Unexpected module name");
}
private void testModuleFlags(ModuleDescriptor moduleDescriptor, Module_attribute module) {
tr.checkEquals(module.module_flags, moduleDescriptor.flags, "Unexpected module flags");
}
private void testRequires(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
tr.checkEquals(module.requires_count, moduleDescriptor.requires.size(), "Wrong amount of requires.");
List<Pair<String, Integer>> actualRequires = new ArrayList<>();
List<Requires> actualRequires = new ArrayList<>();
for (Module_attribute.RequiresEntry require : module.requires) {
actualRequires.add(Pair.of(
require.getRequires(constantPool).replace('/', '.'),
actualRequires.add(new Requires(
require.getRequires(constantPool),
require.requires_flags));
}
tr.checkContains(actualRequires, moduleDescriptor.requires, "Lists of requires don't match");
@ -104,18 +113,36 @@ public class ModuleTestBase {
tr.checkEquals(export.exports_to_count, expectedTo.size(), "Wrong amount of exports to");
List<String> actualTo = new ArrayList<>();
for (int toIdx : export.exports_to_index) {
actualTo.add(constantPool.getModuleInfo(toIdx).getName().replace('/', '.'));
actualTo.add(constantPool.getModuleInfo(toIdx).getName());
}
tr.checkContains(actualTo, expectedTo, "Lists of \"exports to\" don't match.");
}
}
}
private void testOpens(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
tr.checkEquals(module.opens_count, moduleDescriptor.opens.size(), "Wrong amount of opens.");
for (Module_attribute.OpensEntry open : module.opens) {
String pkg = constantPool.getPackageInfo(open.opens_index).getName();
if (tr.checkTrue(moduleDescriptor.opens.containsKey(pkg), "Unexpected open " + pkg)) {
Open expectedOpen = moduleDescriptor.opens.get(pkg);
tr.checkEquals(expectedOpen.mask, open.opens_flags, "Wrong open flags");
List<String> expectedTo = expectedOpen.to;
tr.checkEquals(open.opens_to_count, expectedTo.size(), "Wrong amount of opens to");
List<String> actualTo = new ArrayList<>();
for (int toIdx : open.opens_to_index) {
actualTo.add(constantPool.getModuleInfo(toIdx).getName());
}
tr.checkContains(actualTo, expectedTo, "Lists of \"opens to\" don't match.");
}
}
}
private void testUses(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
tr.checkEquals(module.uses_count, moduleDescriptor.uses.size(), "Wrong amount of uses.");
List<String> actualUses = new ArrayList<>();
for (int usesIdx : module.uses_index) {
String uses = constantPool.getClassInfo(usesIdx).getBaseName().replace('/', '.');
String uses = constantPool.getClassInfo(usesIdx).getBaseName();
actualUses.add(uses);
}
tr.checkContains(actualUses, moduleDescriptor.uses, "Lists of uses don't match");
@ -131,10 +158,10 @@ public class ModuleTestBase {
tr.checkEquals(moduleProvidesCount, moduleDescriptorProvidesCount, "Wrong amount of provides.");
Map<String, List<String>> actualProvides = new HashMap<>();
for (Module_attribute.ProvidesEntry provide : module.provides) {
String provides = constantPool.getClassInfo(provide.provides_index).getBaseName().replace('/', '.');
String provides = constantPool.getClassInfo(provide.provides_index).getBaseName();
List<String> impls = new ArrayList<>();
for (int i = 0; i < provide.with_count; i++) {
String with = constantPool.getClassInfo(provide.with_index[i]).getBaseName().replace('/', '.');
String with = constantPool.getClassInfo(provide.with_index[i]).getBaseName();
impls.add(with);
}
actualProvides.put(provides, impls);
@ -163,9 +190,27 @@ public class ModuleTestBase {
int getMask();
}
public enum ModuleFlag implements Mask {
OPEN("open", Module_attribute.ACC_OPEN);
private final String token;
private final int mask;
ModuleFlag(String token, int mask) {
this.token = token;
this.mask = mask;
}
@Override
public int getMask() {
return mask;
}
}
public enum RequiresFlag implements Mask {
TRANSITIVE("transitive", Module_attribute.ACC_TRANSITIVE),
STATIC("static", Module_attribute.ACC_STATIC_PHASE);
STATIC("static", Module_attribute.ACC_STATIC_PHASE),
MANDATED("", Module_attribute.ACC_MANDATED);
private final String token;
private final int mask;
@ -181,13 +226,30 @@ public class ModuleTestBase {
}
}
public enum ExportFlag implements Mask {
public enum ExportsFlag implements Mask {
SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
private final String token;
private final int mask;
ExportFlag(String token, int mask) {
ExportsFlag(String token, int mask) {
this.token = token;
this.mask = mask;
}
@Override
public int getMask() {
return mask;
}
}
public enum OpensFlag implements Mask {
SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
private final String token;
private final int mask;
OpensFlag(String token, int mask) {
this.token = token;
this.mask = mask;
}
@ -199,27 +261,64 @@ public class ModuleTestBase {
}
private class Export {
String pkg;
int mask;
List<String> to = new ArrayList<>();
private final String pkg;
private final int mask;
private final List<String> to = new ArrayList<>();
public Export(String pkg, int mask) {
Export(String pkg, int mask) {
this.pkg = pkg;
this.mask = mask;
}
}
private class Open {
private final String pkg;
private final int mask;
private final List<String> to = new ArrayList<>();
Open(String pkg, int mask) {
this.pkg = pkg;
this.mask = mask;
}
}
private class Requires {
private final String module;
private final int mask;
Requires(String module, int mask) {
this.module = module;
this.mask = mask;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Requires requires = (Requires) o;
return mask == requires.mask &&
Objects.equals(module, requires.module);
}
@Override
public int hashCode() {
return Objects.hash(module, mask);
}
}
protected class ModuleDescriptor {
private final String name;
//pair is name of module and flag(public,mandated,synthetic)
private final List<Pair<String, Integer>> requires = new ArrayList<>();
private final int flags;
private final List<Requires> requires = new ArrayList<>();
{
requires.add(new Pair<>("java.base", Module_attribute.ACC_MANDATED));
requires.add(new Requires("java.base", computeMask(RequiresFlag.MANDATED)));
}
private final Map<String, Export> exports = new HashMap<>();
private final Map<String, Open> opens = new HashMap<>();
//List of service and implementation
private final Map<String, List<String>> provides = new LinkedHashMap<>();
@ -227,22 +326,26 @@ public class ModuleTestBase {
private static final String LINE_END = ";\n";
StringBuilder content = new StringBuilder("module ");
StringBuilder content = new StringBuilder("");
public ModuleDescriptor(String moduleName) {
public ModuleDescriptor(String moduleName, ModuleFlag... flags) {
this.name = moduleName;
content.append(name).append('{').append('\n');
this.flags = computeMask(flags);
for (ModuleFlag flag : flags) {
content.append(flag.token).append(" ");
}
content.append("module ").append(moduleName).append('{').append('\n');
}
public ModuleDescriptor requires(String module) {
this.requires.add(Pair.of(module, 0));
this.requires.add(new Requires(module, 0));
content.append(" requires ").append(module).append(LINE_END);
return this;
}
public ModuleDescriptor requires(String module, RequiresFlag... flags) {
this.requires.add(new Pair<>(module, computeMask(flags)));
this.requires.add(new Requires(module, computeMask(flags)));
content.append(" requires ");
for (RequiresFlag flag : flags) {
@ -253,26 +356,52 @@ public class ModuleTestBase {
return this;
}
public ModuleDescriptor exports(String pkg, ExportFlag... flags) {
this.exports.putIfAbsent(pkg, new Export(pkg, computeMask(flags)));
public ModuleDescriptor exports(String pkg, ExportsFlag... flags) {
this.exports.put(toInternalForm(pkg), new Export(toInternalForm(pkg), computeMask(flags)));
content.append(" exports ");
for (ExportFlag flag : flags) {
for (ExportsFlag flag : flags) {
content.append(flag.token).append(" ");
}
content.append(pkg).append(LINE_END);
return this;
}
public ModuleDescriptor exportsTo(String pkg, String to, ExportFlag... flags) {
public ModuleDescriptor exportsTo(String pkg, String to, ExportsFlag... flags) {
List<String> tos = Pattern.compile(",")
.splitAsStream(to)
.map(String::trim)
.collect(Collectors.toList());
this.exports.computeIfAbsent(pkg, k -> new Export(pkg, computeMask(flags)))
this.exports.compute(toInternalForm(pkg), (k,v) -> new Export(k, computeMask(flags)))
.to.addAll(tos);
content.append(" exports ");
for (ExportFlag flag : flags) {
for (ExportsFlag flag : flags) {
content.append(flag.token).append(" ");
}
content.append(pkg).append(" to ").append(to).append(LINE_END);
return this;
}
public ModuleDescriptor opens(String pkg, OpensFlag... flags) {
this.opens.put(toInternalForm(pkg), new Open(toInternalForm(pkg), computeMask(flags)));
content.append(" opens ");
for (OpensFlag flag : flags) {
content.append(flag.token).append(" ");
}
content.append(pkg).append(LINE_END);
return this;
}
public ModuleDescriptor opensTo(String pkg, String to, OpensFlag... flags) {
List<String> tos = Pattern.compile(",")
.splitAsStream(to)
.map(String::trim)
.collect(Collectors.toList());
this.opens.compute(toInternalForm(pkg), (k,v) -> new Open(toInternalForm(k), computeMask(flags)))
.to.addAll(tos);
content.append(" opens ");
for (OpensFlag flag : flags) {
content.append(flag.token).append(" ");
}
content.append(pkg).append(" to ").append(to).append(LINE_END);
@ -280,7 +409,10 @@ public class ModuleTestBase {
}
public ModuleDescriptor provides(String provides, String... with) {
this.provides.put(provides, Arrays.asList(with));
List<String> impls = Arrays.stream(with)
.map(this::toInternalForm)
.collect(Collectors.toList());
this.provides.put(toInternalForm(provides), impls);
content.append(" provides ")
.append(provides)
.append(" with ")
@ -290,8 +422,8 @@ public class ModuleTestBase {
}
public ModuleDescriptor uses(String... uses) {
Collections.addAll(this.uses, uses);
for (String use : uses) {
this.uses.add(toInternalForm(use));
content.append(" uses ").append(use).append(LINE_END);
}
return this;
@ -305,7 +437,11 @@ public class ModuleTestBase {
return this;
}
private int computeMask(Mask[] masks) {
private String toInternalForm(String name) {
return name.replace('.', '/');
}
private int computeMask(Mask... masks) {
return Arrays.stream(masks)
.map(Mask::getMask)
.reduce((a, b) -> a | b)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2017, 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
@ -82,7 +82,8 @@ public class TestResult extends TestBase {
Set<?> copy = new HashSet<>(expected);
copy.removeAll(found);
if (!found.containsAll(expected)) {
return checkTrue(false, message + " FAIL : not found elements : " + copy);
return checkTrue(false, message + " FAIL : not found elements : " + copy + "\n" +
"Actual: " + found);
} else {
return checkTrue(true, message + " PASS : all elements found");
}

View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2016, 2017, 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.
*
* 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.
*/
/*
* @test
* @bug 8147414
* @summary java.nio.file.ClosedFileSystemException in javadoc
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* @build toolbox.JarTask toolbox.JavacTask toolbox.ToolBox
* @run main FileSystemClosedTest
*/
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.ClosedFileSystemException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import toolbox.ToolBox;
import toolbox.JarTask;
import toolbox.JavacTask;
public class FileSystemClosedTest {
public static void main(String... args) throws Exception {
new FileSystemClosedTest().run();
}
void run() throws Exception {
ToolBox tb = new ToolBox();
Path jar = createJar(tb);
Path src = Paths.get("src");
tb.writeJavaFiles(src, "class C { p1.C1 c1; }");
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
PrintWriter out = new PrintWriter(System.err, true);
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
List<String> options = Arrays.asList("-classpath", jar.toString());
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(src.resolve("C.java"));
com.sun.source.util.JavacTask task =
(com.sun.source.util.JavacTask) comp.getTask(out, fm, null, options, null, files);
task.parse();
Elements elems = task.getElements();
try {
// Use p1, p1.C1 as a control to verify normal behavior
PackageElement p1 = elems.getPackageElement("p1");
TypeElement p1C1 = elems.getTypeElement("p1.C1");
System.err.println("p1: " + p1 + "; p1C1: " + p1C1);
if (p1C1 == null) {
throw new Exception("p1.C1 not found");
}
// Now repeat for p2, p2.C2, closing the file manager early
PackageElement p2 = elems.getPackageElement("p2");
System.err.println("closing file manager");
fm.close();
TypeElement p2C2 = elems.getTypeElement("p2.C2");
System.err.println("p2: " + p2 + "; p2C2: " + p2C2);
if (p2C2 != null) {
throw new Exception("p1.C1 found unexpectedly");
}
} catch (ClosedFileSystemException e) {
throw new Exception("unexpected exception thrown", e);
}
}
private Path createJar(ToolBox tb) throws IOException {
Path jarSrc = Paths.get("jarSrc");
Path jarClasses = Paths.get("jarClasses");
Path jar = Paths.get("jar.jar");
Files.createDirectories(jarClasses);
tb.writeJavaFiles(jarSrc,
"package p1; public class C1 { }",
"package p2; public class C2 { }");
new JavacTask(tb)
.outdir(jarClasses)
.files(tb.findJavaFiles(jarSrc))
.run()
.writeAll();
new JarTask(tb)
.run("cf", jar.toString(), "-C", jarClasses.toString(), "p1", "p2");
return jar;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2017, 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
@ -66,6 +66,7 @@ class Example implements Comparable<Example> {
modulePathFiles = new ArrayList<File>();
classPathFiles = new ArrayList<File>();
additionalFiles = new ArrayList<File>();
nonEmptySrcFiles = new ArrayList<File>();
findFiles(file, srcFiles);
for (File f: srcFiles) {
@ -99,11 +100,11 @@ class Example implements Comparable<Example> {
}
}
} else if (f.isFile()) {
if (f.getName().endsWith(".java")) {
files.add(f);
} else if (f.getName().equals("modulesourcepath")) {
moduleSourcePathDir = f;
}
if (f.getName().endsWith(".java")) {
files.add(f);
} else if (f.getName().equals("modulesourcepath")) {
moduleSourcePathDir = f;
}
}
}
@ -132,8 +133,10 @@ class Example implements Comparable<Example> {
foundInfo(f);
runOpts = Arrays.asList(runMatch.group(1).trim().split(" +"));
}
if (javaPat.matcher(line).matches())
if (javaPat.matcher(line).matches()) {
nonEmptySrcFiles.add(f);
break;
}
}
} catch (IOException e) {
throw new Error(e);
@ -236,6 +239,7 @@ class Example implements Comparable<Example> {
// source for import statements or a magic comment
for (File pf: procFiles) {
if (pf.getName().equals("CreateBadClassFile.java")) {
pOpts.add("--add-modules=jdk.jdeps");
pOpts.add("--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED");
}
}
@ -263,7 +267,9 @@ class Example implements Comparable<Example> {
if (moduleSourcePathDir != null) {
opts.add("--module-source-path");
opts.add(moduleSourcePathDir.getPath());
files = moduleSourcePathFiles;
files = new ArrayList<>();
files.addAll(moduleSourcePathFiles);
files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
}
if (additionalFiles.size() > 0) {
@ -343,6 +349,7 @@ class Example implements Comparable<Example> {
List<File> modulePathFiles;
List<File> classPathFiles;
List<File> additionalFiles;
List<File> nonEmptySrcFiles;
File infoFile;
private List<String> runOpts;
private List<String> options;

View File

@ -103,6 +103,7 @@ compiler.warn.annotation.method.not.found.reason # ClassReader
compiler.warn.big.major.version # ClassReader
compiler.warn.future.attr # ClassReader
compiler.warn.illegal.char.for.encoding
compiler.warn.incubating.modules # requires adjusted classfile
compiler.warn.invalid.archive.file
compiler.warn.override.bridge
compiler.warn.position.overflow # CRTable: caused by files with long lines >= 1024 chars

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, 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
@ -24,5 +24,3 @@
// key: compiler.warn.dir.path.element.not.directory
// options: -Xlint:path
// run: simple
class DirPathElementNotDirectory { }

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
// key: compiler.err.module.not.found.on.module.source.path

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
module m { }

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2016, 2017, 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.
*
* 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.
*/
// key: compiler.err.not.in.module.on.module.source.path
package p; class C { }

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
module m { }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, 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
@ -22,5 +22,3 @@
*/
// key: compiler.err.unnamed.pkg.not.allowed.named.modules
class UnnamedPackageInNamedModule {}

Some files were not shown because too many files have changed in this diff Show More