This commit is contained in:
Lana Steuck 2017-01-20 19:10:00 +00:00
commit f0bbed0c96
115 changed files with 4726 additions and 515 deletions
langtools
src
java.compiler/share/classes/javax/lang/model
jdk.compiler/share/classes/com/sun
jdk.javadoc/share/classes
jdk.jdeps/share/classes/com/sun/tools/classfile
jdk.jshell/share/classes/jdk
internal/jshell/tool
jshell/tool/resources
test

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,7 @@ import java.util.List;
import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.tools.Diagnostic; import javax.tools.Diagnostic;
import javax.tools.FileObject; import javax.tools.FileObject;
import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaCompiler.CompilationTask;
@ -127,17 +128,22 @@ public abstract class DocTrees extends Trees {
/** /**
* Returns a doc tree path containing the doc comment tree of the given file. * 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 * The file must be an HTML file, in which case the doc comment tree represents
* contents of the &lt;body&gt; tag, and any enclosing tags are ignored. * 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. * Returns {@code null} if no doc comment was found.
* Future releases may support additional file types.
* *
* @param fileObject the content container * @param fileObject a file object encapsulating the HTML content
* @return a doc tree path containing the doc comment read from the given file. * @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 * @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 * Returns the language model element referred to by the leaf node of the given

@ -423,7 +423,16 @@ public class Checker extends DocTreePathScanner<Void, Void> {
break; break;
case OTHER: 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; return;
} }
@ -552,15 +561,19 @@ public class Checker extends DocTreePathScanner<Void, Void> {
if (!first) if (!first)
env.messages.error(HTML, tree, "dc.attr.repeated", name); env.messages.error(HTML, tree, "dc.attr.repeated", name);
} }
AttrKind k = currTag.getAttrKind(name); // for now, doclint allows all attribute names beginning with "on" as event handler names,
switch (env.htmlVersion) { // without checking the validity or applicability of the name
case HTML4: if (!name.toString().startsWith("on")) {
validateHtml4Attrs(tree, name, k); AttrKind k = currTag.getAttrKind(name);
break; switch (env.htmlVersion) {
case HTML4:
validateHtml4Attrs(tree, name, k);
break;
case HTML5: case HTML5:
validateHtml5Attrs(tree, name, k); validateHtml5Attrs(tree, name, k);
break; break;
}
} }
if (attr != null) { if (attr != null) {
@ -722,6 +735,9 @@ public class Checker extends DocTreePathScanner<Void, Void> {
} }
private void checkURI(AttributeTree tree, String uri) { 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 { try {
URI u = new URI(uri); URI u = new URI(uri);
} catch (URISyntaxException e) { } catch (URISyntaxException e) {

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -287,7 +287,8 @@ public enum HtmlTag {
SAMP(BlockType.INLINE, EndKind.REQUIRED, SAMP(BlockType.INLINE, EndKind.REQUIRED,
EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), 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, SECTION(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED,
EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),

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

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1045,7 +1045,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
DO_NOT_RESOLVE_BY_DEFAULT(0x0001), DO_NOT_RESOLVE_BY_DEFAULT(0x0001),
WARN_DEPRECATED(0x0002), WARN_DEPRECATED(0x0002),
WARN_DEPRECATED_REMOVAL(0x0004), WARN_DEPRECATED_REMOVAL(0x0004),
WARN_INCUBATOR(0x0008); WARN_INCUBATING(0x0008);
public static int value(Set<ModuleResolutionFlags> s) { public static int value(Set<ModuleResolutionFlags> s) {
int v = 0; int v = 0;
@ -1070,6 +1070,8 @@ public abstract class Symbol extends AnnoConstruct implements Element {
public Name fullname; public Name fullname;
public ClassSymbol package_info; // see bug 6443073 public ClassSymbol package_info; // see bug 6443073
public ModuleSymbol modle; public ModuleSymbol modle;
// the file containing the documentation comments for the package
public JavaFileObject sourcefile;
public PackageSymbol(Name name, Type type, Symbol owner) { public PackageSymbol(Name name, Type type, Symbol owner) {
super(PCK, 0, name, type, owner); super(PCK, 0, name, type, owner);

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -818,4 +818,12 @@ public class Symtab {
public Collection<ModuleSymbol> getAllModules() { public Collection<ModuleSymbol> getAllModules() {
return modules.values(); 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();
}
} }

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

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

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

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -553,7 +553,7 @@ public class Locations {
@Override @Override
Location getLocationForModule(Path dir) { Location getLocationForModule(Path dir) {
return pathLocations.get(dir); return (pathLocations == null) ? null : pathLocations.get(dir);
} }
private boolean listed; private boolean listed;

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ import java.io.*;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.CharBuffer; import java.nio.CharBuffer;
import java.nio.file.ClosedFileSystemException;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
@ -2756,8 +2757,8 @@ public class ClassReader {
currentModule.provides = List.nil(); currentModule.provides = List.nil();
} }
} }
} catch (IOException ex) { } catch (IOException | ClosedFileSystemException ex) {
throw badClassFile("unable.to.access.file", ex.getMessage()); throw badClassFile("unable.to.access.file", ex.toString());
} catch (ArrayIndexOutOfBoundsException ex) { } catch (ArrayIndexOutOfBoundsException ex) {
throw badClassFile("bad.class.file", c.flatname); throw badClassFile("bad.class.file", c.flatname);
} finally { } finally {

@ -588,7 +588,9 @@ public class Arguments {
checkOptionAllowed(t.compareTo(Target.JDK1_9) >= 0, checkOptionAllowed(t.compareTo(Target.JDK1_9) >= 0,
option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name), option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name),
Option.MODULE_SOURCE_PATH, Option.UPGRADE_MODULE_PATH, 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); Option.PATCH_MODULE);
if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) { if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) {

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -363,7 +363,7 @@ public class JavaCompiler {
**/ **/
protected boolean implicitSourceFilesRead; protected boolean implicitSourceFilesRead;
protected boolean enterDone; private boolean enterDone;
protected CompileStates compileStates; protected CompileStates compileStates;
@ -1042,7 +1042,7 @@ public class JavaCompiler {
public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) { public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
modules.initModules(roots); modules.initModules(roots);
if (roots.isEmpty()) { if (roots.isEmpty()) {
enterDone = true; enterDone();
} }
return roots; return roots;
} }
@ -1063,7 +1063,7 @@ public class JavaCompiler {
enter.main(roots); enter.main(roots);
enterDone = true; enterDone();
if (!taskListener.isEmpty()) { if (!taskListener.isEmpty()) {
for (JCCompilationUnit unit: roots) { for (JCCompilationUnit unit: roots) {
@ -1725,6 +1725,11 @@ public class JavaCompiler {
} }
} }
public void enterDone() {
enterDone = true;
annotate.enterDone();
}
public boolean isEnterDone() { public boolean isEnterDone() {
return enterDone; return enterDone;
} }

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

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

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

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -92,6 +92,7 @@ import com.sun.tools.javac.util.Options;
import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING; import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
import static com.sun.tools.javac.code.Kinds.Kind.*; 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.comp.CompileStates.CompileState;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
@ -123,6 +124,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
private final JavaCompiler compiler; private final JavaCompiler compiler;
private final Modules modules; private final Modules modules;
private final Types types; private final Types types;
private final Annotate annotate;
/** /**
* Holds relevant state history of which processors have been * Holds relevant state history of which processors have been
@ -219,6 +221,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
typeUtils = JavacTypes.instance(context); typeUtils = JavacTypes.instance(context);
modules = Modules.instance(context); modules = Modules.instance(context);
types = Types.instance(context); types = Types.instance(context);
annotate = Annotate.instance(context);
processorOptions = initProcessorOptions(); processorOptions = initProcessorOptions();
unmatchedProcessorOptions = initUnmatchedProcessorOptions(); unmatchedProcessorOptions = initUnmatchedProcessorOptions();
messages = JavacMessages.instance(context); messages = JavacMessages.instance(context);
@ -1256,6 +1259,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
compiler.newRound(); compiler.newRound();
modules.newRound(); modules.newRound();
types.newRound(); types.newRound();
annotate.newRound();
boolean foundError = false; boolean foundError = false;

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

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -335,4 +335,16 @@ public class Convert {
} }
return names; 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();
}
} }

@ -40,6 +40,7 @@ import com.sun.tools.doclint.DocLint;
import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.StringUtils; import com.sun.tools.javac.util.StringUtils;
import com.sun.tools.javadoc.main.JavaScriptScanner;
import com.sun.tools.javadoc.main.RootDocImpl; import com.sun.tools.javadoc.main.RootDocImpl;
/** /**
@ -188,6 +189,11 @@ public class ConfigurationImpl extends Configuration {
*/ */
public Set<String> doclintOpts = new LinkedHashSet<>(); 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. * Unique Resource Handler for this package.
*/ */
@ -309,8 +315,11 @@ public class ConfigurationImpl extends Configuration {
doclintOpts.add(DocLint.XMSGS_CUSTOM_PREFIX + opt.substring(opt.indexOf(":") + 1)); doclintOpts.add(DocLint.XMSGS_CUSTOM_PREFIX + opt.substring(opt.indexOf(":") + 1));
} else if (opt.startsWith("-xdoclint/package:")) { } else if (opt.startsWith("-xdoclint/package:")) {
doclintOpts.add(DocLint.XCHECK_PACKAGE + opt.substring(opt.indexOf(":") + 1)); 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) { if (root.specifiedClasses().length > 0) {
Map<String,PackageDoc> map = new HashMap<>(); Map<String,PackageDoc> map = new HashMap<>();
PackageDoc pd; PackageDoc pd;
@ -322,15 +331,37 @@ public class ConfigurationImpl extends Configuration {
} }
} }
} }
setCreateOverview(); setCreateOverview();
setTopFile(root); setTopFile(root);
if (root instanceof RootDocImpl) { if (root instanceof RootDocImpl) {
((RootDocImpl) root).initDocLint(doclintOpts, tagletManager.getCustomTagNames(), ((RootDocImpl) root).initDocLint(doclintOpts, tagletManager.getCustomTagNames(),
StringUtils.toLowerCase(htmlVersion.name())); 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 * Returns the "length" of a given option. If an option takes no
* arguments, its length is one. If it takes one argument, it's * arguments, its length is one. If it takes one argument, it's
@ -366,7 +397,8 @@ public class ConfigurationImpl extends Configuration {
option.equals("-html5") || option.equals("-html5") ||
option.equals("-xdoclint") || option.equals("-xdoclint") ||
option.startsWith("-xdoclint:") || option.startsWith("-xdoclint:") ||
option.startsWith("-xdoclint/package:")) { option.startsWith("-xdoclint/package:") ||
option.startsWith("--allow-script-in-comments")) {
return 1; return 1;
} else if (option.equals("-help")) { } else if (option.equals("-help")) {
// Uugh: first, this should not be hidden inside optionLength, // Uugh: first, this should not be hidden inside optionLength,
@ -666,4 +698,13 @@ public class ConfigurationImpl extends Configuration {
} }
tagSearchIndexKeys = tagSearchIndexMap.keySet(); 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;
}
} }

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

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

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

