--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/AnnotationValueVisitor.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/AnnotationValueVisitor.java Fri Jan 20 19:10:00 2017 +0000
@@ -68,8 +68,8 @@
* 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 @@
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.
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementVisitor.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementVisitor.java Fri Jan 20 19:10:00 2017 +0000
@@ -59,8 +59,8 @@
* 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 @@
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 @@
/**
* 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);
+ }
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeVisitor.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeVisitor.java Fri Jan 20 19:10:00 2017 +0000
@@ -59,8 +59,8 @@
* 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 @@
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.
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java Fri Jan 20 19:10:00 2017 +0000
@@ -65,17 +65,17 @@
* @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() {}
/**
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java Fri Jan 20 19:10:00 2017 +0000
@@ -59,13 +59,13 @@
* @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();
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java Fri Jan 20 19:10:00 2017 +0000
@@ -67,15 +67,15 @@
* @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 @@
*/
@Override
public R visitModule(ModuleElement e, P p) {
- return visitUnknown(e, p);
+ // Use implementation from interface default method
+ return ElementVisitor.super.visitModule(e, p);
}
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor7.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor7.java Fri Jan 20 19:10:00 2017 +0000
@@ -63,12 +63,12 @@
* @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();
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Fri Jan 20 19:10:00 2017 +0000
@@ -66,15 +66,15 @@
* @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() {}
/**
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java Fri Jan 20 19:10:00 2017 +0000
@@ -63,12 +63,12 @@
* @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();
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java Fri Jan 20 19:10:00 2017 +0000
@@ -81,17 +81,17 @@
* @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 @@
* 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);
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor7.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor7.java Fri Jan 20 19:10:00 2017 +0000
@@ -76,13 +76,13 @@
* @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 @@
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
*/
+ @SuppressWarnings("deprecation") // Superclass constructor deprecated
protected ElementKindVisitor7(R defaultValue) {
super(defaultValue);
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java Fri Jan 20 19:10:00 2017 +0000
@@ -92,10 +92,7 @@
* @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 @@
/**
* 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 @@
* 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;
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner7.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner7.java Fri Jan 20 19:10:00 2017 +0000
@@ -89,13 +89,13 @@
* @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 @@
*
* @param defaultValue the default value
*/
+ @SuppressWarnings("deprecation") // Superclass constructor deprecated
protected ElementScanner7(R defaultValue){
super(defaultValue);
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java Fri Jan 20 19:10:00 2017 +0000
@@ -74,10 +74,7 @@
* @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 @@
/**
* 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 @@
* 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;
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java Fri Jan 20 19:10:00 2017 +0000
@@ -66,13 +66,13 @@
* @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 @@
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
*/
+ @SuppressWarnings("deprecation") // Superclass constructor deprecated
protected SimpleAnnotationValueVisitor7(R defaultValue) {
super(defaultValue);
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java Fri Jan 20 19:10:00 2017 +0000
@@ -78,10 +78,7 @@
* @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 @@
/**
* 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 @@
* 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;
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor7.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor7.java Fri Jan 20 19:10:00 2017 +0000
@@ -72,13 +72,13 @@
* @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 @@
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
*/
+ @SuppressWarnings("deprecation") // Superclass constructor deprecated
protected SimpleElementVisitor7(R defaultValue){
super(defaultValue);
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java Fri Jan 20 19:10:00 2017 +0000
@@ -78,10 +78,7 @@
* @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 @@
/**
* 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 @@
* 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;
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java Fri Jan 20 19:10:00 2017 +0000
@@ -72,13 +72,13 @@
* @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 @@
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
*/
+ @SuppressWarnings("deprecation") // Superclass constructor deprecated
protected SimpleTypeVisitor7(R defaultValue){
super(defaultValue);
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java Fri Jan 20 19:10:00 2017 +0000
@@ -76,16 +76,16 @@
* @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 @@
* 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);
}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor7.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor7.java Fri Jan 20 19:10:00 2017 +0000
@@ -73,13 +73,13 @@
* @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 @@
*
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
*/
+ @SuppressWarnings("deprecation") // Superclass constructor deprecated
protected TypeKindVisitor7(R defaultValue) {
super(defaultValue);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreePath.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreePath.java Fri Jan 20 19:10:00 2017 +0000
@@ -98,7 +98,7 @@
* @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;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 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 @@
/**
* 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 <body> 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
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java Fri Jan 20 19:10:00 2017 +0000
@@ -423,7 +423,16 @@
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 @@
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 @@
}
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) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
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)),
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Fri Jan 20 19:10:00 2017 +0000
@@ -174,7 +174,6 @@
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 @@
}
protected JavacTrees(Context context) {
- javaFileObjectToPackageMap = new HashMap<>();
this.breakIterator = null;
context.put(JavacTrees.class, this);
init(context);
@@ -1039,10 +1037,11 @@
}
@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 @@
}
}
- /**
- * 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 @@
}
};
- PackageSymbol psym = javaFileObjectToPackageMap.getOrDefault(jfo,
- syms.unnamedModule.unnamedPackage);
-
jcCompilationUnit.docComments = new DocCommentTable() {
@Override
public boolean hasComment(JCTree tree) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
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 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);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 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();
+ }
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Fri Jan 20 19:10:00 2017 +0000
@@ -118,6 +118,8 @@
Source source = Source.instance(context);
allowRepeatedAnnos = source.allowRepeatedAnnotations();
sourceName = source.name;
+
+ blockCount = 1;
}
/** Semaphore to delay annotation processing */
@@ -144,6 +146,10 @@
/** 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 void newRound() {
+ blockCount = 1;
+ }
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Fri Jan 20 19:10:00 2017 +0000
@@ -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.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.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 @@
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 @@
} 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 @@
}
}
+ /**
+ * 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 @@
fileManager.getLocationForModule(sourceOutput,
fo, (pkgName == null) ? null : pkgName.toString());
}
-
return loc;
}
@@ -962,7 +978,7 @@
@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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
} 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;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jan 20 19:10:00 2017 +0000
@@ -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.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.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.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 @@
* @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 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);
-
- if (existing != null) {
- return new InvisibleSymbolError(env, true, existing);
- }
-
- return lookupInvisibleSymbol(env, name, syms::getClass, (ms, n) -> {
+ private final RecoveryLoadClass noRecovery = (env, name) -> null;
+
+ 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 @@
.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 @@
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 @@
* @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 @@
}
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 @@
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 @@
JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
- if (pos.getTree() != null && pos.getTree().hasTag(SELECT) && sym.owner.kind == PCK) {
- pos = ((JCFieldAccess) pos.getTree()).selected.pos();
-
- return diags.create(dkind, log.currentSource(),
- pos, "package.not.visible", sym.packge(), details);
+ if (pos.getTree() != null) {
+ Symbol o = sym;
+ JCTree tree = pos.getTree();
+
+ 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(),
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
@Override
Location getLocationForModule(Path dir) {
- return pathLocations.get(dir);
+ return (pathLocations == null) ? null : pathLocations.get(dir);
}
private boolean listed;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Jan 20 19:10:00 2017 +0000
@@ -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.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 @@
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 {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Fri Jan 20 19:10:00 2017 +0000
@@ -588,7 +588,9 @@
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)) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
**/
protected boolean implicitSourceFilesRead;
- protected boolean enterDone;
+ private boolean enterDone;
protected CompileStates compileStates;
@@ -1042,7 +1042,7 @@
public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
modules.initModules(roots);
if (roots.isEmpty()) {
- enterDone = true;
+ enterDone();
}
return roots;
}
@@ -1063,7 +1063,7 @@
enter.main(roots);
- enterDone = true;
+ enterDone();
if (!taskListener.isEmpty()) {
for (JCCompilationUnit unit: roots) {
@@ -1725,6 +1725,11 @@
}
}
+ public void enterDone() {
+ enterDone = true;
+ annotate.enterDone();
+ }
+
public boolean isEnterDone() {
return enterDone;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Fri Jan 20 19:10:00 2017 +0000
@@ -184,39 +184,34 @@
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;
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Fri Jan 20 19:10:00 2017 +0000
@@ -30,7 +30,6 @@
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;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri Jan 20 19:10:00 2017 +0000
@@ -588,7 +588,7 @@
/**
* Ident = IDENTIFIER
*/
- protected Name ident() {
+ public Name ident() {
return ident(false);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 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 @@
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 @@
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 @@
compiler.newRound();
modules.newRound();
types.newRound();
+ annotate.newRound();
boolean foundError = false;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Jan 20 19:10:00 2017 +0000
@@ -1535,6 +1535,10 @@
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.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}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Convert.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Convert.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
}
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();
+ }
}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Fri Jan 20 19:10:00 2017 +0000
@@ -40,6 +40,7 @@
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;
/**
@@ -189,6 +190,11 @@
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.
*/
public final MessageRetriever standardmessage;
@@ -309,8 +315,11 @@
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 @@
}
}
}
+
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 @@
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 @@
}
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;
+ }
}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java Fri Jan 20 19:10:00 2017 +0000
@@ -237,6 +237,8 @@
}
} catch (IOException e) {
throw new DocletAbortException(e);
+ } catch (FatalError fe) {
+ throw fe;
} catch (DocletAbortException de) {
de.printStackTrace();
throw de;
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Fri Jan 20 19:10:00 2017 +0000
@@ -148,7 +148,9 @@
public final Content descfrmInterfaceLabel;
- private final Writer writer;
+ private final DocFile file;
+
+ private Writer writer;
protected Content script;
@@ -164,7 +166,7 @@
*/
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 void write(Content c) throws IOException {
+ writer = file.openWriter();
c.write(writer, true);
}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java Fri Jan 20 19:10:00 2017 +0000
@@ -90,6 +90,8 @@
} catch (Configuration.Fault f) {
root.printError(f.getMessage());
return false;
+ } catch (FatalError fe) {
+ return false;
} catch (DocletAbortException e) {
e.printStackTrace();
Throwable cause = e.getCause();
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java Fri Jan 20 19:10:00 2017 +0000
@@ -145,7 +145,14 @@
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 " +
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Fri Jan 20 19:10:00 2017 +0000
@@ -29,6 +29,8 @@
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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/util/FatalError.java Fri Jan 20 19:10:00 2017 +0000
@@ -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() { }
+}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocEnv.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocEnv.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
final Enter enter;
/** The name table. */
- private Names names;
+ private final Names names;
/** The encoding name. */
private String encoding;
@@ -120,6 +120,7 @@
JavaFileManager fileManager;
Context context;
DocLint doclint;
+ JavaScriptScanner javaScriptScanner;
WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
@@ -858,6 +859,15 @@
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);
}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocImpl.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocImpl.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 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 @@
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())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavaScriptScanner.java Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,1103 @@
+/*
+ * Copyright (c) 2012,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.javadoc.main;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import com.sun.tools.javadoc.main.JavaScriptScanner.TagParser.Kind;
+
+import static com.sun.tools.javac.util.LayoutCharacters.EOI;
+
+/**
+ * Parser to detect use of JavaScript in documentation comments.
+ */
+@Deprecated
+public class JavaScriptScanner {
+ public static interface Reporter {
+ void report();
+ }
+
+ static class ParseException extends Exception {
+ private static final long serialVersionUID = 0;
+ ParseException(String key) {
+ super(key);
+ }
+ }
+
+ private Reporter reporter;
+
+ /** The input buffer, index of most recent character read,
+ * index of one past last character in buffer.
+ */
+ protected char[] buf;
+ protected int bp;
+ protected int buflen;
+
+ /** The current character.
+ */
+ protected char ch;
+
+ private boolean newline = true;
+
+ Map<String, TagParser> tagParsers;
+ Set<String> eventAttrs;
+ Set<String> uriAttrs;
+
+ public JavaScriptScanner() {
+ initTagParsers();
+ initEventAttrs();
+ initURIAttrs();
+ }
+
+ public void parse(String comment, Reporter r) {
+ reporter = r;
+ String c = comment;
+ buf = new char[c.length() + 1];
+ c.getChars(0, c.length(), buf, 0);
+ buf[buf.length - 1] = EOI;
+ buflen = buf.length - 1;
+ bp = -1;
+ newline = true;
+ nextChar();
+
+ blockContent();
+ blockTags();
+ }
+
+ private void checkHtmlTag(String tag) {
+ if (tag.equalsIgnoreCase("script")) {
+ reporter.report();
+ }
+ }
+
+ private void checkHtmlAttr(String name, String value) {
+ String n = name.toLowerCase(Locale.ENGLISH);
+ if (eventAttrs.contains(n)
+ || uriAttrs.contains(n)
+ && value != null && value.toLowerCase(Locale.ENGLISH).trim().startsWith("javascript:")) {
+ reporter.report();
+ }
+ }
+
+ void nextChar() {
+ ch = buf[bp < buflen ? ++bp : buflen];
+ switch (ch) {
+ case '\f': case '\n': case '\r':
+ newline = true;
+ }
+ }
+
+ /**
+ * Read block content, consisting of text, html and inline tags.
+ * Terminated by the end of input, or the beginning of the next block tag:
+ * i.e. @ as the first non-whitespace character on a line.
+ */
+ @SuppressWarnings("fallthrough")
+ protected void blockContent() {
+
+ loop:
+ while (bp < buflen) {
+ switch (ch) {
+ case '\n': case '\r': case '\f':
+ newline = true;
+ // fallthrough
+
+ case ' ': case '\t':
+ nextChar();
+ break;
+
+ case '&':
+ entity(null);
+ break;
+
+ case '<':
+ html();
+ break;
+
+ case '>':
+ newline = false;
+ nextChar();
+ break;
+
+ case '{':
+ inlineTag(null);
+ break;
+
+ case '@':
+ if (newline) {
+ break loop;
+ }
+ // fallthrough
+
+ default:
+ newline = false;
+ nextChar();
+ }
+ }
+ }
+
+ /**
+ * Read a series of block tags, including their content.
+ * Standard tags parse their content appropriately.
+ * Non-standard tags are represented by {@link UnknownBlockTag}.
+ */
+ protected void blockTags() {
+ while (ch == '@')
+ blockTag();
+ }
+
+ /**
+ * Read a single block tag, including its content.
+ * Standard tags parse their content appropriately.
+ * Non-standard tags are represented by {@link UnknownBlockTag}.
+ */
+ protected void blockTag() {
+ int p = bp;
+ try {
+ nextChar();
+ if (isIdentifierStart(ch)) {
+ String name = readTagName();
+ TagParser tp = tagParsers.get(name);
+ if (tp == null) {
+ blockContent();
+ } else {
+ switch (tp.getKind()) {
+ case BLOCK:
+ tp.parse(p);
+ return;
+ case INLINE:
+ return;
+ }
+ }
+ }
+ blockContent();
+ } catch (ParseException e) {
+ blockContent();
+ }
+ }
+
+ protected void inlineTag(Void list) {
+ newline = false;
+ nextChar();
+ if (ch == '@') {
+ inlineTag();
+ }
+ }
+
+ /**
+ * Read a single inline tag, including its content.
+ * Standard tags parse their content appropriately.
+ * Non-standard tags are represented by {@link UnknownBlockTag}.
+ * Malformed tags may be returned as {@link Erroneous}.
+ */
+ protected void inlineTag() {
+ int p = bp - 1;
+ try {
+ nextChar();
+ if (isIdentifierStart(ch)) {
+ String name = readTagName();
+ TagParser tp = tagParsers.get(name);
+
+ if (tp == null) {
+ skipWhitespace();
+ inlineText(WhitespaceRetentionPolicy.REMOVE_ALL);
+ nextChar();
+ } else {
+ skipWhitespace();
+ if (tp.getKind() == TagParser.Kind.INLINE) {
+ tp.parse(p);
+ } else { // handle block tags (ex: @see) in inline content
+ inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip content
+ nextChar();
+ }
+ }
+ }
+ } catch (ParseException e) {
+ }
+ }
+
+ private static enum WhitespaceRetentionPolicy {
+ RETAIN_ALL,
+ REMOVE_FIRST_SPACE,
+ REMOVE_ALL
+ }
+
+ /**
+ * Read plain text content of an inline tag.
+ * Matching pairs of { } are skipped; the text is terminated by the first
+ * unmatched }. It is an error if the beginning of the next tag is detected.
+ */
+ private void inlineText(WhitespaceRetentionPolicy whitespacePolicy) throws ParseException {
+ switch (whitespacePolicy) {
+ case REMOVE_ALL:
+ skipWhitespace();
+ break;
+ case REMOVE_FIRST_SPACE:
+ if (ch == ' ')
+ nextChar();
+ break;
+ case RETAIN_ALL:
+ default:
+ // do nothing
+ break;
+
+ }
+ int pos = bp;
+ int depth = 1;
+
+ loop:
+ while (bp < buflen) {
+ switch (ch) {
+ case '\n': case '\r': case '\f':
+ newline = true;
+ break;
+
+ case ' ': case '\t':
+ break;
+
+ case '{':
+ newline = false;
+ depth++;
+ break;
+
+ case '}':
+ if (--depth == 0) {
+ return;
+ }
+ newline = false;
+ break;
+
+ case '@':
+ if (newline)
+ break loop;
+ newline = false;
+ break;
+
+ default:
+ newline = false;
+ break;
+ }
+ nextChar();
+ }
+ throw new ParseException("dc.unterminated.inline.tag");
+ }
+
+ /**
+ * Read Java class name, possibly followed by member
+ * Matching pairs of {@literal < >} are skipped. The text is terminated by the first
+ * unmatched }. It is an error if the beginning of the next tag is detected.
+ */
+ // TODO: boolean allowMember should be enum FORBID, ALLOW, REQUIRE
+ // TODO: improve quality of parse to forbid bad constructions.
+ // TODO: update to use ReferenceParser
+ @SuppressWarnings("fallthrough")
+ protected void reference(boolean allowMember) throws ParseException {
+ int pos = bp;
+ int depth = 0;
+
+ // scan to find the end of the signature, by looking for the first
+ // whitespace not enclosed in () or <>, or the end of the tag
+ loop:
+ while (bp < buflen) {
+ switch (ch) {
+ case '\n': case '\r': case '\f':
+ newline = true;
+ // fallthrough
+
+ case ' ': case '\t':
+ if (depth == 0)
+ break loop;
+ break;
+
+ case '(':
+ case '<':
+ newline = false;
+ depth++;
+ break;
+
+ case ')':
+ case '>':
+ newline = false;
+ --depth;
+ break;
+
+ case '}':
+ if (bp == pos)
+ return;
+ newline = false;
+ break loop;
+
+ case '@':
+ if (newline)
+ break loop;
+ // fallthrough
+
+ default:
+ newline = false;
+
+ }
+ nextChar();
+ }
+
+ if (depth != 0)
+ throw new ParseException("dc.unterminated.signature");
+ }
+
+ /**
+ * Read Java identifier
+ * Matching pairs of { } are skipped; the text is terminated by the first
+ * unmatched }. It is an error if the beginning of the next tag is detected.
+ */
+ @SuppressWarnings("fallthrough")
+ protected void identifier() throws ParseException {
+ skipWhitespace();
+ int pos = bp;
+
+ if (isJavaIdentifierStart(ch)) {
+ readJavaIdentifier();
+ return;
+ }
+
+ throw new ParseException("dc.identifier.expected");
+ }
+
+ /**
+ * Read a quoted string.
+ * It is an error if the beginning of the next tag is detected.
+ */
+ @SuppressWarnings("fallthrough")
+ protected void quotedString() {
+ int pos = bp;
+ nextChar();
+
+ loop:
+ while (bp < buflen) {
+ switch (ch) {
+ case '\n': case '\r': case '\f':
+ newline = true;
+ break;
+
+ case ' ': case '\t':
+ break;
+
+ case '"':
+ nextChar();
+ // trim trailing white-space?
+ return;
+
+ case '@':
+ if (newline)
+ break loop;
+
+ }
+ nextChar();
+ }
+ }
+
+ /**
+ * Read a term ie. one word.
+ * It is an error if the beginning of the next tag is detected.
+ */
+ @SuppressWarnings("fallthrough")
+ protected void inlineWord() {
+ int pos = bp;
+ int depth = 0;
+ loop:
+ while (bp < buflen) {
+ switch (ch) {
+ case '\n':
+ newline = true;
+ // fallthrough
+
+ case '\r': case '\f': case ' ': case '\t':
+ return;
+
+ case '@':
+ if (newline)
+ break loop;
+
+ case '{':
+ depth++;
+ break;
+
+ case '}':
+ if (depth == 0 || --depth == 0)
+ return;
+ break;
+ }
+ newline = false;
+ nextChar();
+ }
+ }
+
+ /**
+ * Read general text content of an inline tag, including HTML entities and elements.
+ * Matching pairs of { } are skipped; the text is terminated by the first
+ * unmatched }. It is an error if the beginning of the next tag is detected.
+ */
+ @SuppressWarnings("fallthrough")
+ private void inlineContent() {
+
+ skipWhitespace();
+ int pos = bp;
+ int depth = 1;
+
+ loop:
+ while (bp < buflen) {
+
+ switch (ch) {
+ case '\n': case '\r': case '\f':
+ newline = true;
+ // fall through
+
+ case ' ': case '\t':
+ nextChar();
+ break;
+
+ case '&':
+ entity(null);
+ break;
+
+ case '<':
+ newline = false;
+ html();
+ break;
+
+ case '{':
+ newline = false;
+ depth++;
+ nextChar();
+ break;
+
+ case '}':
+ newline = false;
+ if (--depth == 0) {
+ nextChar();
+ return;
+ }
+ nextChar();
+ break;
+
+ case '@':
+ if (newline)
+ break loop;
+ // fallthrough
+
+ default:
+ nextChar();
+ break;
+ }
+ }
+
+ }
+
+ protected void entity(Void list) {
+ newline = false;
+ entity();
+ }
+
+ /**
+ * Read an HTML entity.
+ * {@literal &identifier; } or {@literal &#digits; } or {@literal &#xhex-digits; }
+ */
+ protected void entity() {
+ nextChar();
+ String name = null;
+ if (ch == '#') {
+ int namep = bp;
+ nextChar();
+ if (isDecimalDigit(ch)) {
+ nextChar();
+ while (isDecimalDigit(ch))
+ nextChar();
+ name = new String(buf, namep, bp - namep);
+ } else if (ch == 'x' || ch == 'X') {
+ nextChar();
+ if (isHexDigit(ch)) {
+ nextChar();
+ while (isHexDigit(ch))
+ nextChar();
+ name = new String(buf, namep, bp - namep);
+ }
+ }
+ } else if (isIdentifierStart(ch)) {
+ name = readIdentifier();
+ }
+
+ if (name != null) {
+ if (ch != ';')
+ return;
+ nextChar();
+ }
+ }
+
+ /**
+ * Read the start or end of an HTML tag, or an HTML comment
+ * {@literal <identifier attrs> } or {@literal </identifier> }
+ */
+ protected void html() {
+ int p = bp;
+ nextChar();
+ if (isIdentifierStart(ch)) {
+ String name = readIdentifier();
+ checkHtmlTag(name);
+ htmlAttrs();
+ if (ch == '/') {
+ nextChar();
+ }
+ if (ch == '>') {
+ nextChar();
+ return;
+ }
+ } else if (ch == '/') {
+ nextChar();
+ if (isIdentifierStart(ch)) {
+ readIdentifier();
+ skipWhitespace();
+ if (ch == '>') {
+ nextChar();
+ return;
+ }
+ }
+ } else if (ch == '!') {
+ nextChar();
+ if (ch == '-') {
+ nextChar();
+ if (ch == '-') {
+ nextChar();
+ while (bp < buflen) {
+ int dash = 0;
+ while (ch == '-') {
+ dash++;
+ nextChar();
+ }
+ // Strictly speaking, a comment should not contain "--"
+ // so dash > 2 is an error, dash == 2 implies ch == '>'
+ // See http://www.w3.org/TR/html-markup/syntax.html#syntax-comments
+ // for more details.
+ if (dash >= 2 && ch == '>') {
+ nextChar();
+ return;
+ }
+
+ nextChar();
+ }
+ }
+ }
+ }
+
+ bp = p + 1;
+ ch = buf[bp];
+ }
+
+ /**
+ * Read a series of HTML attributes, terminated by {@literal > }.
+ * Each attribute is of the form {@literal identifier[=value] }.
+ * "value" may be unquoted, single-quoted, or double-quoted.
+ */
+ protected void htmlAttrs() {
+ skipWhitespace();
+
+ loop:
+ while (isIdentifierStart(ch)) {
+ int namePos = bp;
+ String name = readAttributeName();
+ skipWhitespace();
+ StringBuilder value = new StringBuilder();
+ if (ch == '=') {
+ nextChar();
+ skipWhitespace();
+ if (ch == '\'' || ch == '"') {
+ char quote = ch;
+ nextChar();
+ while (bp < buflen && ch != quote) {
+ if (newline && ch == '@') {
+ // No point trying to read more.
+ // In fact, all attrs get discarded by the caller
+ // and superseded by a malformed.html node because
+ // the html tag itself is not terminated correctly.
+ break loop;
+ }
+ value.append(ch);
+ nextChar();
+ }
+ nextChar();
+ } else {
+ while (bp < buflen && !isUnquotedAttrValueTerminator(ch)) {
+ value.append(ch);
+ nextChar();
+ }
+ }
+ skipWhitespace();
+ }
+ checkHtmlAttr(name, value.toString());
+ }
+ }
+
+ protected void attrValueChar(Void list) {
+ switch (ch) {
+ case '&':
+ entity(list);
+ break;
+
+ case '{':
+ inlineTag(list);
+ break;
+
+ default:
+ nextChar();
+ }
+ }
+
+ protected boolean isIdentifierStart(char ch) {
+ return Character.isUnicodeIdentifierStart(ch);
+ }
+
+ protected String readIdentifier() {
+ int start = bp;
+ nextChar();
+ while (bp < buflen && Character.isUnicodeIdentifierPart(ch))
+ nextChar();
+ return new String(buf, start, bp - start);
+ }
+
+ protected String readAttributeName() {
+ int start = bp;
+ nextChar();
+ while (bp < buflen && (Character.isUnicodeIdentifierPart(ch) || ch == '-'))
+ nextChar();
+ return new String(buf, start, bp - start);
+ }
+
+ protected String readTagName() {
+ int start = bp;
+ nextChar();
+ while (bp < buflen
+ && (Character.isUnicodeIdentifierPart(ch) || ch == '.'
+ || ch == '-' || ch == ':')) {
+ nextChar();
+ }
+ return new String(buf, start, bp - start);
+ }
+
+ protected boolean isJavaIdentifierStart(char ch) {
+ return Character.isJavaIdentifierStart(ch);
+ }
+
+ protected String readJavaIdentifier() {
+ int start = bp;
+ nextChar();
+ while (bp < buflen && Character.isJavaIdentifierPart(ch))
+ nextChar();
+ return new String(buf, start, bp - start);
+ }
+
+ protected boolean isDecimalDigit(char ch) {
+ return ('0' <= ch && ch <= '9');
+ }
+
+ protected boolean isHexDigit(char ch) {
+ return ('0' <= ch && ch <= '9')
+ || ('a' <= ch && ch <= 'f')
+ || ('A' <= ch && ch <= 'F');
+ }
+
+ protected boolean isUnquotedAttrValueTerminator(char ch) {
+ switch (ch) {
+ case '\f': case '\n': case '\r': case '\t':
+ case ' ':
+ case '"': case '\'': case '`':
+ case '=': case '<': case '>':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ protected boolean isWhitespace(char ch) {
+ return Character.isWhitespace(ch);
+ }
+
+ protected void skipWhitespace() {
+ while (isWhitespace(ch)) {
+ nextChar();
+ }
+ }
+
+ /**
+ * @param start position of first character of string
+ * @param end position of character beyond last character to be included
+ */
+ String newString(int start, int end) {
+ return new String(buf, start, end - start);
+ }
+
+ static abstract class TagParser {
+ enum Kind { INLINE, BLOCK }
+
+ final Kind kind;
+ final String name;
+
+
+ TagParser(Kind k, String tk) {
+ kind = k;
+ name = tk;
+ }
+
+ TagParser(Kind k, String tk, boolean retainWhiteSpace) {
+ this(k, tk);
+ }
+
+ Kind getKind() {
+ return kind;
+ }
+
+ String getName() {
+ return name;
+ }
+
+ abstract void parse(int pos) throws ParseException;
+ }
+
+ /**
+ * @see <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javadoc.html#javadoctags">Javadoc Tags</a>
+ */
+ @SuppressWarnings("deprecation")
+ private void initTagParsers() {
+ TagParser[] parsers = {
+ // @author name-text
+ new TagParser(Kind.BLOCK, "author") {
+ @Override
+ public void parse(int pos) {
+ blockContent();
+ }
+ },
+
+ // {@code text}
+ new TagParser(Kind.INLINE, "code", true) {
+ @Override
+ public void parse(int pos) throws ParseException {
+ inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
+ nextChar();
+ }
+ },
+
+ // @deprecated deprecated-text
+ new TagParser(Kind.BLOCK, "deprecated") {
+ @Override
+ public void parse(int pos) {
+ blockContent();
+ }
+ },
+
+ // {@docRoot}
+ new TagParser(Kind.INLINE, "docRoot") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ if (ch == '}') {
+ nextChar();
+ return;
+ }
+ inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content
+ nextChar();
+ throw new ParseException("dc.unexpected.content");
+ }
+ },
+
+ // @exception class-name description
+ new TagParser(Kind.BLOCK, "exception") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ skipWhitespace();
+ reference(false);
+ blockContent();
+ }
+ },
+
+ // @hidden hidden-text
+ new TagParser(Kind.BLOCK, "hidden") {
+ @Override
+ public void parse(int pos) {
+ blockContent();
+ }
+ },
+
+ // @index search-term options-description
+ new TagParser(Kind.INLINE, "index") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ skipWhitespace();
+ if (ch == '}') {
+ throw new ParseException("dc.no.content");
+ }
+ if (ch == '"') quotedString(); else inlineWord();
+ skipWhitespace();
+ if (ch != '}') {
+ inlineContent();
+ } else {
+ nextChar();
+ }
+ }
+ },
+
+ // {@inheritDoc}
+ new TagParser(Kind.INLINE, "inheritDoc") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ if (ch == '}') {
+ nextChar();
+ return;
+ }
+ inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content
+ nextChar();
+ throw new ParseException("dc.unexpected.content");
+ }
+ },
+
+ // {@link package.class#member label}
+ new TagParser(Kind.INLINE, "link") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ reference(true);
+ inlineContent();
+ }
+ },
+
+ // {@linkplain package.class#member label}
+ new TagParser(Kind.INLINE, "linkplain") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ reference(true);
+ inlineContent();
+ }
+ },
+
+ // {@literal text}
+ new TagParser(Kind.INLINE, "literal", true) {
+ @Override
+ public void parse(int pos) throws ParseException {
+ inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
+ nextChar();
+ }
+ },
+
+ // @param parameter-name description
+ new TagParser(Kind.BLOCK, "param") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ skipWhitespace();
+
+ boolean typaram = false;
+ if (ch == '<') {
+ typaram = true;
+ nextChar();
+ }
+
+ identifier();
+
+ if (typaram) {
+ if (ch != '>')
+ throw new ParseException("dc.gt.expected");
+ nextChar();
+ }
+
+ skipWhitespace();
+ blockContent();
+ }
+ },
+
+ // @return description
+ new TagParser(Kind.BLOCK, "return") {
+ @Override
+ public void parse(int pos) {
+ blockContent();
+ }
+ },
+
+ // @see reference | quoted-string | HTML
+ new TagParser(Kind.BLOCK, "see") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ skipWhitespace();
+ switch (ch) {
+ case '"':
+ quotedString();
+ skipWhitespace();
+ if (ch == '@'
+ || ch == EOI && bp == buf.length - 1) {
+ return;
+ }
+ break;
+
+ case '<':
+ blockContent();
+ return;
+
+ case '@':
+ if (newline)
+ throw new ParseException("dc.no.content");
+ break;
+
+ case EOI:
+ if (bp == buf.length - 1)
+ throw new ParseException("dc.no.content");
+ break;
+
+ default:
+ if (isJavaIdentifierStart(ch) || ch == '#') {
+ reference(true);
+ blockContent();
+ }
+ }
+ throw new ParseException("dc.unexpected.content");
+ }
+ },
+
+ // @serialData data-description
+ new TagParser(Kind.BLOCK, "@serialData") {
+ @Override
+ public void parse(int pos) {
+ blockContent();
+ }
+ },
+
+ // @serialField field-name field-type description
+ new TagParser(Kind.BLOCK, "serialField") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ skipWhitespace();
+ identifier();
+ skipWhitespace();
+ reference(false);
+ if (isWhitespace(ch)) {
+ skipWhitespace();
+ blockContent();
+ }
+ }
+ },
+
+ // @serial field-description | include | exclude
+ new TagParser(Kind.BLOCK, "serial") {
+ @Override
+ public void parse(int pos) {
+ blockContent();
+ }
+ },
+
+ // @since since-text
+ new TagParser(Kind.BLOCK, "since") {
+ @Override
+ public void parse(int pos) {
+ blockContent();
+ }
+ },
+
+ // @throws class-name description
+ new TagParser(Kind.BLOCK, "throws") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ skipWhitespace();
+ reference(false);
+ blockContent();
+ }
+ },
+
+ // {@value package.class#field}
+ new TagParser(Kind.INLINE, "value") {
+ @Override
+ public void parse(int pos) throws ParseException {
+ reference(true);
+ skipWhitespace();
+ if (ch == '}') {
+ nextChar();
+ return;
+ }
+ nextChar();
+ throw new ParseException("dc.unexpected.content");
+ }
+ },
+
+ // @version version-text
+ new TagParser(Kind.BLOCK, "version") {
+ @Override
+ public void parse(int pos) {
+ blockContent();
+ }
+ },
+ };
+
+ tagParsers = new HashMap<>();
+ for (TagParser p: parsers)
+ tagParsers.put(p.getName(), p);
+
+ }
+
+ private void initEventAttrs() {
+ eventAttrs = new HashSet<>(Arrays.asList(
+ // See https://www.w3.org/TR/html-markup/global-attributes.html#common.attrs.event-handler
+ "onabort", "onblur", "oncanplay", "oncanplaythrough",
+ "onchange", "onclick", "oncontextmenu", "ondblclick",
+ "ondrag", "ondragend", "ondragenter", "ondragleave",
+ "ondragover", "ondragstart", "ondrop", "ondurationchange",
+ "onemptied", "onended", "onerror", "onfocus", "oninput",
+ "oninvalid", "onkeydown", "onkeypress", "onkeyup",
+ "onload", "onloadeddata", "onloadedmetadata", "onloadstart",
+ "onmousedown", "onmousemove", "onmouseout", "onmouseover",
+ "onmouseup", "onmousewheel", "onpause", "onplay",
+ "onplaying", "onprogress", "onratechange", "onreadystatechange",
+ "onreset", "onscroll", "onseeked", "onseeking",
+ "onselect", "onshow", "onstalled", "onsubmit", "onsuspend",
+ "ontimeupdate", "onvolumechange", "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.
+ // "onchange", "onclick", "ondblclick", "onfocus",
+ // "onkeydown", "onkeypress", "onkeyup", "onload",
+ // "onmousedown", "onmousemove", "onmouseout", "onmouseover",
+ // "onmouseup", "onreset", "onselect", "onsubmit",
+ "onunload"
+ ));
+ }
+
+ private void initURIAttrs() {
+ uriAttrs = new HashSet<>(Arrays.asList(
+ // 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
+ "action", "cite", "classid", "codebase", "data",
+ "datasrc", "for", "href", "longdesc", "profile",
+ "src", "usemap"
+ ));
+ }
+
+}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocEnter.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocEnter.java Fri Jan 20 19:10:00 2017 +0000
@@ -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.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 @@
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;
}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
// 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)
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
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(
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Fri Jan 20 19:10:00 2017 +0000
@@ -145,6 +145,8 @@
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
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java Fri Jan 20 19:10:00 2017 +0000
@@ -296,9 +296,21 @@
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()) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties Fri Jan 20 19:10:00 2017 +0000
@@ -363,6 +363,9 @@
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=\
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java Fri Jan 20 19:10:00 2017 +0000
@@ -40,6 +40,7 @@
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 @@
}
try {
- startGeneration(docEnv);
- return true;
+ try {
+ startGeneration(docEnv);
+ return true;
+ } catch (UncheckedDocletException e) {
+ throw (DocletException) e.getCause();
+ }
} catch (DocFileIOException e) {
switch (e.mode) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java Fri Jan 20 19:10:00 2017 +0000
@@ -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.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 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 @@
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);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Fri Jan 20 19:10:00 2017 +0000
@@ -228,6 +228,11 @@
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 @@
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 @@
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 @@
}
}
}
+
+ /**
+ * 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;
+ }
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Fri Jan 20 19:10:00 2017 +0000
@@ -44,6 +44,7 @@
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.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 @@
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 @@
}
}
- // 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.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AbstractBuilder.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AbstractBuilder.java Fri Jan 20 19:10:00 2017 +0000
@@ -35,6 +35,7 @@
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 @@
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
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties Fri Jan 20 19:10:00 2017 +0000
@@ -42,6 +42,10 @@
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
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css Fri Jan 20 19:10:00 2017 +0000
@@ -250,17 +250,19 @@
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;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/JavaScriptScanner.java Fri Jan 20 19:10:00 2017 +0000
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/UncheckedDocletException.java Fri Jan 20 19:10:00 2017 +0000
@@ -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();
+ }
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Fri Jan 20 19:10:00 2017 +0000
@@ -27,6 +27,7 @@
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 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 @@
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 @@
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 @@
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;
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 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.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.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 @@
}
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;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocClassFinder.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocClassFinder.java Fri Jan 20 19:10:00 2017 +0000
@@ -88,8 +88,7 @@
@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;
}
}
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocEnter.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocEnter.java Fri Jan 20 19:10:00 2017 +0000
@@ -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.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 @@
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;
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
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);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java Fri Jan 20 19:10:00 2017 +0000
@@ -182,7 +182,7 @@
}
private String getDiagSource(DocTreePath path) {
- if (path == null) {
+ if (path == null || path.getTreePath() == null) {
return programName;
}
JavacTrees trees = JavacTrees.instance(context);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
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 @@
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 @@
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.
*
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ModuleResolution_attribute.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ModuleResolution_attribute.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 ModuleResolution_attribute(ConstantPool constant_pool,
int resolution_flags)
throws ConstantPoolException {
- this(constant_pool.getUTF8Index(Attribute.ModulePackages),
+ this(constant_pool.getUTF8Index(Attribute.ModuleResolution),
resolution_flags);
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Fri Jan 20 19:10:00 2017 +0000
@@ -128,9 +128,8 @@
*/
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 @@
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 @@
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 @@
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 @@
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 = Startup.fromFileList(sts, "--startup", new InitMessageHandler());
+ if (initialStartup == null) {
+ return null;
}
- initialStartup = sb.toString();
} else if (options.has(argNoStart)) {
- initialStartup = "";
+ initialStartup = Startup.noStartup();
} else {
- initialStartup = prefs.get(STARTUP_KEY);
- if (initialStartup == null) {
- initialStartup = defaultStartup();
- }
+ String packedStartup = prefs.get(STARTUP_KEY);
+ initialStartup = Startup.unpack(packedStartup, new InitMessageHandler());
}
if (options.has(argExecution)) {
executionControlSpec = options.valueOf(argExecution);
@@ -639,6 +630,11 @@
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 @@
analysis = state.sourceCodeAnalysis();
live = true;
- startUpRun(startup);
+ startUpRun(startup.toString());
currentNameSpace = mainNamespace;
}
@@ -1077,7 +1073,7 @@
.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 @@
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);
+ 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 {
+ sb.append(startup.show(false));
+ sb.append(startup.showDetail());
}
- }
-
- 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";
- } else {
- stset = "startup.jsh:\n" + start + "\n" + cmd + "startup.jsh";
- }
- hard(stset);
+ hard(sb.toString());
}
boolean cmdDebug(String arg) {
@@ -2200,13 +2191,22 @@
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 @@
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 @@
}
// 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 @@
writer.write("\n");
}
} else if (at.hasOption("-start")) {
- writer.append(startup);
+ writer.append(startup.toString());
} else {
String sources = (at.hasOption("-all")
? state.snippets()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Startup.java Fri Jan 20 19:10:00 2017 +0000
@@ -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();
+ }
+
+}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Fri Jan 20 19:10:00 2017 +0000
@@ -148,6 +148,8 @@
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>
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/tool/resources/DEFAULT.jsh Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/tool/resources/DEFAULT.jsh Fri Jan 20 19:10:00 2017 +0000
@@ -8,4 +8,3 @@
import java.util.prefs.*;
import java.util.regex.*;
import java.util.stream.*;
-
--- a/langtools/test/Makefile Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/Makefile Fri Jan 20 19:10:00 2017 +0000
@@ -378,7 +378,7 @@
@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 @@
@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 \
--- a/langtools/test/TEST.ROOT Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/TEST.ROOT Fri Jan 20 19:10:00 2017 +0000
@@ -14,8 +14,8 @@
# 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/TestScriptInComment.java Fri Jan 20 19:10:00 2017 +0000
@@ -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;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/treeapi/TestDocTrees.java Fri Jan 20 19:10:00 2017 +0000
@@ -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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/treeapi/overview.html Fri Jan 20 19:10:00 2017 +0000
@@ -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>
\ No newline at end of file
--- a/langtools/test/jdk/jshell/ExternalEditorTest.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/jdk/jshell/ExternalEditorTest.java Fri Jan 20 19:10:00 2017 +0000
@@ -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.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 @@
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");
}
--- a/langtools/test/jdk/jshell/ToolCommandOptionTest.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
(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 @@
"| /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.*;")
);
}
--- a/langtools/test/jdk/jshell/ToolFormatTest.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/jdk/jshell/ToolFormatTest.java Fri Jan 20 19:10:00 2017 +0000
@@ -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.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 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 @@
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");
+ ****/
}
}
}
--- a/langtools/test/tools/doclint/html/OtherTagsTest.out Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/doclint/html/OtherTagsTest.out Fri Jan 20 19:10:00 2017 +0000
@@ -19,10 +19,7 @@
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
--- a/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java Fri Jan 20 19:10:00 2017 +0000
@@ -143,6 +143,7 @@
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",
--- a/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTest.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTest.java Fri Jan 20 19:10:00 2017 +0000
@@ -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
@@ -53,6 +53,28 @@
}
@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")
.exports("pack")
@@ -92,16 +114,6 @@
}
@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")
.exportsTo("pack", "jdk.compiler, jdk.jdeps")
@@ -121,6 +133,47 @@
}
@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")
.requires("jdk.compiler")
@@ -182,10 +235,12 @@
.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 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,10 @@
Path m1 = base.resolve("m1x");
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m1x")
.exports("pack1")
- .exports("pack3")
+ .opens("pack3")
.exportsTo("packTo1", "m2x")
- .exportsTo("packTo3", "m3x")
+ .opensTo("packTo1", "m2x") // the same as exportsTo
+ .opensTo("packTo3", "m3x")
.requires("jdk.compiler")
.requires("m2x", RequiresFlag.TRANSITIVE)
.requires("m3x", RequiresFlag.STATIC)
@@ -230,9 +287,49 @@
.requires("m5x", RequiresFlag.STATIC)
.requires("m6x", RequiresFlag.TRANSITIVE)
.requires("java.compiler")
- .exportsTo("packTo4", "java.compiler")
+ .opensTo("packTo4", "java.compiler")
.exportsTo("packTo2", "java.compiler")
- .exports("pack4")
+ .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")
+ .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")
+ .exportsTo("packTo2", "java.compiler")
.exports("pack2")
.write(m1);
tb.writeJavaFiles(m1, "package pack1; public class C extends java.util.ArrayList{ }",
--- a/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTestBase.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTestBase.java Fri Jan 20 19:10:00 2017 +0000
@@ -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.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.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 @@
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 @@
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 @@
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 @@
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 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 @@
}
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 @@
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 @@
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 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 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 @@
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)
--- a/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
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");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classreader/FileSystemClosedTest.java Fri Jan 20 19:10:00 2017 +0000
@@ -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;
+ }
+}
+
--- a/langtools/test/tools/javac/diags/Example.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/diags/Example.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 @@
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 @@
}
}
} 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 @@
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 @@
// 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 @@
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 @@
List<File> modulePathFiles;
List<File> classPathFiles;
List<File> additionalFiles;
+ List<File> nonEmptySrcFiles;
File infoFile;
private List<String> runOpts;
private List<String> options;
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Fri Jan 20 19:10:00 2017 +0000
@@ -103,6 +103,7 @@
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
--- a/langtools/test/tools/javac/diags/examples/DirPathElementNotDirectory/DirPathElementNotDirectory.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/DirPathElementNotDirectory/DirPathElementNotDirectory.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleNotOnModuleSourcePath/ModuleNotOnModuleSourcePath.java Fri Jan 20 19:10:00 2017 +0000
@@ -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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleNotOnModuleSourcePath/modulesourcepath/m/extra/module-info.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotInModuleOnModuleSourcePath/NotInModuleOnModuleSourcePath.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotInModuleOnModuleSourcePath/modulesourcepath/m/module-info.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 { }
+
--- a/langtools/test/tools/javac/diags/examples/UnnamedPackageInNamedModule/UnnamedPackageInNamedModule.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/UnnamedPackageInNamedModule/UnnamedPackageInNamedModule.java Fri Jan 20 19:10:00 2017 +0000
@@ -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 {}
--- a/langtools/test/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8132096
+ * @bug 8132096 8157611
* @summary test the APIs in the DocTree interface
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
@@ -48,12 +48,15 @@
import java.util.Locale;
import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.util.Elements;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.util.DocTreePath;
import com.sun.source.util.DocTrees;
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.api.JavacTool;
@@ -90,6 +93,9 @@
// tests files relative path in an unnamed package
test.runRelativePathTest("OverviewTest.java", "overview0.html");
+ // tests doctreepath using package element and package.html
+ test.runDocTreePath("pkg/Anchor.java", "package.html");
+
// test for correct parsing using valid and some invalid html tags
for (int i = 0; i < 7; i++) {
String hname = "overview" + i + ".html";
@@ -152,6 +158,7 @@
}
}
}
+
/**
* Tests DocTrees.getDocCommentTree(Element e, String relpath) using relative path.
*
@@ -219,6 +226,49 @@
}
}
+ /**
+ * Tests DocTrees.getDocTreePath(PackageElement p, FileObject fo).
+ *
+ * @param javaFileName the java anchor file
+ * @param pkgFileName the package file name
+ * @throws Exception e if something goes awry
+ */
+ public void runDocTreePath(String javaFileName, String pkgFileName) throws Exception {
+ List<File> javaFiles = new ArrayList<>();
+ javaFiles.add(new File(testSrc, javaFileName));
+
+ List<File> dirs = new ArrayList<>();
+ dirs.add(new File(testSrc));
+
+ try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) {
+ fm.setLocation(javax.tools.StandardLocation.SOURCE_PATH, dirs);
+ Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(javaFiles);
+
+ final JavacTask t = javac.getTask(null, fm, null, null, null, fos);
+ final DocTrees trees = DocTrees.instance(t);
+ final Elements elementUtils = t.getElements();
+
+ Iterable<? extends Element> elements = t.analyze();
+
+ Element klass = elements.iterator().next();
+ PackageElement pkg = elementUtils.getPackageOf(klass);
+
+ FileObject htmlFo = fm.getFileForInput(javax.tools.StandardLocation.SOURCE_PATH,
+ t.getElements().getPackageOf(klass).getQualifiedName().toString(),
+ "package.html");
+ System.out.println();
+ DocTreePath treePath = trees.getDocTreePath(htmlFo, pkg);
+ DocCommentTree dcTree = treePath.getDocComment();
+
+ StringWriter sw = new StringWriter();
+ printer.print(dcTree, sw);
+ String found = sw.toString();
+
+ String expected = getExpected(htmlFo.openReader(true));
+ astcheck(pkgFileName, expected, found);
+ }
+ }
+
void astcheck(String testinfo, String expected, String found) {
System.err.print("ASTChecker: " + testinfo);
check0(expected, found);
--- a/langtools/test/tools/javac/lib/combo/ReusableContext.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/lib/combo/ReusableContext.java Fri Jan 20 19:10:00 2017 +0000
@@ -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
@@ -38,6 +38,7 @@
import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.CompileStates;
import com.sun.tools.javac.comp.Enter;
@@ -95,6 +96,7 @@
Types.instance(this).newRound();
Check.instance(this).newRound();
Modules.instance(this).newRound();
+ Annotate.instance(this).newRound();
CompileStates.instance(this).clear();
MultiTaskListener.instance(this).clear();
--- a/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java Fri Jan 20 19:10:00 2017 +0000
@@ -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
@@ -23,11 +23,12 @@
/*
* @test
- * @bug 8169197 8172668
+ * @bug 8169197 8172668 8173117
* @summary Check convenient errors are produced for inaccessible classes.
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
+ * jdk.compiler/com.sun.tools.javac.util
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
* @run main ConvenientAccessErrorsTest
*/
@@ -37,6 +38,10 @@
import java.util.Arrays;
import java.util.List;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Convert;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
import toolbox.JarTask;
import toolbox.JavacTask;
import toolbox.Task;
@@ -79,6 +84,37 @@
}
@Test
+ public void testNoDepNested(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { exports api; }",
+ "package api; public class Api { public static class Nested {} }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { }",
+ "package test; public class Test { api.Api.Nested nested; }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:35: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read: m2x, api, m1x)",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
public void testNotExported(Path base) throws Exception {
Path src = base.resolve("src");
Path src_m1 = src.resolve("m1x");
@@ -390,8 +426,7 @@
List<String> expected = Arrays.asList(
"Test.java:1:22: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.not.exported: api, m1x)",
- "Test.java:1:49: compiler.err.not.def.access.package.cant.access: api.Api, api, (compiler.misc.not.def.access.not.exported: api, m1x)",
- "2 errors");
+ "1 error");
if (!expected.equals(log))
throw new Exception("expected output not found; actual: " + log);
@@ -593,4 +628,80 @@
throw new Exception("expected output not found; actual: " + log);
}
+ @Test
+ public void testInaccessibleInSourceModuleViaBinaryModule(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "@Deprecated module m1x { }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { requires transitive m1x; }");
+ Path src_m3 = src.resolve("m3x");
+ tb.writeJavaFiles(src_m3,
+ "module m3x { requires transitive m2x; exports api; }",
+ "package api; class Api { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ tb.cleanDirectory(classes.resolve("m2x")); //force completion from source if needed
+ Files.delete(classes.resolve("m2x"));
+
+ tb.cleanDirectory(src_m3); //binary only module
+ Files.delete(src_m3);
+
+ //m4x does not depend on m1x/m2x/m3x, so cannot access api.Api
+ //but the recovery search should not complete m2x, as that would cause a deprecation warning:
+ Path src_m4 = src.resolve("m4x");
+ tb.writeJavaFiles(src_m4,
+ "module m4x { }",
+ "package m4x; public class Test extends api.Api { }");
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString(),
+ "--module-path", classes.toString(),
+ "-Xlint:deprecation")
+ .outdir(classes)
+ .files(findJavaFiles(src_m4))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:40: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read: m4x, api, m3x)",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testConvertNameCandidates(Path base) throws Exception {
+ Context ctx = new Context();
+ Names names = Names.instance(ctx);
+ Name name = names.fromString("com.sun.tools.javac.Attr.BreakAttr");
+
+ com.sun.tools.javac.util.List<String> actual =
+ Convert.classCandidates(name).map(n -> n.toString());
+ List<String> expected = Arrays.asList(
+ "com.sun$tools$javac$Attr$BreakAttr",
+ "com.sun.tools$javac$Attr$BreakAttr",
+ "com.sun.tools.javac$Attr$BreakAttr",
+ "com.sun.tools.javac.Attr$BreakAttr",
+ "com.sun.tools.javac.Attr.BreakAttr"
+ );
+
+ if (!expected.equals(actual)) {
+ throw new Exception("Expected names not generated: " + actual);
+ }
+ }
}
--- a/langtools/test/tools/javac/modules/EdgeCases.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/modules/EdgeCases.java Fri Jan 20 19:10:00 2017 +0000
@@ -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
@@ -23,13 +23,14 @@
/*
* @test
- * @bug 8154283 8167320
+ * @bug 8154283 8167320 8171098 8172809 8173117
* @summary tests for multi-module mode compilation
* @library /tools/lib
* @modules
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.main
+ * jdk.compiler/com.sun.tools.javac.util
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
* @run main EdgeCases
*/
@@ -44,7 +45,16 @@
import java.util.Objects;
import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedOptions;
+import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.ModuleElement.RequiresDirective;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
@@ -484,4 +494,164 @@
throw new AssertionError("Unexpected output: " + log);
}
}
+
+ @Test
+ public void testInvisibleClassVisiblePackageClash(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { }",
+ "package m1x;\n" +
+ "import m1x.a.*; public class Test { A a; }\n",
+ "package m1x.a;\n" +
+ "public class A { }\n");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { }",
+ "package m1x;\n" +
+ "public class a { public static class A { } }\n");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ new JavacTask(tb)
+ .options("--module-source-path", src.toString(),
+ "-XDrawDiagnostics")
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+ }
+
+ @Test
+ public void testStripUnknownRequired(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { }");
+ Path src_m3 = src.resolve("m3x");
+ tb.writeJavaFiles(src_m3,
+ "module m3x { }");
+ Path src_m4 = src.resolve("m4x");
+ tb.writeJavaFiles(src_m4,
+ "module m4x { }");
+ Path src_test = src.resolve("test");
+ tb.writeJavaFiles(src_test,
+ "module test { requires m1x; requires m2x; requires java.base; requires m3x; requires m4x; }");
+ Path src_compile = src.resolve("compile");
+ tb.writeJavaFiles(src_compile,
+ "module compile { exports p to test; }",
+ "package p; public class Test { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-processor", ListRequires.class.getName(),
+ "--module-source-path", src.toString(),
+ "--limit-modules", "compile",
+ "-XDaccessInternalAPI=true")
+ .outdir(classes)
+ .files(findJavaFiles(src_compile))
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.STDOUT);
+
+ List<String> expected = Arrays.asList(
+ "from directives:",
+ "java.base",
+ "from requires:",
+ "java.base"
+ );
+ if (!Objects.equals(log, expected))
+ throw new AssertionError("Unexpected output: " + log);
+ }
+
+ @SupportedAnnotationTypes("*")
+ @SupportedOptions("expectedEnclosedElements")
+ public static final class ListRequires extends AbstractProcessor {
+
+ private int round;
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (round++ == 0) {
+ ModuleElement compileE = processingEnv.getElementUtils().getModuleElement("compile");
+ ModuleElement testE = ElementFilter.exportsIn(compileE.getDirectives()).get(0).getTargetModules().get(0);
+
+ System.out.println("from directives:");
+ for (RequiresDirective rd : ElementFilter.requiresIn(testE.getDirectives())) {
+ System.out.println(rd.getDependency().getSimpleName());
+ }
+
+ System.out.println("from requires:");
+ for (RequiresDirective rd : ((ModuleSymbol) testE).requires) {
+ System.out.println(rd.getDependency().getSimpleName());
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
+ }
+
+ @Test
+ public void testOnDemandCompletionModuleInfoJava(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "@Deprecated module m1x { }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { requires m1x; }");
+ Path src_m3 = src.resolve("m3x");
+ tb.writeJavaFiles(src_m3,
+ "module m3x { requires m2x; requires m1x; }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log;
+ List<String> expected;
+
+ log = new JavacTask(tb)
+ .options("--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src_m1))
+ .run()
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList("");
+
+ if (!expected.equals(log)) {
+ throw new IllegalStateException(log.toString());
+ }
+
+ log = new JavacTask(tb)
+ .options("--module-source-path", src.toString(),
+ "-XDrawDiagnostics",
+ "-Xlint:deprecation")
+ .outdir(classes)
+ .files(findJavaFiles(src_m3))
+ .run()
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList(
+ "module-info.java:1:23: compiler.warn.has.been.deprecated.module: m1x",
+ "module-info.java:1:37: compiler.warn.has.been.deprecated.module: m1x",
+ "2 warnings"
+ );
+
+ if (!expected.equals(log)) {
+ throw new IllegalStateException(log.toString());
+ }
+ }
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/IncubatingTest.java Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,291 @@
+/*
+ * 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
+ * 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 8171177
+ * @summary Verify that ModuleResolution attribute flags are honored.
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * jdk.jdeps/com.sun.tools.classfile
+ * jdk.jdeps/com.sun.tools.javap
+ * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.JavapTask ModuleTestBase
+ * @run main IncubatingTest
+ */
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.Attributes;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ClassWriter;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
+import com.sun.tools.classfile.ConstantPool.CPInfo;
+import com.sun.tools.classfile.ModuleResolution_attribute;
+import toolbox.JavacTask;
+import toolbox.Task;
+import toolbox.Task.Expect;
+
+public class IncubatingTest extends ModuleTestBase {
+
+ public static void main(String... args) throws Exception {
+ new IncubatingTest().runTests();
+ }
+
+ @Test
+ public void testDoNotResolve(Path base) throws Exception {
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src,
+ "module jdk.i { exports api; }",
+ "package api; public class Api { }");
+ Path classes = base.resolve("classes");
+ Files.deleteIfExists(classes);
+ Path iClasses = classes.resolve("jdk.i");
+ tb.createDirectories(iClasses);
+
+ new JavacTask(tb)
+ .outdir(iClasses)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ copyJavaBase(classes);
+
+ Path jdkIModuleInfo = iClasses.resolve("module-info.class");
+ addModuleResolutionAttribute(jdkIModuleInfo, ModuleResolution_attribute.DO_NOT_RESOLVE_BY_DEFAULT);
+
+ Path testSrc = base.resolve("test-src");
+ tb.writeJavaFiles(testSrc,
+ "class T { api.Api api; }");
+ Path testClasses = base.resolve("test-classes");
+ tb.createDirectories(testClasses);
+
+ List<String> log;
+ List<String> expected;
+
+ log = new JavacTask(tb)
+ .options("--system", "none",
+ "--upgrade-module-path", classes.toString(),
+ "-XDrawDiagnostics")
+ .outdir(testClasses)
+ .files(findJavaFiles(testSrc))
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList(
+ "T.java:1:11: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read.from.unnamed: api, jdk.i)",
+ "1 error"
+ );
+
+ if (!expected.equals(log)) {
+ throw new AssertionError("Unexpected output: " + log);
+ }
+
+ log = new JavacTask(tb)
+ .options("--system", "none",
+ "--upgrade-module-path", classes.toString(),
+ "--add-modules", "ALL-SYSTEM",
+ "-XDrawDiagnostics")
+ .outdir(testClasses)
+ .files(findJavaFiles(testSrc))
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList(
+ "T.java:1:11: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read.from.unnamed: api, jdk.i)",
+ "1 error"
+ );
+
+ if (!expected.equals(log)) {
+ throw new AssertionError("Unexpected output: " + log);
+ }
+
+ new JavacTask(tb)
+ .options("--system", "none",
+ "--upgrade-module-path", classes.toString(),
+ "--add-modules", "jdk.i")
+ .outdir(testClasses)
+ .files(findJavaFiles(testSrc))
+ .run()
+ .writeAll();
+
+ Path testModuleSrc = base.resolve("test-module-src");
+ tb.writeJavaFiles(testModuleSrc,
+ "module test { requires jdk.i; }", //explicit requires of an incubating module
+ "class T { api.Api api; }");
+ Path testModuleClasses = base.resolve("test-module-classes");
+ tb.createDirectories(testModuleClasses);
+
+ new JavacTask(tb)
+ .options("--system", "none",
+ "--upgrade-module-path", classes.toString())
+ .outdir(testModuleClasses)
+ .files(findJavaFiles(testModuleSrc))
+ .run()
+ .writeAll();
+ }
+
+ @Test
+ public void testIncubating(Path base) throws Exception {
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src,
+ "module jdk.i { exports api; }",
+ "package api; public class Api { }");
+ Path classes = base.resolve("classes");
+ Files.deleteIfExists(classes);
+ Path iClasses = classes.resolve("jdk.i");
+ tb.createDirectories(iClasses);
+
+ new JavacTask(tb)
+ .outdir(iClasses)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ Path jdkIModuleInfo = iClasses.resolve("module-info.class");
+ addModuleResolutionAttribute(jdkIModuleInfo, ModuleResolution_attribute.WARN_INCUBATING);
+
+ Path testSrc = base.resolve("test-src");
+ tb.writeJavaFiles(testSrc,
+ "class T { api.Api api; }");
+ Path testClasses = base.resolve("test-classes");
+ tb.createDirectories(testClasses);
+
+ List<String> log;
+ List<String> expected;
+
+ log = new JavacTask(tb)
+ .options("--module-path", classes.toString(),
+ "--add-modules", "jdk.i",
+ "-XDrawDiagnostics",
+ "-Werror")
+ .outdir(testClasses)
+ .files(findJavaFiles(testSrc))
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList(
+ "- compiler.warn.incubating.modules: jdk.i",
+ "- compiler.err.warnings.and.werror",
+ "1 error",
+ "1 warning"
+ );
+
+ if (!expected.equals(log)) {
+ throw new AssertionError("Unexpected output: " + log);
+ }
+
+ Path testModuleSrc = base.resolve("test-module-src");
+ tb.writeJavaFiles(testModuleSrc,
+ "module test { requires jdk.i; }", //explicit requires of an incubating module
+ "class T { api.Api api; }");
+ Path testModuleClasses = base.resolve("test-module-classes");
+ tb.createDirectories(testModuleClasses);
+
+ log = new JavacTask(tb)
+ .options("--module-path", classes.toString(),
+ "-XDrawDiagnostics",
+ "-Werror")
+ .outdir(testModuleClasses)
+ .files(findJavaFiles(testModuleSrc))
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList(
+ "- compiler.warn.incubating.modules: jdk.i",
+ "- compiler.err.warnings.and.werror",
+ "1 error",
+ "1 warning"
+ );
+
+ if (!expected.equals(log)) {
+ throw new AssertionError("Unexpected output: " + log);
+ }
+ }
+
+ private void copyJavaBase(Path targetDir) throws IOException {
+ FileSystem jrt = FileSystems.getFileSystem(URI.create("jrt:/"));
+ Path javaBase = jrt.getPath("modules", "java.base");
+
+ if (!Files.exists(javaBase)) {
+ throw new AssertionError("No java.base?");
+ }
+
+ Path javaBaseClasses = targetDir.resolve("java.base");
+
+ for (Path clazz : tb.findFiles("class", javaBase)) {
+ Path target = javaBaseClasses.resolve(javaBase.relativize(clazz).toString());
+ Files.createDirectories(target.getParent());
+ Files.copy(clazz, target);
+ }
+ }
+
+ private void addModuleResolutionAttribute(Path classfile, int resolution_flags) throws Exception {
+ ClassFile cf = ClassFile.read(classfile);
+ Attributes attrs = cf.attributes;
+ List<CPInfo> cpData = new ArrayList<>();
+ cpData.add(null);
+ for (CPInfo info : cf.constant_pool.entries()) {
+ cpData.add(info);
+ if (info.size() == 2)
+ cpData.add(null);
+ }
+ cpData.add(new CONSTANT_Utf8_info(Attribute.ModuleResolution));
+ ConstantPool newCP = new ConstantPool(cpData.toArray(new CPInfo[0]));
+ ModuleResolution_attribute res = new ModuleResolution_attribute(newCP, resolution_flags);
+ Map<String, Attribute> newAttributeMap = new HashMap<>(attrs.map);
+ newAttributeMap.put(Attribute.ModuleResolution, res);
+ Attributes newAttrs = new Attributes(newAttributeMap);
+ ClassFile newCF = new ClassFile(cf.magic,
+ cf.minor_version,
+ cf.major_version,
+ newCP,
+ cf.access_flags,
+ cf.this_class,
+ cf.super_class,
+ cf.interfaces,
+ cf.fields,
+ cf.methods,
+ newAttrs);
+ try (OutputStream out = Files.newOutputStream(classfile)) {
+ new ClassWriter().write(newCF, out);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/ModulesAndModuleSourcePathTest.java Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+/**
+ * @test 8165102
+ * @summary incorrect message from javac
+ * @library /tools/lib
+ * @modules
+ * jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
+ * @run main ModulesAndModuleSourcePathTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import toolbox.JavacTask;
+import toolbox.Task;
+import toolbox.ToolBox;
+
+public class ModulesAndModuleSourcePathTest extends ModuleTestBase {
+ public static void main(String... args) throws Exception {
+ ModulesAndModuleSourcePathTest t = new ModulesAndModuleSourcePathTest();
+ t.runTests();
+ }
+
+ @Test
+ public void testModuleNotInModuleSrcPath(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path m = src.resolve("m");
+ Path extra = m.resolve("extra");
+ tb.writeJavaFiles(extra, "module m {}");
+ Path classes = base.resolve("classes");
+ Files.createDirectories(classes);
+
+ String log = new JavacTask(tb)
+ .options("-XDrawDiagnostics", "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+ if (!log.contains("module-info.java:1:1: compiler.err.module.not.found.on.module.source.path"))
+ throw new Exception("expected output not found");
+ }
+}
--- a/langtools/test/tools/javac/modules/MultiModuleModeTest.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/modules/MultiModuleModeTest.java Fri Jan 20 19:10:00 2017 +0000
@@ -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
@@ -90,7 +90,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("C.java:1:1: compiler.err.unnamed.pkg.not.allowed.named.modules"))
+ if (!log.contains("C.java:1:1: compiler.err.not.in.module.on.module.source.path"))
throw new Exception("expected output not found");
}
--- a/langtools/test/tools/javac/modules/PackageMultipleModules.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/modules/PackageMultipleModules.java Fri Jan 20 19:10:00 2017 +0000
@@ -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
@@ -70,9 +70,10 @@
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
- List<String> expected = Arrays.asList("A.java:1:22: compiler.err.package.not.visible: test, (compiler.misc.not.def.access.does.not.read: m1x, test, m2x)",
- "B.java:1:22: compiler.err.package.not.visible: test, (compiler.misc.not.def.access.does.not.read: m2x, test, m1x)",
- "2 errors");
+ List<String> expected = Arrays.asList(
+ "A.java:1:26: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.package, test, null)",
+ "B.java:1:26: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.package, test, null)",
+ "2 errors");
if (!log.equals(expected))
throw new Exception("expected output not found");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/TestVisitorDefaults.java Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8172910
+ * @summary Test behavior of default methods on visitors.
+ * @modules java.compiler
+ */
+
+import java.util.List;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+/**
+ * Verify expected behavior of default methods on visitors.
+ */
+public class TestVisitorDefaults {
+ public static void main(String... args) {
+ DirectElementVisitorChild dvc = new DirectElementVisitorChild();
+ if (!"visitUnknown".equals(dvc.visitModule(null, null))) {
+ throw new RuntimeException("Problem with DirectElementVisitorChild");
+ }
+ if (!"visit".equals(dvc.visit(null))) {
+ throw new RuntimeException("Problem with DirectElementVisitorChild");
+ }
+
+ IndirectElementVisitorChild ivc = new IndirectElementVisitorChild();
+ if (!"visitUnknown".equals(ivc.visitModule(null, null))) {
+ throw new RuntimeException("Problem with IndirectElementVisitorChild");
+ }
+
+ DirectTypeVisitorChild dtvc = new DirectTypeVisitorChild();
+ if (!"visit".equals(dtvc.visit(null))) {
+ throw new RuntimeException("Problem with DirectTypeVisitorChild");
+ }
+
+ DirectAnnotationVisitorChild davc = new DirectAnnotationVisitorChild();
+ if (!"visit".equals(davc.visit(null))) {
+ throw new RuntimeException("Problem with DirectAnnotationVisitorChild");
+ }
+ }
+
+ private static class DirectElementVisitorChild
+ implements ElementVisitor<String, Object> {
+
+ public DirectElementVisitorChild() {
+ super();
+ }
+
+ @Override
+ public String visitModule(ModuleElement e, Object o) {
+ return ElementVisitor.super.visitModule(e, null);
+ }
+
+ @Override
+ public String visitUnknown(Element e, Object o) {
+ return "visitUnknown";
+ }
+
+ @Override
+ public String visit(Element e) {
+ return ElementVisitor.super.visit(e);
+ }
+
+ @Override
+ public String visit(Element e, Object o) {
+ return "visit";
+ }
+
+ @Override
+ public String visitExecutable(ExecutableElement e, Object o) { return throwUOE(); }
+ @Override
+ public String visitPackage(PackageElement e, Object o) { return throwUOE(); }
+ @Override
+ public String visitType(TypeElement e, Object o) { return throwUOE(); }
+ @Override
+ public String visitTypeParameter(TypeParameterElement e, Object o) { return throwUOE(); }
+ @Override
+ public String visitVariable(VariableElement e, Object o) { return throwUOE(); }
+ }
+
+ private static class IndirectElementVisitorChild
+ extends AbstractElementVisitor6<String, Object> {
+
+ public IndirectElementVisitorChild() {
+ super();
+ }
+
+ @Override
+ public String visitModule(ModuleElement e, Object o) {
+ return super.visitModule(e, o);
+ }
+
+
+ @Override
+ public String visitUnknown(Element e, Object o) {
+ return "visitUnknown";
+ }
+
+ @Override
+ public String visitExecutable(ExecutableElement e, Object o) { return throwUOE(); }
+ @Override
+ public String visitPackage(PackageElement e, Object o) { return throwUOE(); }
+ @Override
+ public String visitType(TypeElement e, Object o) { return throwUOE(); }
+ @Override
+ public String visitTypeParameter(TypeParameterElement e, Object o) { return throwUOE(); }
+ @Override
+ public String visitVariable(VariableElement e, Object o) { return throwUOE(); }
+ }
+
+
+ private static class DirectTypeVisitorChild
+ implements TypeVisitor<String, Object> {
+
+ public DirectTypeVisitorChild() {
+ super();
+ }
+
+ @Override
+ public String visit(TypeMirror t) {
+ return TypeVisitor.super.visit(t);
+ }
+
+ @Override
+ public String visit(TypeMirror t, Object o) {
+ return "visit";
+ }
+
+ @Override
+ public String visitUnknown(TypeMirror t, Object o) { return throwUOE(); }
+ @Override
+ public String visitArray(ArrayType t, Object o) { return throwUOE(); }
+ @Override
+ public String visitDeclared(DeclaredType t, Object o) { return throwUOE(); }
+ @Override
+ public String visitError(ErrorType t, Object o) { return throwUOE(); }
+ @Override
+ public String visitExecutable(ExecutableType t, Object o) { return throwUOE(); }
+ @Override
+ public String visitIntersection(IntersectionType t, Object o) { return throwUOE(); }
+ @Override
+ public String visitNoType(NoType t, Object o) { return throwUOE(); }
+ @Override
+ public String visitNull(NullType t, Object o) { return throwUOE(); }
+ @Override
+ public String visitPrimitive(PrimitiveType t, Object o) { return throwUOE(); }
+ @Override
+ public String visitTypeVariable(TypeVariable t, Object o) { return throwUOE(); }
+ @Override
+ public String visitUnion(UnionType t, Object o) { return throwUOE(); }
+ @Override
+ public String visitWildcard(WildcardType t, Object o) { return throwUOE(); }
+ }
+
+ private static class DirectAnnotationVisitorChild
+ implements AnnotationValueVisitor<String, Object> {
+
+ @Override
+ public String visit(AnnotationValue av) {
+ return AnnotationValueVisitor.super.visit(av);
+ }
+
+ @Override
+ public String visit(AnnotationValue av, Object o) {
+ return "visit";
+ }
+
+ @Override
+ public String visitAnnotation(AnnotationMirror a, Object o) { return throwUOE(); }
+ @Override
+ public String visitArray(List<? extends AnnotationValue> vals,
+ Object o) { return throwUOE(); }
+ @Override
+ public String visitBoolean(boolean b, Object o) { return throwUOE(); }
+ @Override
+ public String visitByte(byte b, Object o) { return throwUOE(); }
+ @Override
+ public String visitChar(char c, Object o) { return throwUOE(); }
+ @Override
+ public String visitDouble(double d, Object o) { return throwUOE(); }
+ @Override
+ public String visitEnumConstant(VariableElement c, Object o) { return throwUOE(); }
+ @Override
+ public String visitFloat(float f, Object o) { return throwUOE(); }
+ @Override
+ public String visitInt(int i, Object o) { return throwUOE(); }
+ @Override
+ public String visitLong(long i, Object o) { return throwUOE(); }
+ @Override
+ public String visitShort(short s, Object o) { return throwUOE(); }
+ @Override
+ public String visitString(String s, Object o) { return throwUOE(); }
+ @Override
+ public String visitType(TypeMirror t, Object o) { return throwUOE(); }
+ @Override
+ public String visitUnknown(AnnotationValue av, Object o) { return throwUOE(); }
+ }
+
+ private static String throwUOE() {
+ throw new UnsupportedOperationException();
+ }
+}
--- a/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -88,6 +88,8 @@
Path path = fm.asPath(file);
int moduleIndex = path.getNameCount() - type.split("\\Q.\\E").length - 1;
String moduleName = path.getName(moduleIndex).toString();
+ if (moduleName.startsWith("jdk.incubator.")) //incubator modules not in module graph by default
+ continue;
try {
ModuleElement me = elements.getModuleElement(moduleName);
me.getClass();
--- a/langtools/test/tools/javadoc/8147801/T8147801.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javadoc/8147801/T8147801.java Fri Jan 20 19:10:00 2017 +0000
@@ -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
@@ -32,6 +32,8 @@
*/
import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.nio.file.ClosedFileSystemException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -80,19 +82,22 @@
void test(boolean withOption) {
System.err.println("Testing " + (withOption ? "with" : "without") + " option");
try {
+ String dump = "";
RootDoc root = getRootDoc(withOption);
for (ClassDoc cd: root.specifiedClasses()) {
- dump("", cd);
+ dump += dump(cd);
}
- if (!withOption) {
- error("expected option did not occur");
+ if (dump.contains("lib.Lib2.i")) {
+ if (!withOption) {
+ error("control case failed: Lib2 class file was read, unexpectedly, without using option");
+ }
+ } else {
+ if (withOption) {
+ error("test case failed: could not read Lib2 class file, using option");
+ }
}
} catch (ClosedFileSystemException e) {
- if (withOption) {
- error("Unexpected exception: " + e);
- } else {
- System.err.println("Exception received as expected: " + e);
- }
+ error("Unexpected exception: " + e);
}
System.err.println();
}
@@ -118,12 +123,21 @@
return cachedRoot;
}
- void dump(String prefix, ClassDoc cd) {
- System.err.println(prefix + "class: " + cd);
+ String dump(ClassDoc cd) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ dump(pw, "", cd);
+ String out = sw.toString();
+ System.err.println(out);
+ return out;
+ }
+
+ void dump(PrintWriter out, String prefix, ClassDoc cd) {
+ out.println(prefix + "class: " + cd);
for (FieldDoc fd: cd.fields()) {
- System.err.println(fd);
+ out.println(prefix + " " + fd);
if (fd.type().asClassDoc() != null) {
- dump(prefix + " ", fd.type().asClassDoc());
+ dump(out, prefix + " ", fd.type().asClassDoc());
}
}
}
--- a/langtools/test/tools/javadoc/8147801/jarsrc/lib/Lib2.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javadoc/8147801/jarsrc/lib/Lib2.java Fri Jan 20 19:10:00 2017 +0000
@@ -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,5 @@
package lib;
public class Lib2 {
- int i;
+ public int i;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/TestScriptInComment.java Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,314 @@
+/*
+ * 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/com.sun.tools.javadoc
+ */
+
+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
+ SA("<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); // javadcript 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 com.sun.tools.javadoc.Main.execute("javadoc", pw, pw, pw,
+ "com.sun.tools.doclets.standard.Standard", opts.toArray(new String[opts.size()]));
+ }
+
+ 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;
+}
+
--- a/langtools/test/tools/javap/T7004698.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javap/T7004698.java Fri Jan 20 19:10:00 2017 +0000
@@ -42,6 +42,7 @@
File srcFile = new File(srcDir, T7004698.class.getSimpleName() + ".java");
File classesDir = new File(".");
compile("-Xjcov",
+ "--add-modules", "jdk.jdeps",
"--add-exports", "jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED",
"-d", classesDir.getPath(),
srcFile.getPath());
--- a/langtools/test/tools/jdeps/APIDeps.java Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/jdeps/APIDeps.java Fri Jan 20 19:10:00 2017 +0000
@@ -60,6 +60,9 @@
Path testsrc = Paths.get(System.getProperty("test.src"));
List<String> options = new ArrayList<>();
+ // jdk.jdeps is a service provider module so needs to be explicitly included
+ options.add("--add-modules=jdk.jdeps");
+
// add --add-exports
String testModules = System.getProperty("test.modules", "");
List<String> addExports = new ArrayList<>();