@ -145,7 +145,14 @@ public abstract class AbstractBuilder {
configuration.root.printError("Unknown element: " + component); configuration.root.printError("Unknown element: " + component);
throw new DocletAbortException(e); throw new DocletAbortException(e);
} catch (InvocationTargetException 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) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
configuration.root.printError("Exception " + configuration.root.printError("Exception " +

@ -29,6 +29,8 @@ doclet.Encoding_not_supported=Encoding not supported: {0}
doclet.Building_Tree=Building tree for all the packages and classes... doclet.Building_Tree=Building tree for all the packages and classes...
doclet.Building_Index=Building index 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.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.sourcetab_warning=The argument for -sourcetab must be an integer greater than 0.
doclet.Packages=Packages doclet.Packages=Packages
doclet.Other_Packages=Other Packages doclet.Other_Packages=Other Packages

@ -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() { }
}

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -97,7 +97,7 @@ public class DocEnv {
final Enter enter; final Enter enter;
/** The name table. */ /** The name table. */
private Names names; private final Names names;
/** The encoding name. */ /** The encoding name. */
private String encoding; private String encoding;
@ -120,6 +120,7 @@ public class DocEnv {
JavaFileManager fileManager; JavaFileManager fileManager;
Context context; Context context;
DocLint doclint; DocLint doclint;
JavaScriptScanner javaScriptScanner;
WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>(); WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
@ -858,6 +859,15 @@ public class DocEnv {
doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false); 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() { boolean showTagMessages() {
return (doclint == null); return (doclint == null);
} }

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,8 @@ import javax.tools.FileObject;
import com.sun.javadoc.*; import com.sun.javadoc.*;
import com.sun.source.util.TreePath; 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;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Position; import com.sun.tools.javac.util.Position;
@ -128,6 +130,15 @@ public abstract class DocImpl implements Doc, Comparable<Object> {
Comment comment() { Comment comment() {
if (comment == null) { if (comment == null) {
String d = documentation(); 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 if (env.doclint != null
&& treePath != null && treePath != null
&& env.shouldCheck(treePath.getCompilationUnit()) && env.shouldCheck(treePath.getCompilationUnit())

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.code.Kinds.Kind.*; 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 * Javadoc's own enter phase does a few things above and beyond that
@ -65,16 +66,19 @@ public class JavadocEnter extends Enter {
super(context); super(context);
messager = Messager.instance0(context); messager = Messager.instance0(context);
docenv = DocEnv.instance(context); docenv = DocEnv.instance(context);
compiler = JavaCompiler.instance(context);
} }
final Messager messager; final Messager messager;
final DocEnv docenv; final DocEnv docenv;
final JavaCompiler compiler;
@Override @Override
public void main(List<JCCompilationUnit> trees) { public void main(List<JCCompilationUnit> trees) {
// count all Enter errors as warnings. // count all Enter errors as warnings.
int nerrors = messager.nerrors; int nerrors = messager.nerrors;
super.main(trees); super.main(trees);
compiler.enterDone();
messager.nwarnings += (messager.nerrors - nerrors); messager.nwarnings += (messager.nerrors - nerrors);
messager.nerrors = nerrors; messager.nerrors = nerrors;
} }

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -219,7 +219,6 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
// Enter symbols for all files // Enter symbols for all files
docenv.notice("main.Building_tree"); docenv.notice("main.Building_tree");
javadocEnter.main(classTrees.toList().appendList(packageTrees.toList())); javadocEnter.main(classTrees.toList().appendList(packageTrees.toList()));
enterDone = true;
} catch (Abort ex) {} } catch (Abort ex) {}
if (messager.nerrors() != 0) if (messager.nerrors() != 0)

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -383,6 +383,10 @@ public class RootDocImpl extends DocImpl implements RootDoc {
env.initDoclint(opts, customTagNames, htmlVersion); env.initDoclint(opts, customTagNames, htmlVersion);
} }
public JavaScriptScanner initJavaScriptScanner(boolean allowScriptInComments) {
return env.initJavaScriptScanner(allowScriptInComments);
}
public boolean isFunctionalInterface(AnnotationDesc annotationDesc) { public boolean isFunctionalInterface(AnnotationDesc annotationDesc) {
return env.source.allowLambda() return env.source.allowLambda()
&& annotationDesc.annotationType().qualifiedName().equals( && annotationDesc.annotationType().qualifiedName().equals(

@ -145,6 +145,8 @@ javadoc.File_Read_Error=Error while reading file {0}
javadoc.Body_missing_from_html_file=Body tag missing from HTML file javadoc.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.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.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.class_not_found=Class {0} not found.
javadoc.error=error javadoc.error=error
javadoc.warning=warning javadoc.warning=warning

@ -296,9 +296,21 @@ public class ConfigurationImpl extends Configuration {
return false; 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; return true;
} }
@Override @Override
public boolean finishOptionSettings() { public boolean finishOptionSettings() {
if (!validateOptions()) { if (!validateOptions()) {

@ -363,6 +363,9 @@ doclet.usage.frames.description=\
doclet.usage.no-frames.description=\ doclet.usage.no-frames.description=\
Disable the use of frames in the generated output 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=\ doclet.usage.xdocrootparent.parameters=\
<url> <url>
doclet.usage.xdocrootparent.description=\ doclet.usage.xdocrootparent.description=\

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

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,21 @@
package jdk.javadoc.internal.doclets.toolkit; 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.DocCommentTree;
import com.sun.source.doctree.DocTree; import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.IdentifierTree; import com.sun.source.doctree.IdentifierTree;
@ -43,17 +58,8 @@ import com.sun.source.util.DocTreeFactory;
import com.sun.source.util.DocTreePath; import com.sun.source.util.DocTreePath;
import com.sun.source.util.DocTrees; import com.sun.source.util.DocTrees;
import com.sun.source.util.TreePath; import com.sun.source.util.TreePath;
import java.util.ArrayList; import com.sun.tools.javac.util.DefinedBy;
import java.util.HashMap; import com.sun.tools.javac.util.DefinedBy.Api;
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 jdk.javadoc.internal.doclets.toolkit.util.Utils; import jdk.javadoc.internal.doclets.toolkit.util.Utils;
public class CommentUtils { public class CommentUtils {
@ -168,10 +174,18 @@ public class CommentUtils {
*/ */
public DocCommentDuo getHtmlCommentDuo(Element e) { public DocCommentDuo getHtmlCommentDuo(Element e) {
FileObject fo = null; FileObject fo = null;
if (e.getKind().equals(ElementKind.OTHER)) { PackageElement pe = null;
fo = configuration.getOverviewPath(); switch (e.getKind()) {
} else if (e.getKind().equals(ElementKind.PACKAGE)) { case OTHER:
fo = configuration.workArounds.getJavaFileObject((PackageElement)e); 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) { if (fo == null) {
return null; return null;
@ -181,10 +195,20 @@ public class CommentUtils {
if (dcTree == null) { if (dcTree == null) {
return null; return null;
} }
DocTreePath treePath = trees.getDocTreePath(fo); DocTreePath treePath = trees.getDocTreePath(fo, pe);
return new DocCommentDuo(treePath.getTreePath(), dcTree); 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, public void setDocCommentTree(Element element, List<DocTree> fullBody,
List<DocTree> blockTags, Utils utils) { List<DocTree> blockTags, Utils utils) {
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, blockTags); DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, blockTags);

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

@ -44,6 +44,7 @@ import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement; import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import javax.tools.FileObject;
import javax.tools.JavaFileManager.Location; import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
@ -59,7 +60,9 @@ import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol; 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.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.model.JavacElements;
@ -192,11 +195,24 @@ public class WorkArounds {
return ((VarSymbol)ve).getConstValue(); 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() { public Map<Element, TreePath> getElementToTreePath() {
return toolEnv.elementToTreePath; 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. // TODO: needs to ported to jx.l.m.
public TypeElement searchClass(TypeElement klass, String className) { public TypeElement searchClass(TypeElement klass, String className) {
// search by qualified name first // search by qualified name first
@ -530,12 +546,6 @@ public class WorkArounds {
} }
} }
// TODO: this is a fast way to get the JavaFileObject for
// a package.html file, however we need to eliminate this.
public JavaFileObject getJavaFileObject(PackageElement pe) {
return toolEnv.pkgToJavaFOMap.get(pe);
}
// TODO: we need to eliminate this, as it is hacky. // TODO: we need to eliminate this, as it is hacky.
/** /**
* Returns a representation of the package truncated to two levels. * Returns a representation of the package truncated to two levels.

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

@ -42,6 +42,10 @@ doclet.Building_Tree=Building tree for all the packages and classes...
doclet.Building_Index=Building index for all the packages and classes... doclet.Building_Index=Building index for all the packages and classes...
doclet.Building_Index_For_All_Classes=Building index for all 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.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.Packages=Packages
doclet.Modules=Modules doclet.Modules=Modules
doclet.Other_Packages=Other Packages doclet.Other_Packages=Other Packages

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

@ -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;
}
}

@ -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();
}
}

@ -27,6 +27,7 @@ package jdk.javadoc.internal.doclets.toolkit.util;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.net.URI;
import java.text.CollationKey; import java.text.CollationKey;
import java.text.Collator; import java.text.Collator;
import java.util.*; import java.util.*;
@ -108,6 +109,7 @@ public class Utils {
public final DocTrees docTrees; public final DocTrees docTrees;
public final Elements elementUtils; public final Elements elementUtils;
public final Types typeUtils; public final Types typeUtils;
public final JavaScriptScanner javaScriptScanner;
public Utils(Configuration c) { public Utils(Configuration c) {
configuration = c; configuration = c;
@ -115,6 +117,7 @@ public class Utils {
elementUtils = c.docEnv.getElementUtils(); elementUtils = c.docEnv.getElementUtils();
typeUtils = c.docEnv.getTypeUtils(); typeUtils = c.docEnv.getTypeUtils();
docTrees = c.docEnv.getDocTrees(); docTrees = c.docEnv.getDocTrees();
javaScriptScanner = c.isAllowScriptInComments() ? null : new JavaScriptScanner();
} }
// our own little symbol table // our own little symbol table
@ -3025,6 +3028,16 @@ public class Utils {
TreePath path = isValidDuo(duo) ? duo.treePath : null; TreePath path = isValidDuo(duo) ? duo.treePath : null;
if (!dcTreeCache.containsKey(element)) { if (!dcTreeCache.containsKey(element)) {
if (docCommentTree != null && path != null) { 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); configuration.workArounds.runDocLint(path);
} }
dcTreeCache.put(element, duo); dcTreeCache.put(element, duo);
@ -3044,6 +3057,21 @@ public class Utils {
return null; 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) { boolean isValidDuo(DocCommentDuo duo) {
return duo != null && duo.dcTree != null; return duo != null && duo.dcTree != null;
} }

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,14 +39,12 @@ import java.util.Set;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind; import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
import javax.lang.model.element.ModuleElement; import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.ModuleElement.ExportsDirective; import javax.lang.model.element.ModuleElement.ExportsDirective;
import javax.lang.model.element.ModuleElement.RequiresDirective; import javax.lang.model.element.ModuleElement.RequiresDirective;
import javax.lang.model.element.PackageElement; import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter; import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleElementVisitor9; import javax.lang.model.util.SimpleElementVisitor9;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
@ -54,15 +52,12 @@ import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.StandardLocation; 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.Kinds.Kind;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.CompletionFailure; 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.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol; 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.code.Symtab;
import com.sun.tools.javac.comp.Modules; import com.sun.tools.javac.comp.Modules;
import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCClassDecl;
@ -75,9 +70,11 @@ import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.DocletEnvironment.ModuleMode; import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; 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.Main.Result.*;
import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName; import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
/** /**
* This class manages elements specified on the command line, and * This class manages elements specified on the command line, and
* produces "specified" and "included" data sets, needed by the * produces "specified" and "included" data sets, needed by the
@ -864,7 +861,7 @@ public class ElementsTable {
} }
private boolean isTypeElementSelected(TypeElement te) { 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; SimpleElementVisitor9<Boolean, Void> visibleElementVisitor = null;

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

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.code.Kinds.Kind.*; 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 * Javadoc's own enter phase does a few things above and beyond that
@ -64,16 +65,19 @@ public class JavadocEnter extends Enter {
super(context); super(context);
messager = Messager.instance0(context); messager = Messager.instance0(context);
toolEnv = ToolEnvironment.instance(context); toolEnv = ToolEnvironment.instance(context);
compiler = JavaCompiler.instance(context);
} }
final Messager messager; final Messager messager;
final ToolEnvironment toolEnv; final ToolEnvironment toolEnv;
final JavaCompiler compiler;
@Override @Override
public void main(List<JCCompilationUnit> trees) { public void main(List<JCCompilationUnit> trees) {
// count all Enter errors as warnings. // count all Enter errors as warnings.
int nerrors = messager.nerrors; int nerrors = messager.nerrors;
super.main(trees); super.main(trees);
compiler.enterDone();
messager.nwarnings += (messager.nerrors - nerrors); messager.nwarnings += (messager.nerrors - nerrors);
messager.nerrors = nerrors; messager.nerrors = nerrors;
} }

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -202,7 +202,6 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
javadocEnter.main(classTrees.toList().appendList(packageTrees)); javadocEnter.main(classTrees.toList().appendList(packageTrees));
etable.setClassDeclList(listClasses(classTrees.toList())); etable.setClassDeclList(listClasses(classTrees.toList()));
enterDone = true;
etable.analyze(); etable.analyze();
} catch (CompletionFailure cf) { } catch (CompletionFailure cf) {
throw new ToolException(ABNORMAL, cf.getMessage(), cf); throw new ToolException(ABNORMAL, cf.getMessage(), cf);

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

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,6 @@ package jdk.javadoc.internal.tool;
import java.util.*; import java.util.*;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
@ -116,8 +115,6 @@ public class ToolEnvironment {
WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>(); WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
public final HashMap<PackageElement, JavaFileObject> pkgToJavaFOMap = new HashMap<>();
/** Allow documenting from class files? */ /** Allow documenting from class files? */
boolean docClasses = false; boolean docClasses = false;
@ -193,21 +190,11 @@ public class ToolEnvironment {
elementToTreePath.put(e, tree); 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) { public Kind getFileKind(TypeElement te) {
JavaFileObject jfo = ((ClassSymbol)te).outermostClass().classfile; JavaFileObject jfo = ((ClassSymbol)te).outermostClass().classfile;
return jfo == null ? Kind.SOURCE : jfo.getKind(); return jfo == null ? Kind.SOURCE : jfo.getKind();
} }
/** /**
* Print a notice, iff <em>quiet</em> is not specified. * Print a notice, iff <em>quiet</em> is not specified.
* *

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -50,7 +50,7 @@ public class ModuleResolution_attribute extends Attribute {
public ModuleResolution_attribute(ConstantPool constant_pool, public ModuleResolution_attribute(ConstantPool constant_pool,
int resolution_flags) int resolution_flags)
throws ConstantPoolException { throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.ModulePackages), this(constant_pool.getUTF8Index(Attribute.ModuleResolution),
resolution_flags); resolution_flags);
} }

@ -128,9 +128,8 @@ import static jdk.internal.jshell.tool.ContinuousCompletionProvider.STARTSWITH_M
*/ */
public class JShellTool implements MessageHandler { 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 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 RB_NAME_PREFIX = "jdk.internal.jshell.tool.resources";
private static final String VERSION_RB_NAME = RB_NAME_PREFIX + ".version"; private static final String VERSION_RB_NAME = RB_NAME_PREFIX + ".version";
private static final String L10N_RB_NAME = RB_NAME_PREFIX + ".l10n"; private static final String L10N_RB_NAME = RB_NAME_PREFIX + ".l10n";
@ -199,7 +198,7 @@ public class JShellTool implements MessageHandler {
private boolean debug = false; private boolean debug = false;
public boolean testPrompt = false; public boolean testPrompt = false;
private String defaultStartup = null; private String defaultStartup = null;
private String startup = null; private Startup startup = null;
private String executionControlSpec = null; private String executionControlSpec = null;
private EditorSetting editor = BUILT_IN_EDITOR; private EditorSetting editor = BUILT_IN_EDITOR;
@ -216,7 +215,6 @@ public class JShellTool implements MessageHandler {
static final String MODE_KEY = "MODE"; static final String MODE_KEY = "MODE";
static final String REPLAY_RESTORE_KEY = "REPLAY_RESTORE"; 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 Pattern BUILTIN_FILE_PATTERN = Pattern.compile("\\w+");
static final String BUILTIN_FILE_PATH_FORMAT = "/jdk/jshell/tool/resources/%s.jsh"; static final String BUILTIN_FILE_PATH_FORMAT = "/jdk/jshell/tool/resources/%s.jsh";
@ -431,13 +429,13 @@ public class JShellTool implements MessageHandler {
private final OptionSpecBuilder argX = parser.accepts("X"); private final OptionSpecBuilder argX = parser.accepts("X");
private String feedbackMode = null; private String feedbackMode = null;
private String initialStartup = null; private Startup initialStartup = null;
String feedbackMode() { String feedbackMode() {
return feedbackMode; return feedbackMode;
} }
String startup() { Startup startup() {
return initialStartup; return initialStartup;
} }
@ -485,22 +483,15 @@ public class JShellTool implements MessageHandler {
startmsg("jshell.err.opt.startup.conflict"); startmsg("jshell.err.opt.startup.conflict");
return null; return null;
} }
StringBuilder sb = new StringBuilder(); initialStartup = Startup.fromFileList(sts, "--startup", new InitMessageHandler());
for (String fn : sts) {
String s = readFile(fn, "--startup");
if (s == null) {
return null;
}
sb.append(s);
}
initialStartup = sb.toString();
} else if (options.has(argNoStart)) {
initialStartup = "";
} else {
initialStartup = prefs.get(STARTUP_KEY);
if (initialStartup == null) { if (initialStartup == null) {
initialStartup = defaultStartup(); return null;
} }
} else if (options.has(argNoStart)) {
initialStartup = Startup.noStartup();
} else {
String packedStartup = prefs.get(STARTUP_KEY);
initialStartup = Startup.unpack(packedStartup, new InitMessageHandler());
} }
if (options.has(argExecution)) { if (options.has(argExecution)) {
executionControlSpec = options.valueOf(argExecution); executionControlSpec = options.valueOf(argExecution);
@ -639,6 +630,11 @@ public class JShellTool implements MessageHandler {
return ""; return "";
} }
String pp = s.replaceAll("\\R", post + pre); 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; return pre + pp + post;
} }
@ -893,7 +889,7 @@ public class JShellTool implements MessageHandler {
analysis = state.sourceCodeAnalysis(); analysis = state.sourceCodeAnalysis();
live = true; live = true;
startUpRun(startup); startUpRun(startup.toString());
currentNameSpace = mainNamespace; currentNameSpace = mainNamespace;
} }
@ -1077,7 +1073,7 @@ public class JShellTool implements MessageHandler {
.toArray(Command[]::new); .toArray(Command[]::new);
} }
private static Path toPathResolvingUserHome(String pathString) { static Path toPathResolvingUserHome(String pathString) {
if (pathString.replace(File.separatorChar, '/').startsWith("~/")) if (pathString.replace(File.separatorChar, '/').startsWith("~/"))
return Paths.get(System.getProperty("user.home"), pathString.substring(2)); return Paths.get(System.getProperty("user.home"), pathString.substring(2));
else else
@ -1838,48 +1834,43 @@ public class JShellTool implements MessageHandler {
return true; return true;
} }
if (hasFile) { if (hasFile) {
StringBuilder sb = new StringBuilder(); startup = Startup.fromFileList(fns, "/set start", this);
for (String fn : fns) { if (startup == null) {
String s = readFile(fn, "/set start"); return false;
if (s == null) {
return false;
}
sb.append(s);
} }
startup = sb.toString();
} else if (defaultOption) { } else if (defaultOption) {
startup = defaultStartup(); startup = Startup.defaultStartup(this);
} else if (noneOption) { } else if (noneOption) {
startup = ""; startup = Startup.noStartup();
} }
if (retainOption) { if (retainOption) {
// retain startup setting // retain startup setting
prefs.put(STARTUP_KEY, startup); prefs.put(STARTUP_KEY, startup.storedForm());
} }
return true; return true;
} }
// show the "/set start" settings (retained and, if different, current)
// as commands (and file contents). All commands first, then contents.
void showSetStart() { void showSetStart() {
StringBuilder sb = new StringBuilder();
String retained = prefs.get(STARTUP_KEY); String retained = prefs.get(STARTUP_KEY);
if (retained != null) { if (retained != null) {
showSetStart(true, retained); Startup retainedStart = Startup.unpack(retained, this);
} boolean currentDifferent = !startup.equals(retainedStart);
if (retained == null || !startup.equals(retained)) { sb.append(retainedStart.show(true));
showSetStart(false, startup); if (currentDifferent) {
} sb.append(startup.show(false));
} }
sb.append(retainedStart.showDetail());
void showSetStart(boolean isRetained, String start) { if (currentDifferent) {
String cmd = "/set start" + (isRetained ? " -retain " : " "); sb.append(startup.showDetail());
String stset; }
if (start.equals(defaultStartup())) {
stset = cmd + "-default";
} else if (start.isEmpty()) {
stset = cmd + "-none";
} else { } else {
stset = "startup.jsh:\n" + start + "\n" + cmd + "startup.jsh"; sb.append(startup.show(false));
sb.append(startup.showDetail());
} }
hard(stset); hard(sb.toString());
} }
boolean cmdDebug(String arg) { boolean cmdDebug(String arg) {
@ -2200,13 +2191,22 @@ public class JShellTool implements MessageHandler {
case ASSIGNMENT_SUBKIND: case ASSIGNMENT_SUBKIND:
case OTHER_EXPRESSION_SUBKIND: case OTHER_EXPRESSION_SUBKIND:
case TEMP_VAR_EXPRESSION_SUBKIND: case TEMP_VAR_EXPRESSION_SUBKIND:
case STATEMENT_SUBKIND:
case UNKNOWN_SUBKIND: case UNKNOWN_SUBKIND:
if (!src.endsWith(";")) { if (!src.endsWith(";")) {
src = src + ";"; src = src + ";";
} }
srcSet.add(src); srcSet.add(src);
break; 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: default:
srcSet.add(src); srcSet.add(src);
break; break;
@ -2380,38 +2380,7 @@ public class JShellTool implements MessageHandler {
return false; return false;
} }
/** static String getResource(String name) {
* 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) {
if (BUILTIN_FILE_PATTERN.matcher(name).matches()) { if (BUILTIN_FILE_PATTERN.matcher(name).matches()) {
try { try {
return readResource(name); return readResource(name);
@ -2423,33 +2392,16 @@ public class JShellTool implements MessageHandler {
} }
// Read a built-in file from resources // 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 // Attempt to find the file as a resource
String spec = String.format(BUILTIN_FILE_PATH_FORMAT, name); String spec = String.format(BUILTIN_FILE_PATH_FORMAT, name);
try (InputStream in = JShellTool.class.getResourceAsStream(spec); try (InputStream in = JShellTool.class.getResourceAsStream(spec);
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
return reader.lines().collect(Collectors.joining("\n")); 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) { private boolean cmdReset(String rawargs) {
if (!parseCommandLineLikeFlags(rawargs, new OptionParserBase())) { if (!parseCommandLineLikeFlags(rawargs, new OptionParserBase())) {
return false; return false;
@ -2551,7 +2503,7 @@ public class JShellTool implements MessageHandler {
writer.write("\n"); writer.write("\n");
} }
} else if (at.hasOption("-start")) { } else if (at.hasOption("-start")) {
writer.append(startup); writer.append(startup.toString());
} else { } else {
String sources = (at.hasOption("-all") String sources = (at.hasOption("-all")
? state.snippets() ? state.snippets()

@ -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();
}
}

@ -148,6 +148,8 @@ jshell.err.no.such.snippets = No such snippet: {0}
jshell.err.the.snippet.cannot.be.used.with.this.command = This command does not accept the snippet ''{0}'' : {1} jshell.err.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.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.more = <press tab to see more>
jshell.console.see.javadoc = <press shift-tab again to see javadoc> jshell.console.see.javadoc = <press shift-tab again to see javadoc>
jshell.console.see.help = <press shift-tab again to see detailed help> jshell.console.see.help = <press shift-tab again to see detailed help>

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

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

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

@ -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;
}

@ -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();
}
}

@ -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>

@ -24,7 +24,7 @@
/* /*
* @test * @test
* @summary Testing external editor. * @summary Testing external editor.
* @bug 8143955 8080843 8163816 8143006 8169828 * @bug 8143955 8080843 8163816 8143006 8169828 8171130
* @modules jdk.jshell/jdk.internal.jshell.tool * @modules jdk.jshell/jdk.internal.jshell.tool
* @build ReplToolTesting CustomEditor EditorTestBase * @build ReplToolTesting CustomEditor EditorTestBase
* @run testng ExternalEditorTest * @run testng ExternalEditorTest
@ -50,6 +50,7 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail; import static org.testng.Assert.fail;
public class ExternalEditorTest extends EditorTestBase { public class ExternalEditorTest extends EditorTestBase {
@ -119,6 +120,28 @@ public class ExternalEditorTest extends EditorTestBase {
super.testEditor(defaultStartup, args, t); 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() { private static boolean isWindows() {
return System.getProperty("os.name").startsWith("Windows"); return System.getProperty("os.name").startsWith("Windows");
} }

@ -23,7 +23,7 @@
/* /*
* @test * @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 * @summary Tests of jshell comand options, and undoing operations
* @modules jdk.jshell/jdk.internal.jshell.tool * @modules jdk.jshell/jdk.internal.jshell.tool
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
@ -273,14 +273,13 @@ public class ToolCommandOptionTest extends ReplToolTesting {
(a) -> assertCommand(a, "/set start DEFAULT PRINTING", (a) -> assertCommand(a, "/set start DEFAULT PRINTING",
""), ""),
(a) -> assertCommandOutputContains(a, "/set start", (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.toString(),
""), ""),
(a) -> assertCommand(a, "/set start", (a) -> assertCommandOutputContains(a, "/set start",
"| startup.jsh:\n" + "| /set start " + startup + "\n" +
"| int iAmHere = 1234;\n" + "| ---- " + startup + " @ ", " ----\n" +
"| \n" + "| int iAmHere = 1234;\n"),
"| /set start startup.jsh"),
(a) -> assertCommand(a, "/se sta -no", (a) -> assertCommand(a, "/se sta -no",
""), ""),
(a) -> assertCommand(a, "/set start", (a) -> assertCommand(a, "/set start",
@ -322,11 +321,18 @@ public class ToolCommandOptionTest extends ReplToolTesting {
"| /set start -retain -none"), "| /set start -retain -none"),
(a) -> assertCommand(a, "/set start -retain " + startup.toString(), (a) -> assertCommand(a, "/set start -retain " + startup.toString(),
""), ""),
(a) -> assertCommand(a, "/set start", (a) -> assertCommand(a, "/set start DEFAULT PRINTING",
"| startup.jsh:\n" + ""),
"| int iAmHere = 1234;\n" + (a) -> assertCommandOutputStartsWith(a, "/set start",
"| \n" + "| /set start -retain " + startup.toString() + "\n" +
"| /set start -retain startup.jsh") "| /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.*;")
); );
} }

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

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

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

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

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,6 @@ import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPool; import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException; import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Module_attribute; import com.sun.tools.classfile.Module_attribute;
import com.sun.tools.javac.util.Pair;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@ -36,11 +35,11 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -74,20 +73,30 @@ public class ModuleTestBase {
ClassFile classFile = ClassFile.read(modulePath.resolve("module-info.class")); ClassFile classFile = ClassFile.read(modulePath.resolve("module-info.class"));
Module_attribute moduleAttribute = (Module_attribute) classFile.getAttribute("Module"); Module_attribute moduleAttribute = (Module_attribute) classFile.getAttribute("Module");
ConstantPool constantPool = classFile.constant_pool; ConstantPool constantPool = classFile.constant_pool;
testModuleName(moduleDescriptor, moduleAttribute, constantPool);
testModuleFlags(moduleDescriptor, moduleAttribute);
testRequires(moduleDescriptor, moduleAttribute, constantPool); testRequires(moduleDescriptor, moduleAttribute, constantPool);
testExports(moduleDescriptor, moduleAttribute, constantPool); testExports(moduleDescriptor, moduleAttribute, constantPool);
testOpens(moduleDescriptor, moduleAttribute, constantPool);
testProvides(moduleDescriptor, moduleAttribute, constantPool); testProvides(moduleDescriptor, moduleAttribute, constantPool);
testUses(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 { private void testRequires(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
tr.checkEquals(module.requires_count, moduleDescriptor.requires.size(), "Wrong amount of requires."); 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) { for (Module_attribute.RequiresEntry require : module.requires) {
actualRequires.add(Pair.of( actualRequires.add(new Requires(
require.getRequires(constantPool).replace('/', '.'), require.getRequires(constantPool),
require.requires_flags)); require.requires_flags));
} }
tr.checkContains(actualRequires, moduleDescriptor.requires, "Lists of requires don't match"); tr.checkContains(actualRequires, moduleDescriptor.requires, "Lists of requires don't match");
@ -104,18 +113,36 @@ public class ModuleTestBase {
tr.checkEquals(export.exports_to_count, expectedTo.size(), "Wrong amount of exports to"); tr.checkEquals(export.exports_to_count, expectedTo.size(), "Wrong amount of exports to");
List<String> actualTo = new ArrayList<>(); List<String> actualTo = new ArrayList<>();
for (int toIdx : export.exports_to_index) { 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."); 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 { private void testUses(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
tr.checkEquals(module.uses_count, moduleDescriptor.uses.size(), "Wrong amount of uses."); tr.checkEquals(module.uses_count, moduleDescriptor.uses.size(), "Wrong amount of uses.");
List<String> actualUses = new ArrayList<>(); List<String> actualUses = new ArrayList<>();
for (int usesIdx : module.uses_index) { for (int usesIdx : module.uses_index) {
String uses = constantPool.getClassInfo(usesIdx).getBaseName().replace('/', '.'); String uses = constantPool.getClassInfo(usesIdx).getBaseName();
actualUses.add(uses); actualUses.add(uses);
} }
tr.checkContains(actualUses, moduleDescriptor.uses, "Lists of uses don't match"); tr.checkContains(actualUses, moduleDescriptor.uses, "Lists of uses don't match");
@ -131,10 +158,10 @@ public class ModuleTestBase {
tr.checkEquals(moduleProvidesCount, moduleDescriptorProvidesCount, "Wrong amount of provides."); tr.checkEquals(moduleProvidesCount, moduleDescriptorProvidesCount, "Wrong amount of provides.");
Map<String, List<String>> actualProvides = new HashMap<>(); Map<String, List<String>> actualProvides = new HashMap<>();
for (Module_attribute.ProvidesEntry provide : module.provides) { 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<>(); List<String> impls = new ArrayList<>();
for (int i = 0; i < provide.with_count; i++) { 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); impls.add(with);
} }
actualProvides.put(provides, impls); actualProvides.put(provides, impls);
@ -163,9 +190,27 @@ public class ModuleTestBase {
int getMask(); 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 { public enum RequiresFlag implements Mask {
TRANSITIVE("transitive", Module_attribute.ACC_TRANSITIVE), 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 String token;
private final int mask; private final int mask;
@ -181,13 +226,30 @@ public class ModuleTestBase {
} }
} }
public enum ExportFlag implements Mask { public enum ExportsFlag implements Mask {
SYNTHETIC("", Module_attribute.ACC_SYNTHETIC); SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
private final String token; private final String token;
private final int mask; 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.token = token;
this.mask = mask; this.mask = mask;
} }
@ -199,27 +261,64 @@ public class ModuleTestBase {
} }
private class Export { private class Export {
String pkg; private final String pkg;
int mask; private final int mask;
List<String> to = new ArrayList<>(); private final List<String> to = new ArrayList<>();
public Export(String pkg, int mask) { Export(String pkg, int mask) {
this.pkg = pkg; this.pkg = pkg;
this.mask = mask; 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 { protected class ModuleDescriptor {
private final String name; private final String name;
//pair is name of module and flag(public,mandated,synthetic) private final int flags;
private final List<Pair<String, Integer>> requires = new ArrayList<>();
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, Export> exports = new HashMap<>();
private final Map<String, Open> opens = new HashMap<>();
//List of service and implementation //List of service and implementation
private final Map<String, List<String>> provides = new LinkedHashMap<>(); private final Map<String, List<String>> provides = new LinkedHashMap<>();
@ -227,22 +326,26 @@ public class ModuleTestBase {
private static final String LINE_END = ";\n"; 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; 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) { 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); content.append(" requires ").append(module).append(LINE_END);
return this; return this;
} }
public ModuleDescriptor requires(String module, RequiresFlag... flags) { 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 "); content.append(" requires ");
for (RequiresFlag flag : flags) { for (RequiresFlag flag : flags) {
@ -253,26 +356,52 @@ public class ModuleTestBase {
return this; return this;
} }
public ModuleDescriptor exports(String pkg, ExportFlag... flags) { public ModuleDescriptor exports(String pkg, ExportsFlag... flags) {
this.exports.putIfAbsent(pkg, new Export(pkg, computeMask(flags))); this.exports.put(toInternalForm(pkg), new Export(toInternalForm(pkg), computeMask(flags)));
content.append(" exports "); content.append(" exports ");
for (ExportFlag flag : flags) { for (ExportsFlag flag : flags) {
content.append(flag.token).append(" "); content.append(flag.token).append(" ");
} }
content.append(pkg).append(LINE_END); content.append(pkg).append(LINE_END);
return this; 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(",") List<String> tos = Pattern.compile(",")
.splitAsStream(to) .splitAsStream(to)
.map(String::trim) .map(String::trim)
.collect(Collectors.toList()); .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); .to.addAll(tos);
content.append(" exports "); 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(flag.token).append(" ");
} }
content.append(pkg).append(" to ").append(to).append(LINE_END); content.append(pkg).append(" to ").append(to).append(LINE_END);
@ -280,7 +409,10 @@ public class ModuleTestBase {
} }
public ModuleDescriptor provides(String provides, String... with) { 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 ") content.append(" provides ")
.append(provides) .append(provides)
.append(" with ") .append(" with ")
@ -290,8 +422,8 @@ public class ModuleTestBase {
} }
public ModuleDescriptor uses(String... uses) { public ModuleDescriptor uses(String... uses) {
Collections.addAll(this.uses, uses);
for (String use : uses) { for (String use : uses) {
this.uses.add(toInternalForm(use));
content.append(" uses ").append(use).append(LINE_END); content.append(" uses ").append(use).append(LINE_END);
} }
return this; return this;
@ -305,7 +437,11 @@ public class ModuleTestBase {
return this; return this;
} }
private int computeMask(Mask[] masks) { private String toInternalForm(String name) {
return name.replace('.', '/');
}
private int computeMask(Mask... masks) {
return Arrays.stream(masks) return Arrays.stream(masks)
.map(Mask::getMask) .map(Mask::getMask)
.reduce((a, b) -> a | b) .reduce((a, b) -> a | b)

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -82,7 +82,8 @@ public class TestResult extends TestBase {
Set<?> copy = new HashSet<>(expected); Set<?> copy = new HashSet<>(expected);
copy.removeAll(found); copy.removeAll(found);
if (!found.containsAll(expected)) { 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 { } else {
return checkTrue(true, message + " PASS : all elements found"); return checkTrue(true, message + " PASS : all elements found");
} }

@ -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;
}
}

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -66,6 +66,7 @@ class Example implements Comparable<Example> {
modulePathFiles = new ArrayList<File>(); modulePathFiles = new ArrayList<File>();
classPathFiles = new ArrayList<File>(); classPathFiles = new ArrayList<File>();
additionalFiles = new ArrayList<File>(); additionalFiles = new ArrayList<File>();
nonEmptySrcFiles = new ArrayList<File>();
findFiles(file, srcFiles); findFiles(file, srcFiles);
for (File f: srcFiles) { for (File f: srcFiles) {
@ -99,11 +100,11 @@ class Example implements Comparable<Example> {
} }
} }
} else if (f.isFile()) { } else if (f.isFile()) {
if (f.getName().endsWith(".java")) { if (f.getName().endsWith(".java")) {
files.add(f); files.add(f);
} else if (f.getName().equals("modulesourcepath")) { } else if (f.getName().equals("modulesourcepath")) {
moduleSourcePathDir = f; moduleSourcePathDir = f;
} }
} }
} }
@ -132,8 +133,10 @@ class Example implements Comparable<Example> {
foundInfo(f); foundInfo(f);
runOpts = Arrays.asList(runMatch.group(1).trim().split(" +")); runOpts = Arrays.asList(runMatch.group(1).trim().split(" +"));
} }
if (javaPat.matcher(line).matches()) if (javaPat.matcher(line).matches()) {
nonEmptySrcFiles.add(f);
break; break;
}
} }
} catch (IOException e) { } catch (IOException e) {
throw new Error(e); throw new Error(e);
@ -236,6 +239,7 @@ class Example implements Comparable<Example> {
// source for import statements or a magic comment // source for import statements or a magic comment
for (File pf: procFiles) { for (File pf: procFiles) {
if (pf.getName().equals("CreateBadClassFile.java")) { if (pf.getName().equals("CreateBadClassFile.java")) {
pOpts.add("--add-modules=jdk.jdeps");
pOpts.add("--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED"); pOpts.add("--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED");
} }
} }
@ -263,7 +267,9 @@ class Example implements Comparable<Example> {
if (moduleSourcePathDir != null) { if (moduleSourcePathDir != null) {
opts.add("--module-source-path"); opts.add("--module-source-path");
opts.add(moduleSourcePathDir.getPath()); opts.add(moduleSourcePathDir.getPath());
files = moduleSourcePathFiles; files = new ArrayList<>();
files.addAll(moduleSourcePathFiles);
files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
} }
if (additionalFiles.size() > 0) { if (additionalFiles.size() > 0) {
@ -343,6 +349,7 @@ class Example implements Comparable<Example> {
List<File> modulePathFiles; List<File> modulePathFiles;
List<File> classPathFiles; List<File> classPathFiles;
List<File> additionalFiles; List<File> additionalFiles;
List<File> nonEmptySrcFiles;
File infoFile; File infoFile;
private List<String> runOpts; private List<String> runOpts;
private List<String> options; private List<String> options;

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

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 // key: compiler.warn.dir.path.element.not.directory
// options: -Xlint:path // options: -Xlint:path
// run: simple // run: simple
class DirPathElementNotDirectory { }

@ -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

@ -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 { }

@ -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 { }

@ -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 { }

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 // key: compiler.err.unnamed.pkg.not.allowed.named.modules
class UnnamedPackageInNamedModule {}

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