Merge
This commit is contained in:
commit
f0bbed0c96
@ -68,8 +68,8 @@ import javax.lang.model.type.TypeMirror;
|
||||
* javax.lang.model.*} packages bundled in Java SE 8 were required to
|
||||
* also be runnable on Java SE 7. Therefore, default methods
|
||||
* were <em>not</em> used when extending {@code javax.lang.model.*}
|
||||
* to cover Java SE 8 language features. However, default methods may
|
||||
* be used in subsequent revisions of the {@code javax.lang.model.*}
|
||||
* to cover Java SE 8 language features. However, default methods
|
||||
* are used in subsequent revisions of the {@code javax.lang.model.*}
|
||||
* packages that are only required to run on Java SE 8 and higher
|
||||
* platform versions.
|
||||
*
|
||||
@ -90,11 +90,16 @@ public interface AnnotationValueVisitor<R, P> {
|
||||
R visit(AnnotationValue av, P p);
|
||||
|
||||
/**
|
||||
* A convenience method equivalent to {@code v.visit(av, null)}.
|
||||
* A convenience method equivalent to {@code visit(av, null)}.
|
||||
*
|
||||
* @implSpec The default implementation is {@code visit(av, null)}.
|
||||
*
|
||||
* @param av the value to visit
|
||||
* @return a visitor-specified result
|
||||
*/
|
||||
R visit(AnnotationValue av);
|
||||
default R visit(AnnotationValue av) {
|
||||
return visit(av, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a {@code boolean} value in an annotation.
|
||||
|
@ -59,8 +59,8 @@ import javax.lang.model.util.*;
|
||||
* javax.lang.model.*} packages bundled in Java SE 8 were required to
|
||||
* also be runnable on Java SE 7. Therefore, default methods
|
||||
* were <em>not</em> used when extending {@code javax.lang.model.*}
|
||||
* to cover Java SE 8 language features. However, default methods may
|
||||
* be used in subsequent revisions of the {@code javax.lang.model.*}
|
||||
* to cover Java SE 8 language features. However, default methods
|
||||
* are used in subsequent revisions of the {@code javax.lang.model.*}
|
||||
* packages that are only required to run on Java SE 8 and higher
|
||||
* platform versions.
|
||||
*
|
||||
@ -85,11 +85,16 @@ public interface ElementVisitor<R, P> {
|
||||
R visit(Element e, P p);
|
||||
|
||||
/**
|
||||
* A convenience method equivalent to {@code v.visit(e, null)}.
|
||||
* A convenience method equivalent to {@code visit(e, null)}.
|
||||
*
|
||||
* @implSpec The default implementation is {@code visit(e, null)}.
|
||||
*
|
||||
* @param e the element to visit
|
||||
* @return a visitor-specified result
|
||||
*/
|
||||
R visit(Element e);
|
||||
default R visit(Element e) {
|
||||
return visit(e, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a package element.
|
||||
@ -146,10 +151,16 @@ public interface ElementVisitor<R, P> {
|
||||
|
||||
/**
|
||||
* Visits a module element.
|
||||
*
|
||||
* @implSpec Visits a {@code ModuleElement} by calling {@code
|
||||
* visitUnknown(e, p)}.
|
||||
*
|
||||
* @param e the element to visit
|
||||
* @param p a visitor-specified parameter
|
||||
* @return a visitor-specified result
|
||||
* @since 9
|
||||
*/
|
||||
R visitModule(ModuleElement e, P p);
|
||||
default R visitModule(ModuleElement e, P p) {
|
||||
return visitUnknown(e, p);
|
||||
}
|
||||
}
|
||||
|
@ -59,8 +59,8 @@ import javax.lang.model.element.*;
|
||||
* javax.lang.model.*} packages bundled in Java SE 8 were required to
|
||||
* also be runnable on Java SE 7. Therefore, default methods
|
||||
* were <em>not</em> used when extending {@code javax.lang.model.*}
|
||||
* to cover Java SE 8 language features. However, default methods may
|
||||
* be used in subsequent revisions of the {@code javax.lang.model.*}
|
||||
* to cover Java SE 8 language features. However, default methods
|
||||
* are used in subsequent revisions of the {@code javax.lang.model.*}
|
||||
* packages that are only required to run on Java SE 8 and higher
|
||||
* platform versions.
|
||||
*
|
||||
@ -85,11 +85,16 @@ public interface TypeVisitor<R, P> {
|
||||
R visit(TypeMirror t, P p);
|
||||
|
||||
/**
|
||||
* A convenience method equivalent to {@code v.visit(t, null)}.
|
||||
* A convenience method equivalent to {@code visit(t, null)}.
|
||||
*
|
||||
* @implSpec The default implementation is {@code visit(t, null)}.
|
||||
*
|
||||
* @param t the element to visit
|
||||
* @return a visitor-specified result
|
||||
*/
|
||||
R visit(TypeMirror t);
|
||||
default R visit(TypeMirror t) {
|
||||
return visit(t, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a primitive type.
|
||||
|
@ -65,17 +65,17 @@ import javax.annotation.processing.SupportedSourceVersion;
|
||||
* @see AbstractAnnotationValueVisitor8
|
||||
* @see AbstractAnnotationValueVisitor9
|
||||
* @since 1.6
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
@SupportedSourceVersion(RELEASE_6)
|
||||
public abstract class AbstractAnnotationValueVisitor6<R, P>
|
||||
implements AnnotationValueVisitor<R, P> {
|
||||
|
||||
/**
|
||||
* Constructor for concrete subclasses to call.
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected AbstractAnnotationValueVisitor6() {}
|
||||
|
||||
/**
|
||||
|
@ -59,13 +59,13 @@ import javax.annotation.processing.SupportedSourceVersion;
|
||||
* @see AbstractAnnotationValueVisitor9
|
||||
* @since 1.7
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass deprecated
|
||||
@SupportedSourceVersion(RELEASE_7)
|
||||
public abstract class AbstractAnnotationValueVisitor7<R, P> extends AbstractAnnotationValueVisitor6<R, P> {
|
||||
|
||||
/**
|
||||
* Constructor for concrete subclasses to call.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected AbstractAnnotationValueVisitor7() {
|
||||
super();
|
||||
}
|
||||
|
@ -67,15 +67,15 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see AbstractElementVisitor8
|
||||
* @see AbstractElementVisitor9
|
||||
* @since 1.6
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
@SupportedSourceVersion(RELEASE_6)
|
||||
public abstract class AbstractElementVisitor6<R, P> implements ElementVisitor<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses to call.
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected AbstractElementVisitor6(){}
|
||||
|
||||
/**
|
||||
@ -139,6 +139,7 @@ public abstract class AbstractElementVisitor6<R, P> implements ElementVisitor<R,
|
||||
*/
|
||||
@Override
|
||||
public R visitModule(ModuleElement e, P p) {
|
||||
return visitUnknown(e, p);
|
||||
// Use implementation from interface default method
|
||||
return ElementVisitor.super.visitModule(e, p);
|
||||
}
|
||||
}
|
||||
|
@ -63,12 +63,12 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see AbstractElementVisitor9
|
||||
* @since 1.7
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass deprecated
|
||||
@SupportedSourceVersion(RELEASE_7)
|
||||
public abstract class AbstractElementVisitor7<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses to call.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected AbstractElementVisitor7(){
|
||||
super();
|
||||
}
|
||||
|
@ -66,15 +66,15 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see AbstractTypeVisitor8
|
||||
* @see AbstractTypeVisitor9
|
||||
* @since 1.6
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
@SupportedSourceVersion(RELEASE_6)
|
||||
public abstract class AbstractTypeVisitor6<R, P> implements TypeVisitor<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses to call.
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected AbstractTypeVisitor6() {}
|
||||
|
||||
/**
|
||||
|
@ -63,12 +63,12 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see AbstractTypeVisitor9
|
||||
* @since 1.7
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass deprecated
|
||||
@SupportedSourceVersion(RELEASE_7)
|
||||
public abstract class AbstractTypeVisitor7<R, P> extends AbstractTypeVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses to call.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected AbstractTypeVisitor7() {
|
||||
super();
|
||||
}
|
||||
|
@ -81,17 +81,17 @@ import javax.lang.model.SourceVersion;
|
||||
* @see ElementKindVisitor8
|
||||
* @see ElementKindVisitor9
|
||||
* @since 1.6
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
@SupportedSourceVersion(RELEASE_6)
|
||||
public class ElementKindVisitor6<R, P>
|
||||
extends SimpleElementVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses; uses {@code null} for the
|
||||
* default value.
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected ElementKindVisitor6() {
|
||||
super(null);
|
||||
}
|
||||
@ -101,7 +101,10 @@ public class ElementKindVisitor6<R, P>
|
||||
* default value.
|
||||
*
|
||||
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected ElementKindVisitor6(R defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
@ -76,13 +76,13 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see ElementKindVisitor9
|
||||
* @since 1.7
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass deprecated
|
||||
@SupportedSourceVersion(RELEASE_7)
|
||||
public class ElementKindVisitor7<R, P> extends ElementKindVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses; uses {@code null} for the
|
||||
* default value.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected ElementKindVisitor7() {
|
||||
super(null);
|
||||
}
|
||||
@ -93,6 +93,7 @@ public class ElementKindVisitor7<R, P> extends ElementKindVisitor6<R, P> {
|
||||
*
|
||||
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected ElementKindVisitor7(R defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
@ -92,10 +92,7 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see ElementScanner8
|
||||
* @see ElementScanner9
|
||||
* @since 1.6
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
@SupportedSourceVersion(RELEASE_6)
|
||||
public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
/**
|
||||
@ -106,7 +103,10 @@ public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses; uses {@code null} for the
|
||||
* default value.
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected ElementScanner6(){
|
||||
DEFAULT_VALUE = null;
|
||||
}
|
||||
@ -116,7 +116,10 @@ public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
* default value.
|
||||
*
|
||||
* @param defaultValue the default value
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected ElementScanner6(R defaultValue){
|
||||
DEFAULT_VALUE = defaultValue;
|
||||
}
|
||||
|
@ -89,13 +89,13 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see ElementScanner9
|
||||
* @since 1.7
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass deprecated
|
||||
@SupportedSourceVersion(RELEASE_7)
|
||||
public class ElementScanner7<R, P> extends ElementScanner6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses; uses {@code null} for the
|
||||
* default value.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected ElementScanner7(){
|
||||
super(null);
|
||||
}
|
||||
@ -106,6 +106,7 @@ public class ElementScanner7<R, P> extends ElementScanner6<R, P> {
|
||||
*
|
||||
* @param defaultValue the default value
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected ElementScanner7(R defaultValue){
|
||||
super(defaultValue);
|
||||
}
|
||||
|
@ -74,10 +74,7 @@ import javax.annotation.processing.SupportedSourceVersion;
|
||||
* @see SimpleAnnotationValueVisitor8
|
||||
* @see SimpleAnnotationValueVisitor9
|
||||
* @since 1.6
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
@SupportedSourceVersion(RELEASE_6)
|
||||
public class SimpleAnnotationValueVisitor6<R, P>
|
||||
extends AbstractAnnotationValueVisitor6<R, P> {
|
||||
@ -92,7 +89,10 @@ public class SimpleAnnotationValueVisitor6<R, P>
|
||||
/**
|
||||
* Constructor for concrete subclasses; uses {@code null} for the
|
||||
* default value.
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected SimpleAnnotationValueVisitor6() {
|
||||
super();
|
||||
DEFAULT_VALUE = null;
|
||||
@ -103,7 +103,10 @@ public class SimpleAnnotationValueVisitor6<R, P>
|
||||
* default value.
|
||||
*
|
||||
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected SimpleAnnotationValueVisitor6(R defaultValue) {
|
||||
super();
|
||||
DEFAULT_VALUE = defaultValue;
|
||||
|
@ -66,13 +66,13 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see SimpleAnnotationValueVisitor9
|
||||
* @since 1.7
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass deprecated
|
||||
@SupportedSourceVersion(RELEASE_7)
|
||||
public class SimpleAnnotationValueVisitor7<R, P> extends SimpleAnnotationValueVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses; uses {@code null} for the
|
||||
* default value.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected SimpleAnnotationValueVisitor7() {
|
||||
super(null);
|
||||
}
|
||||
@ -83,6 +83,7 @@ public class SimpleAnnotationValueVisitor7<R, P> extends SimpleAnnotationValueVi
|
||||
*
|
||||
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected SimpleAnnotationValueVisitor7(R defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
@ -78,10 +78,7 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see SimpleElementVisitor8
|
||||
* @see SimpleElementVisitor9
|
||||
* @since 1.6
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
@SupportedSourceVersion(RELEASE_6)
|
||||
public class SimpleElementVisitor6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
/**
|
||||
@ -94,7 +91,10 @@ public class SimpleElementVisitor6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses; uses {@code null} for the
|
||||
* default value.
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected SimpleElementVisitor6(){
|
||||
DEFAULT_VALUE = null;
|
||||
}
|
||||
@ -104,7 +104,10 @@ public class SimpleElementVisitor6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
* default value.
|
||||
*
|
||||
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected SimpleElementVisitor6(R defaultValue){
|
||||
DEFAULT_VALUE = defaultValue;
|
||||
}
|
||||
|
@ -72,13 +72,13 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see SimpleElementVisitor9
|
||||
* @since 1.7
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass deprecated
|
||||
@SupportedSourceVersion(RELEASE_7)
|
||||
public class SimpleElementVisitor7<R, P> extends SimpleElementVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses; uses {@code null} for the
|
||||
* default value.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected SimpleElementVisitor7(){
|
||||
super(null);
|
||||
}
|
||||
@ -89,6 +89,7 @@ public class SimpleElementVisitor7<R, P> extends SimpleElementVisitor6<R, P> {
|
||||
*
|
||||
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected SimpleElementVisitor7(R defaultValue){
|
||||
super(defaultValue);
|
||||
}
|
||||
|
@ -78,10 +78,7 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see SimpleTypeVisitor8
|
||||
* @see SimpleTypeVisitor9
|
||||
* @since 1.6
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
@SupportedSourceVersion(RELEASE_6)
|
||||
public class SimpleTypeVisitor6<R, P> extends AbstractTypeVisitor6<R, P> {
|
||||
/**
|
||||
@ -94,7 +91,10 @@ public class SimpleTypeVisitor6<R, P> extends AbstractTypeVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses; uses {@code null} for the
|
||||
* default value.
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected SimpleTypeVisitor6(){
|
||||
DEFAULT_VALUE = null;
|
||||
}
|
||||
@ -104,7 +104,10 @@ public class SimpleTypeVisitor6<R, P> extends AbstractTypeVisitor6<R, P> {
|
||||
* default value.
|
||||
*
|
||||
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected SimpleTypeVisitor6(R defaultValue){
|
||||
DEFAULT_VALUE = defaultValue;
|
||||
}
|
||||
|
@ -72,13 +72,13 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see SimpleTypeVisitor9
|
||||
* @since 1.7
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass deprecated
|
||||
@SupportedSourceVersion(RELEASE_7)
|
||||
public class SimpleTypeVisitor7<R, P> extends SimpleTypeVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses; uses {@code null} for the
|
||||
* default value.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected SimpleTypeVisitor7(){
|
||||
super(null);
|
||||
}
|
||||
@ -89,6 +89,7 @@ public class SimpleTypeVisitor7<R, P> extends SimpleTypeVisitor6<R, P> {
|
||||
*
|
||||
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected SimpleTypeVisitor7(R defaultValue){
|
||||
super(defaultValue);
|
||||
}
|
||||
|
@ -76,16 +76,16 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* @see TypeKindVisitor7
|
||||
* @see TypeKindVisitor8
|
||||
* @since 1.6
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
@SupportedSourceVersion(RELEASE_6)
|
||||
public class TypeKindVisitor6<R, P> extends SimpleTypeVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses to call; uses {@code null}
|
||||
* for the default value.
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected TypeKindVisitor6() {
|
||||
super(null);
|
||||
}
|
||||
@ -96,7 +96,10 @@ public class TypeKindVisitor6<R, P> extends SimpleTypeVisitor6<R, P> {
|
||||
* for the default value.
|
||||
*
|
||||
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
|
||||
* @deprecated Release 6 is obsolete; update to a visitor for a newer
|
||||
* release level.
|
||||
*/
|
||||
@Deprecated
|
||||
protected TypeKindVisitor6(R defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
@ -73,13 +73,13 @@ import javax.lang.model.SourceVersion;
|
||||
* @see TypeKindVisitor8
|
||||
* @since 1.7
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass deprecated
|
||||
@SupportedSourceVersion(RELEASE_7)
|
||||
public class TypeKindVisitor7<R, P> extends TypeKindVisitor6<R, P> {
|
||||
/**
|
||||
* Constructor for concrete subclasses to call; uses {@code null}
|
||||
* for the default value.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected TypeKindVisitor7() {
|
||||
super(null);
|
||||
}
|
||||
@ -90,6 +90,7 @@ public class TypeKindVisitor7<R, P> extends TypeKindVisitor6<R, P> {
|
||||
*
|
||||
* @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Superclass constructor deprecated
|
||||
protected TypeKindVisitor7(R defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public class DocTreePath implements Iterable<DocTree> {
|
||||
* @param t the DocCommentTree to create the path for.
|
||||
*/
|
||||
public DocTreePath(TreePath treePath, DocCommentTree t) {
|
||||
this.treePath = Objects.requireNonNull(treePath);
|
||||
this.treePath = treePath;
|
||||
this.docComment = Objects.requireNonNull(t);
|
||||
this.parent = null;
|
||||
this.leaf = t;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,6 +31,7 @@ import java.util.List;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaCompiler.CompilationTask;
|
||||
@ -127,17 +128,22 @@ public abstract class DocTrees extends Trees {
|
||||
|
||||
/**
|
||||
* Returns a doc tree path containing the doc comment tree of the given file.
|
||||
* The file must be an HTML file, in which case the doc comment tree represents the
|
||||
* contents of the <body> tag, and any enclosing tags are ignored.
|
||||
* The file must be an HTML file, in which case the doc comment tree represents
|
||||
* the contents of the {@code <body>} tag, and any enclosing tags are ignored.
|
||||
* Any references to source code elements contained in {@code @see} and
|
||||
* {@code {@link}} tags in the doc comment tree will be evaluated in the
|
||||
* context of the given package element.
|
||||
* Returns {@code null} if no doc comment was found.
|
||||
* Future releases may support additional file types.
|
||||
*
|
||||
* @param fileObject the content container
|
||||
* @return a doc tree path containing the doc comment read from the given file.
|
||||
* @param fileObject a file object encapsulating the HTML content
|
||||
* @param packageElement a package element to associate with the given file object
|
||||
* representing a legacy package.html, null otherwise
|
||||
* @return a doc tree path containing the doc comment parsed from the given file
|
||||
* @throws IllegalArgumentException if the fileObject is not an HTML file
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
public abstract DocTreePath getDocTreePath(FileObject fileObject);
|
||||
public abstract DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement);
|
||||
|
||||
/**
|
||||
* Returns the language model element referred to by the leaf node of the given
|
||||
|
@ -423,7 +423,16 @@ public class Checker extends DocTreePathScanner<Void, Void> {
|
||||
break;
|
||||
|
||||
case OTHER:
|
||||
env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
|
||||
switch (t) {
|
||||
case SCRIPT:
|
||||
// <script> may or may not be allowed, depending on --allow-script-in-comments
|
||||
// but we allow it here, and rely on a separate scanner to detect all uses
|
||||
// of JavaScript, including <script> tags, and use in attributes, etc.
|
||||
break;
|
||||
|
||||
default:
|
||||
env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -552,15 +561,19 @@ public class Checker extends DocTreePathScanner<Void, Void> {
|
||||
if (!first)
|
||||
env.messages.error(HTML, tree, "dc.attr.repeated", name);
|
||||
}
|
||||
AttrKind k = currTag.getAttrKind(name);
|
||||
switch (env.htmlVersion) {
|
||||
case HTML4:
|
||||
validateHtml4Attrs(tree, name, k);
|
||||
break;
|
||||
// for now, doclint allows all attribute names beginning with "on" as event handler names,
|
||||
// without checking the validity or applicability of the name
|
||||
if (!name.toString().startsWith("on")) {
|
||||
AttrKind k = currTag.getAttrKind(name);
|
||||
switch (env.htmlVersion) {
|
||||
case HTML4:
|
||||
validateHtml4Attrs(tree, name, k);
|
||||
break;
|
||||
|
||||
case HTML5:
|
||||
validateHtml5Attrs(tree, name, k);
|
||||
break;
|
||||
case HTML5:
|
||||
validateHtml5Attrs(tree, name, k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (attr != null) {
|
||||
@ -722,6 +735,9 @@ public class Checker extends DocTreePathScanner<Void, Void> {
|
||||
}
|
||||
|
||||
private void checkURI(AttributeTree tree, String uri) {
|
||||
// allow URIs beginning with javascript:, which would otherwise be rejected by the URI API.
|
||||
if (uri.startsWith("javascript:"))
|
||||
return;
|
||||
try {
|
||||
URI u = new URI(uri);
|
||||
} catch (URISyntaxException e) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -287,7 +287,8 @@ public enum HtmlTag {
|
||||
SAMP(BlockType.INLINE, EndKind.REQUIRED,
|
||||
EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
|
||||
|
||||
SCRIPT(BlockType.OTHER, EndKind.REQUIRED),
|
||||
SCRIPT(BlockType.OTHER, EndKind.REQUIRED,
|
||||
attrs(AttrKind.ALL, SRC)),
|
||||
|
||||
SECTION(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED,
|
||||
EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
|
||||
|
@ -174,7 +174,6 @@ public class JavacTrees extends DocTrees {
|
||||
private JavaFileManager fileManager;
|
||||
private ParserFactory parser;
|
||||
private Symtab syms;
|
||||
private Map<JavaFileObject, PackageSymbol> javaFileObjectToPackageMap;
|
||||
|
||||
// called reflectively from Trees.instance(CompilationTask task)
|
||||
public static JavacTrees instance(JavaCompiler.CompilationTask task) {
|
||||
@ -198,7 +197,6 @@ public class JavacTrees extends DocTrees {
|
||||
}
|
||||
|
||||
protected JavacTrees(Context context) {
|
||||
javaFileObjectToPackageMap = new HashMap<>();
|
||||
this.breakIterator = null;
|
||||
context.put(JavacTrees.class, this);
|
||||
init(context);
|
||||
@ -1039,10 +1037,11 @@ public class JavacTrees extends DocTrees {
|
||||
}
|
||||
|
||||
@Override @DefinedBy(Api.COMPILER_TREE)
|
||||
public DocTreePath getDocTreePath(FileObject fileObject) {
|
||||
public DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement) {
|
||||
JavaFileObject jfo = asJavaFileObject(fileObject);
|
||||
DocCommentTree docCommentTree = getDocCommentTree(jfo);
|
||||
return new DocTreePath(makeTreePath(jfo, docCommentTree), docCommentTree);
|
||||
TreePath treePath = makeTreePath((PackageSymbol)packageElement, jfo, docCommentTree);
|
||||
return new DocTreePath(treePath, docCommentTree);
|
||||
}
|
||||
|
||||
@Override @DefinedBy(Api.COMPILER_TREE)
|
||||
@ -1160,17 +1159,8 @@ public class JavacTrees extends DocTrees {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a file object, such as for a package.html, that provides
|
||||
* doc comments for a package.
|
||||
* @param psym the PackageSymbol representing the package.
|
||||
* @param jfo the JavaFileObject for the given package.
|
||||
*/
|
||||
public void putJavaFileObject(PackageSymbol psym, JavaFileObject jfo) {
|
||||
javaFileObjectToPackageMap.putIfAbsent(jfo, psym);
|
||||
}
|
||||
|
||||
private TreePath makeTreePath(final JavaFileObject jfo, DocCommentTree dcTree) {
|
||||
private TreePath makeTreePath(final PackageSymbol psym, final JavaFileObject jfo,
|
||||
DocCommentTree dcTree) {
|
||||
JCCompilationUnit jcCompilationUnit = new JCCompilationUnit(List.nil()) {
|
||||
public int getPos() {
|
||||
return Position.FIRSTPOS;
|
||||
@ -1191,9 +1181,6 @@ public class JavacTrees extends DocTrees {
|
||||
}
|
||||
};
|
||||
|
||||
PackageSymbol psym = javaFileObjectToPackageMap.getOrDefault(jfo,
|
||||
syms.unnamedModule.unnamedPackage);
|
||||
|
||||
jcCompilationUnit.docComments = new DocCommentTable() {
|
||||
@Override
|
||||
public boolean hasComment(JCTree tree) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1045,7 +1045,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
DO_NOT_RESOLVE_BY_DEFAULT(0x0001),
|
||||
WARN_DEPRECATED(0x0002),
|
||||
WARN_DEPRECATED_REMOVAL(0x0004),
|
||||
WARN_INCUBATOR(0x0008);
|
||||
WARN_INCUBATING(0x0008);
|
||||
|
||||
public static int value(Set<ModuleResolutionFlags> s) {
|
||||
int v = 0;
|
||||
@ -1070,6 +1070,8 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
public Name fullname;
|
||||
public ClassSymbol package_info; // see bug 6443073
|
||||
public ModuleSymbol modle;
|
||||
// the file containing the documentation comments for the package
|
||||
public JavaFileObject sourcefile;
|
||||
|
||||
public PackageSymbol(Name name, Type type, Symbol owner) {
|
||||
super(PCK, 0, name, type, owner);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -818,4 +818,12 @@ public class Symtab {
|
||||
public Collection<ModuleSymbol> getAllModules() {
|
||||
return modules.values();
|
||||
}
|
||||
|
||||
public Iterable<ClassSymbol> getClassesForName(Name candidate) {
|
||||
return classes.getOrDefault(candidate, Collections.emptyMap()).values();
|
||||
}
|
||||
|
||||
public Iterable<PackageSymbol> getPackagesForName(Name candidate) {
|
||||
return packages.getOrDefault(candidate, Collections.emptyMap()).values();
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +118,8 @@ public class Annotate {
|
||||
Source source = Source.instance(context);
|
||||
allowRepeatedAnnos = source.allowRepeatedAnnotations();
|
||||
sourceName = source.name;
|
||||
|
||||
blockCount = 1;
|
||||
}
|
||||
|
||||
/** Semaphore to delay annotation processing */
|
||||
@ -144,6 +146,10 @@ public class Annotate {
|
||||
/** are we blocking annotation processing? */
|
||||
public boolean annotationsBlocked() {return blockCount > 0; }
|
||||
|
||||
public void enterDone() {
|
||||
unblockAnnotations();
|
||||
}
|
||||
|
||||
public List<TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
|
||||
if (annotations.isEmpty()) {
|
||||
return List.nil();
|
||||
@ -1316,4 +1322,8 @@ public class Annotate {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void newRound() {
|
||||
blockCount = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,6 +41,7 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.lang.model.SourceVersion;
|
||||
@ -114,6 +115,7 @@ import static com.sun.tools.javac.code.Flags.UNATTRIBUTED;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.ERR;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.MDL;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.MTH;
|
||||
import com.sun.tools.javac.code.Symbol.ModuleResolutionFlags;
|
||||
import static com.sun.tools.javac.code.TypeTag.CLASS;
|
||||
|
||||
/**
|
||||
@ -374,6 +376,9 @@ public class Modules extends JCTree.Visitor {
|
||||
log.error(decl.qualId, Errors.ModuleNameMismatch(msym.name, name));
|
||||
}
|
||||
} else {
|
||||
if (tree.getPackage() == null) {
|
||||
log.error(tree.pos(), Errors.UnnamedPkgNotAllowedNamedModules);
|
||||
}
|
||||
msym = syms.enterModule(name);
|
||||
}
|
||||
if (msym.sourceLocation == null) {
|
||||
@ -388,7 +393,11 @@ public class Modules extends JCTree.Visitor {
|
||||
} else if (c != null && c.packge().modle == syms.unnamedModule) {
|
||||
tree.modle = syms.unnamedModule;
|
||||
} else {
|
||||
log.error(tree.pos(), Errors.UnnamedPkgNotAllowedNamedModules);
|
||||
if (tree.getModuleDecl() != null) {
|
||||
log.error(tree.pos(), Errors.ModuleNotFoundOnModuleSourcePath);
|
||||
} else {
|
||||
log.error(tree.pos(), Errors.NotInModuleOnModuleSourcePath);
|
||||
}
|
||||
tree.modle = syms.errModule;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@ -457,19 +466,27 @@ public class Modules extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the location for the module on the module source path
|
||||
* or source output directory which contains a given CompilationUnit.
|
||||
* If the source output directory is unset, the class output directory
|
||||
* will be checked instead.
|
||||
* {@code null} is returned if no such module can be found.
|
||||
* @param tree the compilation unit tree
|
||||
* @return the location for the enclosing module
|
||||
* @throws IOException if there is a problem while searching for the module.
|
||||
*/
|
||||
private Location getModuleLocation(JCCompilationUnit tree) throws IOException {
|
||||
Name pkgName;
|
||||
if (tree.getModuleDecl() != null) {
|
||||
return getModuleLocation(tree.sourcefile, null);
|
||||
} else if (tree.getPackage() != null) {
|
||||
JCPackageDecl pkg = tree.getPackage();
|
||||
return getModuleLocation(tree.sourcefile, TreeInfo.fullName(pkg.pid));
|
||||
pkgName = null;
|
||||
} else {
|
||||
// code in unnamed module
|
||||
return null;
|
||||
JCPackageDecl pkg = tree.getPackage();
|
||||
pkgName = (pkg == null) ? names.empty : TreeInfo.fullName(pkg.pid);
|
||||
}
|
||||
}
|
||||
|
||||
private Location getModuleLocation(JavaFileObject fo, Name pkgName) throws IOException {
|
||||
JavaFileObject fo = tree.sourcefile;
|
||||
|
||||
// For now, just check module source path.
|
||||
// We may want to check source path as well.
|
||||
Location loc =
|
||||
@ -482,7 +499,6 @@ public class Modules extends JCTree.Visitor {
|
||||
fileManager.getLocationForModule(sourceOutput,
|
||||
fo, (pkgName == null) ? null : pkgName.toString());
|
||||
}
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
@ -962,7 +978,7 @@ public class Modules extends JCTree.Visitor {
|
||||
|
||||
@Override
|
||||
public void visitRequires(JCRequires tree) {
|
||||
if (tree.directive != null) {
|
||||
if (tree.directive != null && allModules().contains(tree.directive.module)) {
|
||||
chk.checkDeprecated(tree.moduleName.pos(), msym, tree.directive.module);
|
||||
msym.directives = msym.directives.prepend(tree.directive);
|
||||
}
|
||||
@ -1076,6 +1092,10 @@ public class Modules extends JCTree.Visitor {
|
||||
Predicate<ModuleSymbol> observablePred = sym ->
|
||||
(observable == null) ? (moduleFinder.findModule(sym).kind != ERR) : observable.contains(sym);
|
||||
Predicate<ModuleSymbol> systemModulePred = sym -> (sym.flags() & Flags.SYSTEM_MODULE) != 0;
|
||||
Predicate<ModuleSymbol> noIncubatorPred = sym -> {
|
||||
sym.complete();
|
||||
return !sym.resolutionFlags.contains(ModuleResolutionFlags.DO_NOT_RESOLVE_BY_DEFAULT);
|
||||
};
|
||||
Set<ModuleSymbol> enabledRoot = new LinkedHashSet<>();
|
||||
|
||||
if (rootModules.contains(syms.unnamedModule)) {
|
||||
@ -1094,7 +1114,7 @@ public class Modules extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
for (ModuleSymbol sym : new HashSet<>(syms.getAllModules())) {
|
||||
if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym)) {
|
||||
if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym) && noIncubatorPred.test(sym)) {
|
||||
enabledRoot.add(sym);
|
||||
}
|
||||
}
|
||||
@ -1114,14 +1134,14 @@ public class Modules extends JCTree.Visitor {
|
||||
Stream<ModuleSymbol> modules;
|
||||
switch (added) {
|
||||
case ALL_SYSTEM:
|
||||
modules = syms.getAllModules()
|
||||
.stream()
|
||||
.filter(systemModulePred.and(observablePred));
|
||||
modules = new HashSet<>(syms.getAllModules())
|
||||
.stream()
|
||||
.filter(systemModulePred.and(observablePred).and(noIncubatorPred));
|
||||
break;
|
||||
case ALL_MODULE_PATH:
|
||||
modules = syms.getAllModules()
|
||||
.stream()
|
||||
.filter(systemModulePred.negate().and(observablePred));
|
||||
modules = new HashSet<>(syms.getAllModules())
|
||||
.stream()
|
||||
.filter(systemModulePred.negate().and(observablePred));
|
||||
break;
|
||||
default:
|
||||
if (!isValidName(added))
|
||||
@ -1141,6 +1161,15 @@ public class Modules extends JCTree.Visitor {
|
||||
|
||||
result.add(syms.unnamedModule);
|
||||
|
||||
String incubatingModules = result.stream()
|
||||
.filter(msym -> msym.resolutionFlags.contains(ModuleResolutionFlags.WARN_INCUBATING))
|
||||
.map(msym -> msym.name.toString())
|
||||
.collect(Collectors.joining(","));
|
||||
|
||||
if (!incubatingModules.isEmpty()) {
|
||||
log.warning(Warnings.IncubatingModules(incubatingModules));
|
||||
}
|
||||
|
||||
allModules = result;
|
||||
|
||||
//add module versions from options, if any:
|
||||
@ -1234,7 +1263,6 @@ public class Modules extends JCTree.Visitor {
|
||||
msym.requires = msym.requires.appendList(List.from(addReads.getOrDefault(msym, Collections.emptySet())));
|
||||
|
||||
List<RequiresDirective> requires = msym.requires;
|
||||
List<RequiresDirective> previous = null;
|
||||
|
||||
while (requires.nonEmpty()) {
|
||||
if (!allModules().contains(requires.head.module)) {
|
||||
@ -1249,13 +1277,7 @@ public class Modules extends JCTree.Visitor {
|
||||
} else {
|
||||
Assert.check((msym.flags() & Flags.AUTOMATIC_MODULE) == 0);
|
||||
}
|
||||
if (previous != null) {
|
||||
previous.tail = requires.tail;
|
||||
} else {
|
||||
msym.requires.tail = requires.tail;
|
||||
}
|
||||
} else {
|
||||
previous = requires;
|
||||
msym.requires = List.filter(msym.requires, requires.head);
|
||||
}
|
||||
requires = requires.tail;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,6 +41,7 @@ import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
|
||||
import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
|
||||
import com.sun.tools.javac.jvm.*;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
||||
import com.sun.tools.javac.tree.*;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
|
||||
@ -61,12 +62,12 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.lang.model.element.ElementVisitor;
|
||||
|
||||
import com.sun.tools.javac.code.Directive.ExportsDirective;
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.Flags.BLOCK;
|
||||
import static com.sun.tools.javac.code.Flags.STATIC;
|
||||
@ -74,9 +75,8 @@ import static com.sun.tools.javac.code.Kinds.*;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.*;
|
||||
import static com.sun.tools.javac.code.TypeTag.*;
|
||||
import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Errors;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
||||
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
||||
import static com.sun.tools.javac.util.Iterators.createCompoundIterator;
|
||||
|
||||
/** Helper class for name resolution, used mostly by the attribution phase.
|
||||
*
|
||||
@ -1970,7 +1970,7 @@ public class Resolve {
|
||||
* @param env The current environment.
|
||||
* @param name The fully qualified name of the class to be loaded.
|
||||
*/
|
||||
Symbol loadClass(Env<AttrContext> env, Name name) {
|
||||
Symbol loadClass(Env<AttrContext> env, Name name, RecoveryLoadClass recoveryLoadClass) {
|
||||
try {
|
||||
ClassSymbol c = finder.loadClass(env.toplevel.modle, name);
|
||||
return isAccessible(env, c) ? c : new AccessError(env, null, c);
|
||||
@ -1987,40 +1987,60 @@ public class Resolve {
|
||||
}
|
||||
}
|
||||
|
||||
public static interface RecoveryLoadClass {
|
||||
public interface RecoveryLoadClass {
|
||||
Symbol loadClass(Env<AttrContext> env, Name name);
|
||||
}
|
||||
|
||||
private RecoveryLoadClass recoveryLoadClass = new RecoveryLoadClass() {
|
||||
@Override
|
||||
public Symbol loadClass(Env<AttrContext> env, Name name) {
|
||||
if (allowModules) {
|
||||
Scope importScope = env.toplevel.namedImportScope;
|
||||
Symbol existing = importScope.findFirst(Convert.shortName(name),
|
||||
sym -> sym.kind == TYP && sym.flatName() == name);
|
||||
private final RecoveryLoadClass noRecovery = (env, name) -> null;
|
||||
|
||||
if (existing != null) {
|
||||
return new InvisibleSymbolError(env, true, existing);
|
||||
}
|
||||
|
||||
return lookupInvisibleSymbol(env, name, syms::getClass, (ms, n) -> {
|
||||
private final RecoveryLoadClass doRecoveryLoadClass = new RecoveryLoadClass() {
|
||||
@Override public Symbol loadClass(Env<AttrContext> env, Name name) {
|
||||
List<Name> candidates = Convert.classCandidates(name);
|
||||
return lookupInvisibleSymbol(env, name,
|
||||
n -> () -> createCompoundIterator(candidates,
|
||||
c -> syms.getClassesForName(c)
|
||||
.iterator()),
|
||||
(ms, n) -> {
|
||||
for (Name candidate : candidates) {
|
||||
try {
|
||||
return finder.loadClass(ms, n);
|
||||
return finder.loadClass(ms, candidate);
|
||||
} catch (CompletionFailure cf) {
|
||||
//ignore
|
||||
return null;
|
||||
}
|
||||
}, sym -> sym.kind == Kind.TYP, false, typeNotFound);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}, sym -> sym.kind == Kind.TYP, false, typeNotFound);
|
||||
}
|
||||
};
|
||||
|
||||
public RecoveryLoadClass setRecoveryLoadClass(RecoveryLoadClass recovery) {
|
||||
RecoveryLoadClass prev = recoveryLoadClass;
|
||||
recoveryLoadClass = recovery;
|
||||
return prev;
|
||||
}
|
||||
private final RecoveryLoadClass namedImportScopeRecovery = (env, name) -> {
|
||||
Scope importScope = env.toplevel.namedImportScope;
|
||||
Symbol existing = importScope.findFirst(Convert.shortName(name),
|
||||
sym -> sym.kind == TYP && sym.flatName() == name);
|
||||
|
||||
if (existing != null) {
|
||||
return new InvisibleSymbolError(env, true, existing);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
private final RecoveryLoadClass starImportScopeRecovery = (env, name) -> {
|
||||
Scope importScope = env.toplevel.starImportScope;
|
||||
Symbol existing = importScope.findFirst(Convert.shortName(name),
|
||||
sym -> sym.kind == TYP && sym.flatName() == name);
|
||||
|
||||
if (existing != null) {
|
||||
try {
|
||||
existing = finder.loadClass(existing.packge().modle, name);
|
||||
|
||||
return new InvisibleSymbolError(env, true, existing);
|
||||
} catch (CompletionFailure cf) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
Symbol lookupPackage(Env<AttrContext> env, Name name) {
|
||||
PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, name);
|
||||
@ -2034,7 +2054,7 @@ public class Resolve {
|
||||
.stream()
|
||||
.anyMatch(p -> p.fullname.startsWith(nameAndDot));
|
||||
|
||||
return lookupInvisibleSymbol(env, name, syms::getPackage, syms::enterPackage, sym -> {
|
||||
return lookupInvisibleSymbol(env, name, syms::getPackagesForName, syms::enterPackage, sym -> {
|
||||
sym.complete();
|
||||
return sym.exists();
|
||||
}, prefixOfKnown, pack);
|
||||
@ -2059,42 +2079,44 @@ public class Resolve {
|
||||
return TreeInfo.fullName(((JCFieldAccess) qualid).selected) == name;
|
||||
}
|
||||
|
||||
private Symbol lookupInvisibleSymbol(Env<AttrContext> env,
|
||||
Name name,
|
||||
BiFunction<ModuleSymbol, Name, Symbol> get,
|
||||
BiFunction<ModuleSymbol, Name, Symbol> load,
|
||||
Predicate<Symbol> validate,
|
||||
boolean suppressError,
|
||||
Symbol defaultResult) {
|
||||
private <S extends Symbol> Symbol lookupInvisibleSymbol(Env<AttrContext> env,
|
||||
Name name,
|
||||
Function<Name, Iterable<S>> get,
|
||||
BiFunction<ModuleSymbol, Name, S> load,
|
||||
Predicate<S> validate,
|
||||
boolean suppressError,
|
||||
Symbol defaultResult) {
|
||||
//even if a class/package cannot be found in the current module and among packages in modules
|
||||
//it depends on that are exported for any or this module, the class/package may exist internally
|
||||
//in some of these modules, or may exist in a module on which this module does not depend.
|
||||
//Provide better diagnostic in such cases by looking for the class in any module:
|
||||
Iterable<? extends S> candidates = get.apply(name);
|
||||
|
||||
for (S sym : candidates) {
|
||||
if (validate.test(sym))
|
||||
return new InvisibleSymbolError(env, suppressError, sym);
|
||||
}
|
||||
|
||||
Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
|
||||
|
||||
recoverableModules.remove(env.toplevel.modle);
|
||||
|
||||
for (ModuleSymbol ms : recoverableModules) {
|
||||
Symbol sym = get.apply(ms, name);
|
||||
|
||||
//avoid overly eager completing classes from source-based modules, as those
|
||||
//may not be completable with the current compiler settings:
|
||||
if (sym == null && (ms.sourceLocation == null)) {
|
||||
if (ms.sourceLocation == null) {
|
||||
if (ms.classLocation == null) {
|
||||
ms = moduleFinder.findModule(ms);
|
||||
}
|
||||
|
||||
if (ms.kind != ERR) {
|
||||
sym = load.apply(ms, name);
|
||||
S sym = load.apply(ms, name);
|
||||
|
||||
if (sym != null && validate.test(sym)) {
|
||||
return new InvisibleSymbolError(env, suppressError, sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sym == null)
|
||||
continue;
|
||||
|
||||
if (validate.test(sym)) {
|
||||
return new InvisibleSymbolError(env, suppressError, sym);
|
||||
}
|
||||
}
|
||||
|
||||
return defaultResult;
|
||||
@ -2186,10 +2208,10 @@ public class Resolve {
|
||||
* @param scope The scope in which to look for the type.
|
||||
* @param name The type's name.
|
||||
*/
|
||||
Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
|
||||
Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name, RecoveryLoadClass recoveryLoadClass) {
|
||||
Symbol bestSoFar = typeNotFound;
|
||||
for (Symbol s : scope.getSymbolsByName(name)) {
|
||||
Symbol sym = loadClass(env, s.flatName());
|
||||
Symbol sym = loadClass(env, s.flatName(), recoveryLoadClass);
|
||||
if (bestSoFar.kind == TYP && sym.kind == TYP &&
|
||||
bestSoFar != sym)
|
||||
return new AmbiguityError(bestSoFar, sym);
|
||||
@ -2260,15 +2282,15 @@ public class Resolve {
|
||||
}
|
||||
|
||||
if (!env.tree.hasTag(IMPORT)) {
|
||||
sym = findGlobalType(env, env.toplevel.namedImportScope, name);
|
||||
sym = findGlobalType(env, env.toplevel.namedImportScope, name, namedImportScopeRecovery);
|
||||
if (sym.exists()) return sym;
|
||||
else bestSoFar = bestOf(bestSoFar, sym);
|
||||
|
||||
sym = findGlobalType(env, env.toplevel.packge.members(), name);
|
||||
sym = findGlobalType(env, env.toplevel.packge.members(), name, noRecovery);
|
||||
if (sym.exists()) return sym;
|
||||
else bestSoFar = bestOf(bestSoFar, sym);
|
||||
|
||||
sym = findGlobalType(env, env.toplevel.starImportScope, name);
|
||||
sym = findGlobalType(env, env.toplevel.starImportScope, name, starImportScopeRecovery);
|
||||
if (sym.exists()) return sym;
|
||||
else bestSoFar = bestOf(bestSoFar, sym);
|
||||
}
|
||||
@ -2315,7 +2337,11 @@ public class Resolve {
|
||||
Name fullname = TypeSymbol.formFullName(name, pck);
|
||||
Symbol bestSoFar = typeNotFound;
|
||||
if (kind.contains(KindSelector.TYP)) {
|
||||
Symbol sym = loadClass(env, fullname);
|
||||
RecoveryLoadClass recoveryLoadClass =
|
||||
allowModules && !kind.contains(KindSelector.PCK) &&
|
||||
!pck.exists() && !env.info.isSpeculative ?
|
||||
doRecoveryLoadClass : noRecovery;
|
||||
Symbol sym = loadClass(env, fullname, recoveryLoadClass);
|
||||
if (sym.exists()) {
|
||||
// don't allow programs to use flatnames
|
||||
if (name == sym.name) return sym;
|
||||
@ -4136,11 +4162,21 @@ public class Resolve {
|
||||
|
||||
JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
|
||||
|
||||
if (pos.getTree() != null && pos.getTree().hasTag(SELECT) && sym.owner.kind == PCK) {
|
||||
pos = ((JCFieldAccess) pos.getTree()).selected.pos();
|
||||
if (pos.getTree() != null) {
|
||||
Symbol o = sym;
|
||||
JCTree tree = pos.getTree();
|
||||
|
||||
return diags.create(dkind, log.currentSource(),
|
||||
pos, "package.not.visible", sym.packge(), details);
|
||||
while (o.kind != PCK && tree.hasTag(SELECT)) {
|
||||
o = o.owner;
|
||||
tree = ((JCFieldAccess) tree).selected;
|
||||
}
|
||||
|
||||
if (o.kind == PCK) {
|
||||
pos = tree.pos();
|
||||
|
||||
return diags.create(dkind, log.currentSource(),
|
||||
pos, "package.not.visible", o, details);
|
||||
}
|
||||
}
|
||||
|
||||
return diags.create(dkind, log.currentSource(),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -553,7 +553,7 @@ public class Locations {
|
||||
|
||||
@Override
|
||||
Location getLocationForModule(Path dir) {
|
||||
return pathLocations.get(dir);
|
||||
return (pathLocations == null) ? null : pathLocations.get(dir);
|
||||
}
|
||||
|
||||
private boolean listed;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,6 +29,7 @@ import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.file.ClosedFileSystemException;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
@ -2756,8 +2757,8 @@ public class ClassReader {
|
||||
currentModule.provides = List.nil();
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw badClassFile("unable.to.access.file", ex.getMessage());
|
||||
} catch (IOException | ClosedFileSystemException ex) {
|
||||
throw badClassFile("unable.to.access.file", ex.toString());
|
||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||
throw badClassFile("bad.class.file", c.flatname);
|
||||
} finally {
|
||||
|
@ -588,7 +588,9 @@ public class Arguments {
|
||||
checkOptionAllowed(t.compareTo(Target.JDK1_9) >= 0,
|
||||
option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name),
|
||||
Option.MODULE_SOURCE_PATH, Option.UPGRADE_MODULE_PATH,
|
||||
Option.SYSTEM, Option.MODULE_PATH, Option.ADD_MODULES, Option.LIMIT_MODULES,
|
||||
Option.SYSTEM, Option.MODULE_PATH, Option.ADD_MODULES,
|
||||
Option.ADD_EXPORTS, Option.ADD_OPENS, Option.ADD_READS,
|
||||
Option.LIMIT_MODULES,
|
||||
Option.PATCH_MODULE);
|
||||
|
||||
if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -363,7 +363,7 @@ public class JavaCompiler {
|
||||
**/
|
||||
protected boolean implicitSourceFilesRead;
|
||||
|
||||
protected boolean enterDone;
|
||||
private boolean enterDone;
|
||||
|
||||
protected CompileStates compileStates;
|
||||
|
||||
@ -1042,7 +1042,7 @@ public class JavaCompiler {
|
||||
public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
|
||||
modules.initModules(roots);
|
||||
if (roots.isEmpty()) {
|
||||
enterDone = true;
|
||||
enterDone();
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
@ -1063,7 +1063,7 @@ public class JavaCompiler {
|
||||
|
||||
enter.main(roots);
|
||||
|
||||
enterDone = true;
|
||||
enterDone();
|
||||
|
||||
if (!taskListener.isEmpty()) {
|
||||
for (JCCompilationUnit unit: roots) {
|
||||
@ -1725,6 +1725,11 @@ public class JavaCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
public void enterDone() {
|
||||
enterDone = true;
|
||||
annotate.enterDone();
|
||||
}
|
||||
|
||||
public boolean isEnterDone() {
|
||||
return enterDone;
|
||||
}
|
||||
|
@ -184,39 +184,34 @@ public class JavacElements implements Elements {
|
||||
return nameToSymbol(syms.noModule, nameStr, clazz);
|
||||
}
|
||||
|
||||
RecoveryLoadClass prevRecoveryLoadClass = resolve.setRecoveryLoadClass((env, name) -> null);
|
||||
try {
|
||||
Set<S> found = new LinkedHashSet<>();
|
||||
Set<S> found = new LinkedHashSet<>();
|
||||
|
||||
for (ModuleSymbol msym : modules.allModules()) {
|
||||
S sym = nameToSymbol(msym, nameStr, clazz);
|
||||
for (ModuleSymbol msym : modules.allModules()) {
|
||||
S sym = nameToSymbol(msym, nameStr, clazz);
|
||||
|
||||
if (sym != null) {
|
||||
if (!allowModules || clazz == ClassSymbol.class || !sym.members().isEmpty()) {
|
||||
//do not add packages without members:
|
||||
found.add(sym);
|
||||
}
|
||||
if (sym != null) {
|
||||
if (!allowModules || clazz == ClassSymbol.class || !sym.members().isEmpty()) {
|
||||
//do not add packages without members:
|
||||
found.add(sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found.size() == 1) {
|
||||
return found.iterator().next();
|
||||
} else if (found.size() > 1) {
|
||||
//more than one element found, produce a note:
|
||||
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
|
||||
String moduleNames = found.stream()
|
||||
.map(s -> s.packge().modle)
|
||||
.map(m -> m.toString())
|
||||
.collect(Collectors.joining(", "));
|
||||
log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
//not found, or more than one element found:
|
||||
return null;
|
||||
if (found.size() == 1) {
|
||||
return found.iterator().next();
|
||||
} else if (found.size() > 1) {
|
||||
//more than one element found, produce a note:
|
||||
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
|
||||
String moduleNames = found.stream()
|
||||
.map(s -> s.packge().modle)
|
||||
.map(m -> m.toString())
|
||||
.collect(Collectors.joining(", "));
|
||||
log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
|
||||
}
|
||||
} finally {
|
||||
resolve.setRecoveryLoadClass(prevRecoveryLoadClass);
|
||||
return null;
|
||||
} else {
|
||||
//not found, or more than one element found:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,6 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.source.doctree.AttributeTree.ValueKind;
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import com.sun.tools.javac.parser.DocCommentParser.TagParser.Kind;
|
||||
import com.sun.tools.javac.parser.Tokens.Comment;
|
||||
import com.sun.tools.javac.parser.Tokens.TokenKind;
|
||||
|
@ -588,7 +588,7 @@ public class JavacParser implements Parser {
|
||||
/**
|
||||
* Ident = IDENTIFIER
|
||||
*/
|
||||
protected Name ident() {
|
||||
public Name ident() {
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -92,6 +92,7 @@ import com.sun.tools.javac.util.Options;
|
||||
|
||||
import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.*;
|
||||
import com.sun.tools.javac.comp.Annotate;
|
||||
import static com.sun.tools.javac.comp.CompileStates.CompileState;
|
||||
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
|
||||
|
||||
@ -123,6 +124,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
private final JavaCompiler compiler;
|
||||
private final Modules modules;
|
||||
private final Types types;
|
||||
private final Annotate annotate;
|
||||
|
||||
/**
|
||||
* Holds relevant state history of which processors have been
|
||||
@ -219,6 +221,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
typeUtils = JavacTypes.instance(context);
|
||||
modules = Modules.instance(context);
|
||||
types = Types.instance(context);
|
||||
annotate = Annotate.instance(context);
|
||||
processorOptions = initProcessorOptions();
|
||||
unmatchedProcessorOptions = initUnmatchedProcessorOptions();
|
||||
messages = JavacMessages.instance(context);
|
||||
@ -1256,6 +1259,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
compiler.newRound();
|
||||
modules.newRound();
|
||||
types.newRound();
|
||||
annotate.newRound();
|
||||
|
||||
boolean foundError = false;
|
||||
|
||||
|
@ -1535,6 +1535,10 @@ compiler.warn.finally.cannot.complete=\
|
||||
compiler.warn.poor.choice.for.module.name=\
|
||||
module name {0} should avoid terminal digits
|
||||
|
||||
# 0: string
|
||||
compiler.warn.incubating.modules=\
|
||||
using incubating module(s): {0}
|
||||
|
||||
# 0: symbol, 1: symbol
|
||||
compiler.warn.has.been.deprecated=\
|
||||
{0} in {1} has been deprecated
|
||||
@ -2845,6 +2849,12 @@ compiler.warn.module.not.found=\
|
||||
compiler.err.too.many.modules=\
|
||||
too many module declarations found
|
||||
|
||||
compiler.err.module.not.found.on.module.source.path=\
|
||||
module not found on module source path
|
||||
|
||||
compiler.err.not.in.module.on.module.source.path=\
|
||||
not in a module on the module source path
|
||||
|
||||
# 0: symbol
|
||||
compiler.err.duplicate.module=\
|
||||
duplicate module: {0}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -335,4 +335,16 @@ public class Convert {
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
public static List<Name> classCandidates(Name name) {
|
||||
List<Name> names = List.nil();
|
||||
String nameStr = name.toString();
|
||||
int index = -1;
|
||||
while ((index = nameStr.indexOf('.', index + 1)) > 0) {
|
||||
String pack = nameStr.substring(0, index + 1);
|
||||
String clz = nameStr.substring(index + 1).replace('.', '$');
|
||||
names = names.prepend(name.table.names.fromString(pack + clz));
|
||||
}
|
||||
return names.reverse();
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ import com.sun.tools.doclint.DocLint;
|
||||
import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.StringUtils;
|
||||
import com.sun.tools.javadoc.main.JavaScriptScanner;
|
||||
import com.sun.tools.javadoc.main.RootDocImpl;
|
||||
|
||||
/**
|
||||
@ -188,6 +189,11 @@ public class ConfigurationImpl extends Configuration {
|
||||
*/
|
||||
public Set<String> doclintOpts = new LinkedHashSet<>();
|
||||
|
||||
/**
|
||||
* Whether or not to check for JavaScript in doc comments.
|
||||
*/
|
||||
private boolean allowScriptInComments;
|
||||
|
||||
/**
|
||||
* Unique Resource Handler for this package.
|
||||
*/
|
||||
@ -309,8 +315,11 @@ public class ConfigurationImpl extends Configuration {
|
||||
doclintOpts.add(DocLint.XMSGS_CUSTOM_PREFIX + opt.substring(opt.indexOf(":") + 1));
|
||||
} else if (opt.startsWith("-xdoclint/package:")) {
|
||||
doclintOpts.add(DocLint.XCHECK_PACKAGE + opt.substring(opt.indexOf(":") + 1));
|
||||
} else if (opt.equals("--allow-script-in-comments")) {
|
||||
allowScriptInComments = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (root.specifiedClasses().length > 0) {
|
||||
Map<String,PackageDoc> map = new HashMap<>();
|
||||
PackageDoc pd;
|
||||
@ -322,15 +331,37 @@ public class ConfigurationImpl extends Configuration {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setCreateOverview();
|
||||
setTopFile(root);
|
||||
|
||||
if (root instanceof RootDocImpl) {
|
||||
((RootDocImpl) root).initDocLint(doclintOpts, tagletManager.getCustomTagNames(),
|
||||
StringUtils.toLowerCase(htmlVersion.name()));
|
||||
JavaScriptScanner jss = ((RootDocImpl) root).initJavaScriptScanner(isAllowScriptInComments());
|
||||
if (jss != null) {
|
||||
// In a more object-oriented world, this would be done by methods on the Option objects.
|
||||
// Note that -windowtitle silently removes any and all HTML elements, and so does not need
|
||||
// to be handled here.
|
||||
checkJavaScript(jss, "-header", header);
|
||||
checkJavaScript(jss, "-footer", footer);
|
||||
checkJavaScript(jss, "-top", top);
|
||||
checkJavaScript(jss, "-bottom", bottom);
|
||||
checkJavaScript(jss, "-doctitle", doctitle);
|
||||
checkJavaScript(jss, "-packagesheader", packagesheader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkJavaScript(JavaScriptScanner jss, final String opt, String value) {
|
||||
jss.parse(value, new JavaScriptScanner.Reporter() {
|
||||
public void report() {
|
||||
root.printError(getText("doclet.JavaScript_in_option", opt));
|
||||
throw new FatalError();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "length" of a given option. If an option takes no
|
||||
* arguments, its length is one. If it takes one argument, it's
|
||||
@ -366,7 +397,8 @@ public class ConfigurationImpl extends Configuration {
|
||||
option.equals("-html5") ||
|
||||
option.equals("-xdoclint") ||
|
||||
option.startsWith("-xdoclint:") ||
|
||||
option.startsWith("-xdoclint/package:")) {
|
||||
option.startsWith("-xdoclint/package:") ||
|
||||
option.startsWith("--allow-script-in-comments")) {
|
||||
return 1;
|
||||
} else if (option.equals("-help")) {
|
||||
// Uugh: first, this should not be hidden inside optionLength,
|
||||
@ -666,4 +698,13 @@ public class ConfigurationImpl extends Configuration {
|
||||
}
|
||||
tagSearchIndexKeys = tagSearchIndexMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not to allow JavaScript in comments.
|
||||
* Default is off; can be set true from a command line option.
|
||||
* @return the allowScriptInComments
|
||||
*/
|
||||
public boolean isAllowScriptInComments() {
|
||||
return allowScriptInComments;
|
||||
}
|
||||
}
|
||||
|
@ -237,6 +237,8 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new DocletAbortException(e);
|
||||
} catch (FatalError fe) {
|
||||
throw fe;
|
||||
} catch (DocletAbortException de) {
|
||||
de.printStackTrace();
|
||||
throw de;
|
||||
|
@ -148,7 +148,9 @@ public class HtmlWriter {
|
||||
|
||||
public final Content descfrmInterfaceLabel;
|
||||
|
||||
private final Writer writer;
|
||||
private final DocFile file;
|
||||
|
||||
private Writer writer;
|
||||
|
||||
protected Content script;
|
||||
|
||||
@ -164,7 +166,7 @@ public class HtmlWriter {
|
||||
*/
|
||||
public HtmlWriter(Configuration configuration, DocPath path)
|
||||
throws IOException, UnsupportedEncodingException {
|
||||
writer = DocFile.createFileForOutput(configuration, path).openWriter();
|
||||
file = DocFile.createFileForOutput(configuration, path);
|
||||
this.configuration = configuration;
|
||||
this.memberDetailsListPrinted = false;
|
||||
packageTableHeader = new String[] {
|
||||
@ -214,6 +216,7 @@ public class HtmlWriter {
|
||||
}
|
||||
|
||||
public void write(Content c) throws IOException {
|
||||
writer = file.openWriter();
|
||||
c.write(writer, true);
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,8 @@ public abstract class AbstractDoclet {
|
||||
} catch (Configuration.Fault f) {
|
||||
root.printError(f.getMessage());
|
||||
return false;
|
||||
} catch (FatalError fe) {
|
||||
return false;
|
||||
} catch (DocletAbortException e) {
|
||||
e.printStackTrace();
|
||||
Throwable cause = e.getCause();
|
||||
|
@ -145,7 +145,14 @@ public abstract class AbstractBuilder {
|
||||
configuration.root.printError("Unknown element: " + component);
|
||||
throw new DocletAbortException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new DocletAbortException(e.getCause());
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof FatalError) {
|
||||
throw (FatalError) cause;
|
||||
} else if (cause instanceof DocletAbortException) {
|
||||
throw (DocletAbortException) cause;
|
||||
} else {
|
||||
throw new DocletAbortException(cause);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
configuration.root.printError("Exception " +
|
||||
|
@ -29,6 +29,8 @@ doclet.Encoding_not_supported=Encoding not supported: {0}
|
||||
doclet.Building_Tree=Building tree for all the packages and classes...
|
||||
doclet.Building_Index=Building index for all the packages and classes...
|
||||
doclet.Building_Index_For_All_Classes=Building index for all classes...
|
||||
doclet.JavaScript_in_option=Argument for {0} contains JavaScript.\n\
|
||||
Use --allow-script-in-comments to allow use of JavaScript.
|
||||
doclet.sourcetab_warning=The argument for -sourcetab must be an integer greater than 0.
|
||||
doclet.Packages=Packages
|
||||
doclet.Other_Packages=Other Packages
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -97,7 +97,7 @@ public class DocEnv {
|
||||
final Enter enter;
|
||||
|
||||
/** The name table. */
|
||||
private Names names;
|
||||
private final Names names;
|
||||
|
||||
/** The encoding name. */
|
||||
private String encoding;
|
||||
@ -120,6 +120,7 @@ public class DocEnv {
|
||||
JavaFileManager fileManager;
|
||||
Context context;
|
||||
DocLint doclint;
|
||||
JavaScriptScanner javaScriptScanner;
|
||||
|
||||
WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
|
||||
|
||||
@ -858,6 +859,15 @@ public class DocEnv {
|
||||
doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false);
|
||||
}
|
||||
|
||||
JavaScriptScanner initJavaScriptScanner(boolean allowScriptInComments) {
|
||||
if (allowScriptInComments) {
|
||||
javaScriptScanner = null;
|
||||
} else {
|
||||
javaScriptScanner = new JavaScriptScanner();
|
||||
}
|
||||
return javaScriptScanner;
|
||||
}
|
||||
|
||||
boolean showTagMessages() {
|
||||
return (doclint == null);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,6 +36,8 @@ import javax.tools.FileObject;
|
||||
|
||||
import com.sun.javadoc.*;
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.tools.doclets.internal.toolkit.util.DocletAbortException;
|
||||
import com.sun.tools.doclets.internal.toolkit.util.FatalError;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
import com.sun.tools.javac.util.Position;
|
||||
@ -128,6 +130,15 @@ public abstract class DocImpl implements Doc, Comparable<Object> {
|
||||
Comment comment() {
|
||||
if (comment == null) {
|
||||
String d = documentation();
|
||||
if (env.javaScriptScanner != null) {
|
||||
env.javaScriptScanner.parse(d, new JavaScriptScanner.Reporter() {
|
||||
@Override
|
||||
public void report() {
|
||||
env.error(DocImpl.this, "javadoc.JavaScript_in_comment");
|
||||
throw new FatalError();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (env.doclint != null
|
||||
&& treePath != null
|
||||
&& env.shouldCheck(treePath.getCompilationUnit())
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,6 +36,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.*;
|
||||
import com.sun.tools.javac.main.JavaCompiler;
|
||||
|
||||
/**
|
||||
* Javadoc's own enter phase does a few things above and beyond that
|
||||
@ -65,16 +66,19 @@ public class JavadocEnter extends Enter {
|
||||
super(context);
|
||||
messager = Messager.instance0(context);
|
||||
docenv = DocEnv.instance(context);
|
||||
compiler = JavaCompiler.instance(context);
|
||||
}
|
||||
|
||||
final Messager messager;
|
||||
final DocEnv docenv;
|
||||
final JavaCompiler compiler;
|
||||
|
||||
@Override
|
||||
public void main(List<JCCompilationUnit> trees) {
|
||||
// count all Enter errors as warnings.
|
||||
int nerrors = messager.nerrors;
|
||||
super.main(trees);
|
||||
compiler.enterDone();
|
||||
messager.nwarnings += (messager.nerrors - nerrors);
|
||||
messager.nerrors = nerrors;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -219,7 +219,6 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
|
||||
// Enter symbols for all files
|
||||
docenv.notice("main.Building_tree");
|
||||
javadocEnter.main(classTrees.toList().appendList(packageTrees.toList()));
|
||||
enterDone = true;
|
||||
} catch (Abort ex) {}
|
||||
|
||||
if (messager.nerrors() != 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -383,6 +383,10 @@ public class RootDocImpl extends DocImpl implements RootDoc {
|
||||
env.initDoclint(opts, customTagNames, htmlVersion);
|
||||
}
|
||||
|
||||
public JavaScriptScanner initJavaScriptScanner(boolean allowScriptInComments) {
|
||||
return env.initJavaScriptScanner(allowScriptInComments);
|
||||
}
|
||||
|
||||
public boolean isFunctionalInterface(AnnotationDesc annotationDesc) {
|
||||
return env.source.allowLambda()
|
||||
&& annotationDesc.annotationType().qualifiedName().equals(
|
||||
|
@ -145,6 +145,8 @@ javadoc.File_Read_Error=Error while reading file {0}
|
||||
javadoc.Body_missing_from_html_file=Body tag missing from HTML file
|
||||
javadoc.End_body_missing_from_html_file=Close body tag missing from HTML file
|
||||
javadoc.Multiple_package_comments=Multiple sources of package comments found for package "{0}"
|
||||
javadoc.JavaScript_in_comment=JavaScript found in documentation comment.\n\
|
||||
Use --allow-script-in-comments to allow use of JavaScript.
|
||||
javadoc.class_not_found=Class {0} not found.
|
||||
javadoc.error=error
|
||||
javadoc.warning=warning
|
||||
|
@ -296,9 +296,21 @@ public class ConfigurationImpl extends Configuration {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// In a more object-oriented world, this would be done by methods on the Option objects.
|
||||
// Note that -windowtitle silently removes any and all HTML elements, and so does not need
|
||||
// to be handled here.
|
||||
utils.checkJavaScriptInOption("-header", header);
|
||||
utils.checkJavaScriptInOption("-footer", footer);
|
||||
utils.checkJavaScriptInOption("-top", top);
|
||||
utils.checkJavaScriptInOption("-bottom", bottom);
|
||||
utils.checkJavaScriptInOption("-doctitle", doctitle);
|
||||
utils.checkJavaScriptInOption("-packagesheader", packagesheader);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean finishOptionSettings() {
|
||||
if (!validateOptions()) {
|
||||
|
@ -363,6 +363,9 @@ doclet.usage.frames.description=\
|
||||
doclet.usage.no-frames.description=\
|
||||
Disable the use of frames in the generated output
|
||||
|
||||
doclet.usage.allow-script-in-comments.description=\
|
||||
Allow JavaScript in options and comments
|
||||
|
||||
doclet.usage.xdocrootparent.parameters=\
|
||||
<url>
|
||||
doclet.usage.xdocrootparent.description=\
|
||||
|
@ -40,6 +40,7 @@ import jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder;
|
||||
import jdk.javadoc.internal.doclets.toolkit.builders.BuilderFactory;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.UncheckedDocletException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.InternalException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.PackageListWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ResourceIOException;
|
||||
@ -112,8 +113,12 @@ public abstract class AbstractDoclet implements Doclet {
|
||||
}
|
||||
|
||||
try {
|
||||
startGeneration(docEnv);
|
||||
return true;
|
||||
try {
|
||||
startGeneration(docEnv);
|
||||
return true;
|
||||
} catch (UncheckedDocletException e) {
|
||||
throw (DocletException) e.getCause();
|
||||
}
|
||||
|
||||
} catch (DocFileIOException e) {
|
||||
switch (e.mode) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,6 +34,21 @@
|
||||
|
||||
package jdk.javadoc.internal.doclets.toolkit;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
|
||||
import com.sun.source.doctree.DocCommentTree;
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import com.sun.source.doctree.IdentifierTree;
|
||||
@ -43,17 +58,8 @@ import com.sun.source.util.DocTreeFactory;
|
||||
import com.sun.source.util.DocTreePath;
|
||||
import com.sun.source.util.DocTrees;
|
||||
import com.sun.source.util.TreePath;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.tools.FileObject;
|
||||
import com.sun.tools.javac.util.DefinedBy;
|
||||
import com.sun.tools.javac.util.DefinedBy.Api;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
|
||||
|
||||
public class CommentUtils {
|
||||
@ -168,10 +174,18 @@ public class CommentUtils {
|
||||
*/
|
||||
public DocCommentDuo getHtmlCommentDuo(Element e) {
|
||||
FileObject fo = null;
|
||||
if (e.getKind().equals(ElementKind.OTHER)) {
|
||||
fo = configuration.getOverviewPath();
|
||||
} else if (e.getKind().equals(ElementKind.PACKAGE)) {
|
||||
fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
|
||||
PackageElement pe = null;
|
||||
switch (e.getKind()) {
|
||||
case OTHER:
|
||||
fo = configuration.getOverviewPath();
|
||||
pe = configuration.workArounds.getUnnamedPackage();
|
||||
break;
|
||||
case PACKAGE:
|
||||
fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
|
||||
pe = (PackageElement)e;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
if (fo == null) {
|
||||
return null;
|
||||
@ -181,10 +195,20 @@ public class CommentUtils {
|
||||
if (dcTree == null) {
|
||||
return null;
|
||||
}
|
||||
DocTreePath treePath = trees.getDocTreePath(fo);
|
||||
DocTreePath treePath = trees.getDocTreePath(fo, pe);
|
||||
return new DocCommentDuo(treePath.getTreePath(), dcTree);
|
||||
}
|
||||
|
||||
public DocCommentTree parse(URI uri, String text) {
|
||||
return trees.getDocCommentTree(new SimpleJavaFileObject(
|
||||
uri, JavaFileObject.Kind.SOURCE) {
|
||||
@Override @DefinedBy(Api.COMPILER)
|
||||
public CharSequence getCharContent(boolean ignoreEncoding) {
|
||||
return text;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setDocCommentTree(Element element, List<DocTree> fullBody,
|
||||
List<DocTree> blockTags, Utils utils) {
|
||||
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, blockTags);
|
||||
|
@ -227,6 +227,11 @@ public abstract class Configuration {
|
||||
*/
|
||||
public boolean showversion = false;
|
||||
|
||||
/**
|
||||
* Allow JavaScript in doc comments.
|
||||
*/
|
||||
private boolean allowScriptInComments = false;
|
||||
|
||||
/**
|
||||
* Sourcepath from where to read the source files. Default is classpath.
|
||||
*
|
||||
@ -646,6 +651,13 @@ public abstract class Configuration {
|
||||
dumpOnError = true;
|
||||
return true;
|
||||
}
|
||||
},
|
||||
new Option(resources, "--allow-script-in-comments") {
|
||||
@Override
|
||||
public boolean process(String opt, List<String> args) {
|
||||
allowScriptInComments = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
Set<Doclet.Option> set = new TreeSet<>();
|
||||
@ -1054,7 +1066,7 @@ public abstract class Configuration {
|
||||
private final int argCount;
|
||||
|
||||
protected Option(Resources resources, String name, int argCount) {
|
||||
this(resources, "doclet.usage." + name.toLowerCase().replaceAll("^-*", ""), name, argCount);
|
||||
this(resources, "doclet.usage." + name.toLowerCase().replaceAll("^-+", ""), name, argCount);
|
||||
}
|
||||
|
||||
protected Option(Resources resources, String keyBase, String name, int argCount) {
|
||||
@ -1228,4 +1240,13 @@ public abstract class Configuration {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not to allow JavaScript in comments.
|
||||
* Default is off; can be set true from a command line option.
|
||||
* @return the allowScriptInComments
|
||||
*/
|
||||
public boolean isAllowScriptInComments() {
|
||||
return allowScriptInComments;
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
@ -59,7 +60,9 @@ import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.MethodSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.PackageSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.VarSymbol;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.comp.AttrContext;
|
||||
import com.sun.tools.javac.comp.Env;
|
||||
import com.sun.tools.javac.model.JavacElements;
|
||||
@ -192,11 +195,24 @@ public class WorkArounds {
|
||||
return ((VarSymbol)ve).getConstValue();
|
||||
}
|
||||
|
||||
//TODO: DocTrees: Trees.getPath(Element e) is slow a factor 4-5 times.
|
||||
// TODO: DocTrees: Trees.getPath(Element e) is slow a factor 4-5 times.
|
||||
public Map<Element, TreePath> getElementToTreePath() {
|
||||
return toolEnv.elementToTreePath;
|
||||
}
|
||||
|
||||
// TODO: we need ElementUtils.getPackage to cope with input strings
|
||||
// to return the proper unnamedPackage for all supported releases.
|
||||
PackageElement getUnnamedPackage() {
|
||||
return (toolEnv.source.allowModules())
|
||||
? toolEnv.syms.unnamedModule.unnamedPackage
|
||||
: toolEnv.syms.noModule.unnamedPackage;
|
||||
}
|
||||
|
||||
// TODO: implement in either jx.l.m API (preferred) or DocletEnvironment.
|
||||
FileObject getJavaFileObject(PackageElement packageElement) {
|
||||
return ((PackageSymbol)packageElement).sourcefile;
|
||||
}
|
||||
|
||||
// TODO: needs to ported to jx.l.m.
|
||||
public TypeElement searchClass(TypeElement klass, String className) {
|
||||
// search by qualified name first
|
||||
@ -530,12 +546,6 @@ public class WorkArounds {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this is a fast way to get the JavaFileObject for
|
||||
// a package.html file, however we need to eliminate this.
|
||||
public JavaFileObject getJavaFileObject(PackageElement pe) {
|
||||
return toolEnv.pkgToJavaFOMap.get(pe);
|
||||
}
|
||||
|
||||
// TODO: we need to eliminate this, as it is hacky.
|
||||
/**
|
||||
* Returns a representation of the package truncated to two levels.
|
||||
|
@ -35,6 +35,7 @@ import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.DocletException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Messages;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Resources;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.UncheckedDocletException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.InternalException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.SimpleDocletException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
|
||||
@ -167,6 +168,8 @@ public abstract class AbstractBuilder {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof DocletException) {
|
||||
throw (DocletException) cause;
|
||||
} else if (cause instanceof UncheckedDocletException) {
|
||||
throw (DocletException) cause.getCause();
|
||||
} else {
|
||||
// use InternalException, so that a stacktrace showing the position of
|
||||
// the internal exception is generated
|
||||
|
@ -42,6 +42,10 @@ doclet.Building_Tree=Building tree for all the packages and classes...
|
||||
doclet.Building_Index=Building index for all the packages and classes...
|
||||
doclet.Building_Index_For_All_Classes=Building index for all classes...
|
||||
doclet.sourcetab_warning=The argument for -sourcetab must be an integer greater than 0.
|
||||
doclet.JavaScript_in_comment=JavaScript found in documentation comment.\n\
|
||||
Use --allow-script-in-comments to allow use of JavaScript.
|
||||
doclet.JavaScript_in_option=option {0} contains JavaScript.\n\
|
||||
Use --allow-script-in-comments to allow use of JavaScript.
|
||||
doclet.Packages=Packages
|
||||
doclet.Modules=Modules
|
||||
doclet.Other_Packages=Other Packages
|
||||
|
@ -250,17 +250,19 @@ Page header and footer styles
|
||||
padding:5px 0 0 0;
|
||||
}
|
||||
.indexNav {
|
||||
margin:10px;
|
||||
position:relative;
|
||||
font-size:12px;
|
||||
background-color:#dee3e9;
|
||||
}
|
||||
.indexNav ul {
|
||||
padding:0;
|
||||
margin:0;
|
||||
margin-top:0;
|
||||
padding:5px;
|
||||
}
|
||||
.indexNav ul li {
|
||||
display:inline;
|
||||
list-style-type:none;
|
||||
padding-right:10px;
|
||||
text-transform:uppercase;
|
||||
}
|
||||
.indexNav h1 {
|
||||
font-size:13px;
|
||||
|
@ -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.ref.SoftReference;
|
||||
import java.net.URI;
|
||||
import java.text.CollationKey;
|
||||
import java.text.Collator;
|
||||
import java.util.*;
|
||||
@ -108,6 +109,7 @@ public class Utils {
|
||||
public final DocTrees docTrees;
|
||||
public final Elements elementUtils;
|
||||
public final Types typeUtils;
|
||||
public final JavaScriptScanner javaScriptScanner;
|
||||
|
||||
public Utils(Configuration c) {
|
||||
configuration = c;
|
||||
@ -115,6 +117,7 @@ public class Utils {
|
||||
elementUtils = c.docEnv.getElementUtils();
|
||||
typeUtils = c.docEnv.getTypeUtils();
|
||||
docTrees = c.docEnv.getDocTrees();
|
||||
javaScriptScanner = c.isAllowScriptInComments() ? null : new JavaScriptScanner();
|
||||
}
|
||||
|
||||
// our own little symbol table
|
||||
@ -3025,6 +3028,16 @@ public class Utils {
|
||||
TreePath path = isValidDuo(duo) ? duo.treePath : null;
|
||||
if (!dcTreeCache.containsKey(element)) {
|
||||
if (docCommentTree != null && path != null) {
|
||||
if (!configuration.isAllowScriptInComments()) {
|
||||
try {
|
||||
javaScriptScanner.scan(docCommentTree, path, p -> {
|
||||
throw new JavaScriptScanner.Fault();
|
||||
});
|
||||
} catch (JavaScriptScanner.Fault jsf) {
|
||||
String text = configuration.getText("doclet.JavaScript_in_comment");
|
||||
throw new UncheckedDocletException(new SimpleDocletException(text, jsf));
|
||||
}
|
||||
}
|
||||
configuration.workArounds.runDocLint(path);
|
||||
}
|
||||
dcTreeCache.put(element, duo);
|
||||
@ -3044,6 +3057,21 @@ public class Utils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void checkJavaScriptInOption(String name, String value) {
|
||||
if (!configuration.isAllowScriptInComments()) {
|
||||
DocCommentTree dct = configuration.cmtUtils.parse(
|
||||
URI.create("option://" + name.replace("-", "")), "<body>" + value + "</body>");
|
||||
try {
|
||||
javaScriptScanner.scan(dct, null, p -> {
|
||||
throw new JavaScriptScanner.Fault();
|
||||
});
|
||||
} catch (JavaScriptScanner.Fault jsf) {
|
||||
String text = configuration.getText("doclet.JavaScript_in_option", name);
|
||||
throw new UncheckedDocletException(new SimpleDocletException(text, jsf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isValidDuo(DocCommentDuo duo) {
|
||||
return duo != null && duo.dcTree != null;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -39,14 +39,12 @@ import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.ModuleElement;
|
||||
import javax.lang.model.element.ModuleElement.ExportsDirective;
|
||||
import javax.lang.model.element.ModuleElement.RequiresDirective;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.lang.model.util.SimpleElementVisitor9;
|
||||
import javax.tools.JavaFileManager;
|
||||
@ -54,15 +52,12 @@ import javax.tools.JavaFileManager.Location;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Kinds.Kind;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.CompletionFailure;
|
||||
import com.sun.tools.javac.code.Symbol.MethodSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.PackageSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.VarSymbol;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.comp.Modules;
|
||||
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
||||
@ -75,9 +70,11 @@ import jdk.javadoc.doclet.DocletEnvironment;
|
||||
import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
|
||||
|
||||
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
|
||||
import static javax.tools.JavaFileObject.Kind.*;
|
||||
import static jdk.javadoc.internal.tool.Main.Result.*;
|
||||
import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
|
||||
|
||||
|
||||
/**
|
||||
* This class manages elements specified on the command line, and
|
||||
* produces "specified" and "included" data sets, needed by the
|
||||
@ -864,7 +861,7 @@ public class ElementsTable {
|
||||
}
|
||||
|
||||
private boolean isTypeElementSelected(TypeElement te) {
|
||||
return (xclasses || toolEnv.isFromSource(te)) && isSelected(te);
|
||||
return (xclasses || toolEnv.getFileKind(te) == SOURCE) && isSelected(te);
|
||||
}
|
||||
|
||||
SimpleElementVisitor9<Boolean, Void> visibleElementVisitor = null;
|
||||
|
@ -88,8 +88,7 @@ public class JavadocClassFinder extends ClassFinder {
|
||||
@Override
|
||||
protected void extraFileActions(PackageSymbol pack, JavaFileObject fo) {
|
||||
if (fo.isNameCompatible("package", JavaFileObject.Kind.HTML)) {
|
||||
toolEnv.pkgToJavaFOMap.put(pack, fo);
|
||||
trees.putJavaFileObject(pack, fo);
|
||||
pack.sourcefile = fo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,6 +36,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.*;
|
||||
import com.sun.tools.javac.main.JavaCompiler;
|
||||
|
||||
/**
|
||||
* Javadoc's own enter phase does a few things above and beyond that
|
||||
@ -64,16 +65,19 @@ public class JavadocEnter extends Enter {
|
||||
super(context);
|
||||
messager = Messager.instance0(context);
|
||||
toolEnv = ToolEnvironment.instance(context);
|
||||
compiler = JavaCompiler.instance(context);
|
||||
}
|
||||
|
||||
final Messager messager;
|
||||
final ToolEnvironment toolEnv;
|
||||
final JavaCompiler compiler;
|
||||
|
||||
@Override
|
||||
public void main(List<JCCompilationUnit> trees) {
|
||||
// count all Enter errors as warnings.
|
||||
int nerrors = messager.nerrors;
|
||||
super.main(trees);
|
||||
compiler.enterDone();
|
||||
messager.nwarnings += (messager.nerrors - nerrors);
|
||||
messager.nerrors = nerrors;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -202,7 +202,6 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
|
||||
javadocEnter.main(classTrees.toList().appendList(packageTrees));
|
||||
etable.setClassDeclList(listClasses(classTrees.toList()));
|
||||
|
||||
enterDone = true;
|
||||
etable.analyze();
|
||||
} catch (CompletionFailure cf) {
|
||||
throw new ToolException(ABNORMAL, cf.getMessage(), cf);
|
||||
|
@ -182,7 +182,7 @@ public class Messager extends Log implements Reporter {
|
||||
}
|
||||
|
||||
private String getDiagSource(DocTreePath path) {
|
||||
if (path == null) {
|
||||
if (path == null || path.getTreePath() == null) {
|
||||
return programName;
|
||||
}
|
||||
JavacTrees trees = JavacTrees.instance(context);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,7 +29,6 @@ package jdk.javadoc.internal.tool;
|
||||
import java.util.*;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.tools.JavaFileManager;
|
||||
@ -116,8 +115,6 @@ public class ToolEnvironment {
|
||||
|
||||
WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
|
||||
|
||||
public final HashMap<PackageElement, JavaFileObject> pkgToJavaFOMap = new HashMap<>();
|
||||
|
||||
/** Allow documenting from class files? */
|
||||
boolean docClasses = false;
|
||||
|
||||
@ -193,21 +190,11 @@ public class ToolEnvironment {
|
||||
elementToTreePath.put(e, tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type element originates from source.
|
||||
* Primarily used to disambiguate a type element associated with a source
|
||||
* file versus a class file.
|
||||
* @param te the type element
|
||||
* @return true if the symbol is from source
|
||||
*/
|
||||
public boolean isFromSource(TypeElement te) {
|
||||
return getFileKind(te) == Kind.SOURCE;
|
||||
}
|
||||
|
||||
public Kind getFileKind(TypeElement te) {
|
||||
JavaFileObject jfo = ((ClassSymbol)te).outermostClass().classfile;
|
||||
return jfo == null ? Kind.SOURCE : jfo.getKind();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a notice, iff <em>quiet</em> is not specified.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -50,7 +50,7 @@ public class ModuleResolution_attribute extends Attribute {
|
||||
public ModuleResolution_attribute(ConstantPool constant_pool,
|
||||
int resolution_flags)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.ModulePackages),
|
||||
this(constant_pool.getUTF8Index(Attribute.ModuleResolution),
|
||||
resolution_flags);
|
||||
}
|
||||
|
||||
|
@ -128,9 +128,8 @@ import static jdk.internal.jshell.tool.ContinuousCompletionProvider.STARTSWITH_M
|
||||
*/
|
||||
public class JShellTool implements MessageHandler {
|
||||
|
||||
private static final String LINE_SEP = System.getProperty("line.separator");
|
||||
private static final Pattern LINEBREAK = Pattern.compile("\\R");
|
||||
private static final String RECORD_SEPARATOR = "\u241E";
|
||||
static final String RECORD_SEPARATOR = "\u241E";
|
||||
private static final String RB_NAME_PREFIX = "jdk.internal.jshell.tool.resources";
|
||||
private static final String VERSION_RB_NAME = RB_NAME_PREFIX + ".version";
|
||||
private static final String L10N_RB_NAME = RB_NAME_PREFIX + ".l10n";
|
||||
@ -199,7 +198,7 @@ public class JShellTool implements MessageHandler {
|
||||
private boolean debug = false;
|
||||
public boolean testPrompt = false;
|
||||
private String defaultStartup = null;
|
||||
private String startup = null;
|
||||
private Startup startup = null;
|
||||
private String executionControlSpec = null;
|
||||
private EditorSetting editor = BUILT_IN_EDITOR;
|
||||
|
||||
@ -216,7 +215,6 @@ public class JShellTool implements MessageHandler {
|
||||
static final String MODE_KEY = "MODE";
|
||||
static final String REPLAY_RESTORE_KEY = "REPLAY_RESTORE";
|
||||
|
||||
static final String DEFAULT_STARTUP_NAME = "DEFAULT";
|
||||
static final Pattern BUILTIN_FILE_PATTERN = Pattern.compile("\\w+");
|
||||
static final String BUILTIN_FILE_PATH_FORMAT = "/jdk/jshell/tool/resources/%s.jsh";
|
||||
|
||||
@ -431,13 +429,13 @@ public class JShellTool implements MessageHandler {
|
||||
private final OptionSpecBuilder argX = parser.accepts("X");
|
||||
|
||||
private String feedbackMode = null;
|
||||
private String initialStartup = null;
|
||||
private Startup initialStartup = null;
|
||||
|
||||
String feedbackMode() {
|
||||
return feedbackMode;
|
||||
}
|
||||
|
||||
String startup() {
|
||||
Startup startup() {
|
||||
return initialStartup;
|
||||
}
|
||||
|
||||
@ -485,22 +483,15 @@ public class JShellTool implements MessageHandler {
|
||||
startmsg("jshell.err.opt.startup.conflict");
|
||||
return null;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String fn : sts) {
|
||||
String s = readFile(fn, "--startup");
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
sb.append(s);
|
||||
}
|
||||
initialStartup = sb.toString();
|
||||
} else if (options.has(argNoStart)) {
|
||||
initialStartup = "";
|
||||
} else {
|
||||
initialStartup = prefs.get(STARTUP_KEY);
|
||||
initialStartup = Startup.fromFileList(sts, "--startup", new InitMessageHandler());
|
||||
if (initialStartup == null) {
|
||||
initialStartup = defaultStartup();
|
||||
return null;
|
||||
}
|
||||
} else if (options.has(argNoStart)) {
|
||||
initialStartup = Startup.noStartup();
|
||||
} else {
|
||||
String packedStartup = prefs.get(STARTUP_KEY);
|
||||
initialStartup = Startup.unpack(packedStartup, new InitMessageHandler());
|
||||
}
|
||||
if (options.has(argExecution)) {
|
||||
executionControlSpec = options.valueOf(argExecution);
|
||||
@ -639,6 +630,11 @@ public class JShellTool implements MessageHandler {
|
||||
return "";
|
||||
}
|
||||
String pp = s.replaceAll("\\R", post + pre);
|
||||
if (pp.endsWith(post + pre)) {
|
||||
// prevent an extra prefix char and blank line when the string
|
||||
// already terminates with newline
|
||||
pp = pp.substring(0, pp.length() - (post + pre).length());
|
||||
}
|
||||
return pre + pp + post;
|
||||
}
|
||||
|
||||
@ -893,7 +889,7 @@ public class JShellTool implements MessageHandler {
|
||||
analysis = state.sourceCodeAnalysis();
|
||||
live = true;
|
||||
|
||||
startUpRun(startup);
|
||||
startUpRun(startup.toString());
|
||||
currentNameSpace = mainNamespace;
|
||||
}
|
||||
|
||||
@ -1077,7 +1073,7 @@ public class JShellTool implements MessageHandler {
|
||||
.toArray(Command[]::new);
|
||||
}
|
||||
|
||||
private static Path toPathResolvingUserHome(String pathString) {
|
||||
static Path toPathResolvingUserHome(String pathString) {
|
||||
if (pathString.replace(File.separatorChar, '/').startsWith("~/"))
|
||||
return Paths.get(System.getProperty("user.home"), pathString.substring(2));
|
||||
else
|
||||
@ -1838,48 +1834,43 @@ public class JShellTool implements MessageHandler {
|
||||
return true;
|
||||
}
|
||||
if (hasFile) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String fn : fns) {
|
||||
String s = readFile(fn, "/set start");
|
||||
if (s == null) {
|
||||
return false;
|
||||
}
|
||||
sb.append(s);
|
||||
startup = Startup.fromFileList(fns, "/set start", this);
|
||||
if (startup == null) {
|
||||
return false;
|
||||
}
|
||||
startup = sb.toString();
|
||||
} else if (defaultOption) {
|
||||
startup = defaultStartup();
|
||||
startup = Startup.defaultStartup(this);
|
||||
} else if (noneOption) {
|
||||
startup = "";
|
||||
startup = Startup.noStartup();
|
||||
}
|
||||
if (retainOption) {
|
||||
// retain startup setting
|
||||
prefs.put(STARTUP_KEY, startup);
|
||||
prefs.put(STARTUP_KEY, startup.storedForm());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// show the "/set start" settings (retained and, if different, current)
|
||||
// as commands (and file contents). All commands first, then contents.
|
||||
void showSetStart() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String retained = prefs.get(STARTUP_KEY);
|
||||
if (retained != null) {
|
||||
showSetStart(true, retained);
|
||||
}
|
||||
if (retained == null || !startup.equals(retained)) {
|
||||
showSetStart(false, startup);
|
||||
}
|
||||
}
|
||||
|
||||
void showSetStart(boolean isRetained, String start) {
|
||||
String cmd = "/set start" + (isRetained ? " -retain " : " ");
|
||||
String stset;
|
||||
if (start.equals(defaultStartup())) {
|
||||
stset = cmd + "-default";
|
||||
} else if (start.isEmpty()) {
|
||||
stset = cmd + "-none";
|
||||
Startup retainedStart = Startup.unpack(retained, this);
|
||||
boolean currentDifferent = !startup.equals(retainedStart);
|
||||
sb.append(retainedStart.show(true));
|
||||
if (currentDifferent) {
|
||||
sb.append(startup.show(false));
|
||||
}
|
||||
sb.append(retainedStart.showDetail());
|
||||
if (currentDifferent) {
|
||||
sb.append(startup.showDetail());
|
||||
}
|
||||
} else {
|
||||
stset = "startup.jsh:\n" + start + "\n" + cmd + "startup.jsh";
|
||||
sb.append(startup.show(false));
|
||||
sb.append(startup.showDetail());
|
||||
}
|
||||
hard(stset);
|
||||
hard(sb.toString());
|
||||
}
|
||||
|
||||
boolean cmdDebug(String arg) {
|
||||
@ -2200,13 +2191,22 @@ public class JShellTool implements MessageHandler {
|
||||
case ASSIGNMENT_SUBKIND:
|
||||
case OTHER_EXPRESSION_SUBKIND:
|
||||
case TEMP_VAR_EXPRESSION_SUBKIND:
|
||||
case STATEMENT_SUBKIND:
|
||||
case UNKNOWN_SUBKIND:
|
||||
if (!src.endsWith(";")) {
|
||||
src = src + ";";
|
||||
}
|
||||
srcSet.add(src);
|
||||
break;
|
||||
case STATEMENT_SUBKIND:
|
||||
if (src.endsWith("}")) {
|
||||
// Could end with block or, for example, new Foo() {...}
|
||||
// so, we need deeper analysis to know if it needs a semicolon
|
||||
src = analysis.analyzeCompletion(src).source();
|
||||
} else if (!src.endsWith(";")) {
|
||||
src = src + ";";
|
||||
}
|
||||
srcSet.add(src);
|
||||
break;
|
||||
default:
|
||||
srcSet.add(src);
|
||||
break;
|
||||
@ -2380,38 +2380,7 @@ public class JShellTool implements MessageHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an external file. Error messages accessed via keyPrefix
|
||||
*
|
||||
* @param filename file to access or null
|
||||
* @param context printable non-natural language context for errors
|
||||
* @return contents of file as string
|
||||
*/
|
||||
String readFile(String filename, String context) {
|
||||
if (filename != null) {
|
||||
try {
|
||||
byte[] encoded = Files.readAllBytes(toPathResolvingUserHome(filename));
|
||||
return new String(encoded);
|
||||
} catch (AccessDeniedException e) {
|
||||
errormsg("jshell.err.file.not.accessible", context, filename, e.getMessage());
|
||||
} catch (NoSuchFileException e) {
|
||||
String resource = getResource(filename);
|
||||
if (resource != null) {
|
||||
// Not found as file, but found as resource
|
||||
return resource;
|
||||
}
|
||||
errormsg("jshell.err.file.not.found", context, filename);
|
||||
} catch (Exception e) {
|
||||
errormsg("jshell.err.file.exception", context, filename, e);
|
||||
}
|
||||
} else {
|
||||
errormsg("jshell.err.file.filename", context);
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
String getResource(String name) {
|
||||
static String getResource(String name) {
|
||||
if (BUILTIN_FILE_PATTERN.matcher(name).matches()) {
|
||||
try {
|
||||
return readResource(name);
|
||||
@ -2423,33 +2392,16 @@ public class JShellTool implements MessageHandler {
|
||||
}
|
||||
|
||||
// Read a built-in file from resources
|
||||
String readResource(String name) throws IOException {
|
||||
static String readResource(String name) throws IOException {
|
||||
// Attempt to find the file as a resource
|
||||
String spec = String.format(BUILTIN_FILE_PATH_FORMAT, name);
|
||||
|
||||
try (InputStream in = JShellTool.class.getResourceAsStream(spec);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
|
||||
return reader.lines().collect(Collectors.joining("\n"));
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
|
||||
return reader.lines().collect(Collectors.joining("\n", "", "\n"));
|
||||
}
|
||||
}
|
||||
|
||||
// retrieve the default startup string
|
||||
String defaultStartup() {
|
||||
if (defaultStartup == null) {
|
||||
defaultStartup = ""; // failure case
|
||||
try {
|
||||
defaultStartup = readResource(DEFAULT_STARTUP_NAME);
|
||||
} catch (AccessDeniedException e) {
|
||||
errormsg("jshell.err.file.not.accessible", "jshell", DEFAULT_STARTUP_NAME, e.getMessage());
|
||||
} catch (NoSuchFileException e) {
|
||||
errormsg("jshell.err.file.not.found", "jshell", DEFAULT_STARTUP_NAME);
|
||||
} catch (Exception e) {
|
||||
errormsg("jshell.err.file.exception", "jshell", DEFAULT_STARTUP_NAME, e);
|
||||
}
|
||||
}
|
||||
return defaultStartup;
|
||||
}
|
||||
|
||||
private boolean cmdReset(String rawargs) {
|
||||
if (!parseCommandLineLikeFlags(rawargs, new OptionParserBase())) {
|
||||
return false;
|
||||
@ -2551,7 +2503,7 @@ public class JShellTool implements MessageHandler {
|
||||
writer.write("\n");
|
||||
}
|
||||
} else if (at.hasOption("-start")) {
|
||||
writer.append(startup);
|
||||
writer.append(startup.toString());
|
||||
} else {
|
||||
String sources = (at.hasOption("-all")
|
||||
? state.snippets()
|
||||
|
@ -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.retained.mode.failure = Failure in retained modes (modes cleared) -- {0} {1}
|
||||
|
||||
jshell.err.corrupted.stored.startup = Corrupted stored startup, using default -- {0}
|
||||
|
||||
jshell.console.see.more = <press tab to see more>
|
||||
jshell.console.see.javadoc = <press shift-tab again to see javadoc>
|
||||
jshell.console.see.help = <press shift-tab again to see detailed help>
|
||||
|
@ -8,4 +8,3 @@ import java.util.function.*;
|
||||
import java.util.prefs.*;
|
||||
import java.util.regex.*;
|
||||
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 \
|
||||
$(JCK_COMPILER_OUTPUT_DIR)/diff.html $(JCK_COMPILER_OUTPUT_DIR)/status.txt
|
||||
@mkdir -p $(JCK_COMPILER_OUTPUT_DIR)
|
||||
$(JT_JAVA)/bin/java -Xmx512m \
|
||||
$(JT_JAVA)/bin/java -Xmx1024m \
|
||||
-jar $(JCK_HOME)/JCK-compiler-9/lib/jtjck.jar \
|
||||
$(if $(JCK_VERBOSE),$(if $(filter $(JCK_VERBOSE),summary),-v,-v:$(JCK_VERBOSE))) \
|
||||
-r:$(JCK_COMPILER_OUTPUT_DIR)/report \
|
||||
@ -429,7 +429,7 @@ jck-runtime-tests: check-jck FRC
|
||||
@rm -f -r $(JCK_RUNTIME_OUTPUT_DIR)/work $(JCK_RUNTIME_OUTPUT_DIR)/report \
|
||||
$(JCK_RUNTIME_OUTPUT_DIR)/diff.html $(JCK_RUNTIME_OUTPUT_DIR)/status.txt
|
||||
@mkdir -p $(JCK_RUNTIME_OUTPUT_DIR)
|
||||
$(JT_JAVA)/bin/java -Xmx512m \
|
||||
$(JT_JAVA)/bin/java -Xmx1024m \
|
||||
-jar $(JCK_HOME)/JCK-runtime-9/lib/jtjck.jar \
|
||||
$(if $(JCK_VERBOSE),$(if $(filter $(JCK_VERBOSE),summary),-v,-v:$(JCK_VERBOSE))) \
|
||||
-r:$(JCK_RUNTIME_OUTPUT_DIR)/report \
|
||||
|
@ -14,8 +14,8 @@ keys=intermittent randomness
|
||||
# Group definitions
|
||||
groups=TEST.groups
|
||||
|
||||
# Tests using jtreg 4.2 b04 features
|
||||
requiredVersion=4.2 b04
|
||||
# Tests using jtreg 4.2 b05 features
|
||||
requiredVersion=4.2 b05
|
||||
|
||||
# Use new module options
|
||||
useNewOptions=true
|
||||
|
313
langtools/test/jdk/javadoc/tool/TestScriptInComment.java
Normal file
313
langtools/test/jdk/javadoc/tool/TestScriptInComment.java
Normal file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8138725
|
||||
* @summary test --allow-script-in-comments
|
||||
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Combo-style test, exercising combinations of different HTML fragments that may contain
|
||||
* JavaScript, different places to place those fragments, and whether or not to allow the use
|
||||
* of JavaScript.
|
||||
*/
|
||||
public class TestScriptInComment {
|
||||
public static void main(String... args) throws Exception {
|
||||
new TestScriptInComment().run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Representative samples of different fragments of HTML that may contain JavaScript.
|
||||
* To facilitate checking the output manually in a browser, the text "#ALERT" will be
|
||||
* replaced by a JavaScript call of "alert(msg)", using a message string that is specific
|
||||
* to the test case.
|
||||
*/
|
||||
enum Comment {
|
||||
LC("<script>#ALERT</script>", true), // script tag in Lower Case
|
||||
UC("<SCRIPT>#ALERT</script>", true), // script tag in Upper Case
|
||||
WS("< script >#ALERT</script>", false, "-Xdoclint:none"), // script tag with invalid white space
|
||||
SP("<script src=\"file\"> #ALERT </script>", true), // script tag with an attribute
|
||||
ON("<a onclick='#ALERT'>x</a>", true), // event handler attribute
|
||||
URI("<a href='javascript:#ALERT'>x</a>", true); // javascript URI
|
||||
|
||||
/**
|
||||
* Creates an HTML fragment to be injected into a template.
|
||||
* @param text the HTML fragment to put into a doc comment or option.
|
||||
* @param hasScript whether or not this fragment does contain legal JavaScript
|
||||
* @param opts any additional options to be specified when javadoc is run
|
||||
*/
|
||||
Comment(String text, boolean hasScript, String... opts) {
|
||||
this.text = text;
|
||||
this.hasScript = hasScript;
|
||||
this.opts = Arrays.asList(opts);
|
||||
}
|
||||
|
||||
final String text;
|
||||
final boolean hasScript;
|
||||
final List<String> opts;
|
||||
};
|
||||
|
||||
/**
|
||||
* Representative samples of positions in which javadoc may find JavaScript.
|
||||
* Each template contains a series of strings, which are written to files or inferred as options.
|
||||
* The first source file implies a corresponding output file which should not be written
|
||||
* if the comment contains JavaScript and JavaScript is not allowed.
|
||||
*/
|
||||
enum Template {
|
||||
OVR("<html><body> overview #COMMENT </body></html>", "package p; public class C { }"),
|
||||
PKGINFO("#COMMENT package p;", "package p; public class C { }"),
|
||||
PKGHTML("<html><body>#COMMENT package p;</body></html>", "package p; public class C { }"),
|
||||
CLS("package p; #COMMENT public class C { }"),
|
||||
CON("package p; public class C { #COMMENT public C() { } }"),
|
||||
FLD("package p; public class C { #COMMENT public int f; }"),
|
||||
MTH("package p; public class C { #COMMENT public void m() { } }"),
|
||||
TOP("-top", "lorem #COMMENT ipsum", "package p; public class C { }"),
|
||||
HDR("-header", "lorem #COMMENT ipsum", "package p; public class C { }"),
|
||||
FTR("-footer", "lorem #COMMENT ipsum", "package p; public class C { }"),
|
||||
BTM("-bottom", "lorem #COMMENT ipsum", "package p; public class C { }"),
|
||||
DTTL("-doctitle", "lorem #COMMENT ipsum", "package p; public class C { }"),
|
||||
PHDR("-packagesheader", "lorem #COMMENT ipsum", "package p; public class C { }");
|
||||
|
||||
Template(String... args) {
|
||||
opts = new ArrayList<String>();
|
||||
sources = new ArrayList<String>();
|
||||
int i = 0;
|
||||
while (args[i].startsWith("-")) {
|
||||
// all options being tested have a single argument that follow the option
|
||||
opts.add(args[i++]);
|
||||
opts.add(args[i++]);
|
||||
}
|
||||
while(i < args.length) {
|
||||
sources.add(args[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
// groups: 1 <html> or not; 2: package name; 3: class name
|
||||
private final Pattern pat =
|
||||
Pattern.compile("(?i)(<html>)?.*?(?:package ([a-z]+);.*?(?:class ([a-z]+).*)?)?");
|
||||
|
||||
/**
|
||||
* Infer the file in which to write the given source.
|
||||
* @param dir the base source directory
|
||||
* @param src the source text
|
||||
* @return the file in which the source should be written
|
||||
*/
|
||||
File getSrcFile(File srcDir, String src) {
|
||||
String f;
|
||||
Matcher m = pat.matcher(src);
|
||||
if (!m.matches())
|
||||
throw new Error("match failed");
|
||||
if (m.group(3) != null) {
|
||||
f = m.group(2) + "/" + m.group(3) + ".java";
|
||||
} else if (m.group(2) != null) {
|
||||
f = m.group(2) + "/" + (m.group(1) == null ? "package-info.java" : "package.html");
|
||||
} else {
|
||||
f = "overview.html";
|
||||
}
|
||||
return new File(srcDir, f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options to give to javadoc.
|
||||
* @param srcDir the srcDir to use -overview is needed
|
||||
* @return
|
||||
*/
|
||||
List<String> getOpts(File srcDir) {
|
||||
if (!opts.isEmpty()) {
|
||||
return opts;
|
||||
} else if (sources.get(0).contains("overview")) {
|
||||
return Arrays.asList("-overview", getSrcFile(srcDir, sources.get(0)).getPath());
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the output file corresponding to the first source file.
|
||||
* This file should not be written if the comment contains JavaScript and JavaScripot is
|
||||
* not allowed.
|
||||
* @param dir the base output directory
|
||||
* @return the output file
|
||||
*/
|
||||
File getOutFile(File outDir) {
|
||||
String f;
|
||||
Matcher m = pat.matcher(sources.get(0));
|
||||
if (!m.matches())
|
||||
throw new Error("match failed");
|
||||
if (m.group(3) != null) {
|
||||
f = m.group(2) + "/" + m.group(3) + ".html";
|
||||
} else if (m.group(2) != null) {
|
||||
f = m.group(2) + "/package-summary.html";
|
||||
} else {
|
||||
f = "overview-summary.html";
|
||||
}
|
||||
return new File(outDir, f);
|
||||
}
|
||||
|
||||
final List<String> opts;
|
||||
final List<String> sources;
|
||||
};
|
||||
|
||||
enum Option {
|
||||
OFF(null),
|
||||
ON("--allow-script-in-comments");
|
||||
|
||||
Option(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
final String text;
|
||||
};
|
||||
|
||||
private PrintStream out = System.err;
|
||||
|
||||
public void run() throws Exception {
|
||||
int count = 0;
|
||||
for (Template template: Template.values()) {
|
||||
for (Comment comment: Comment.values()) {
|
||||
for (Option option: Option.values()) {
|
||||
if (test(template, comment, option)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.println(count + " test cases run");
|
||||
if (errors > 0) {
|
||||
throw new Exception(errors + " errors occurred");
|
||||
}
|
||||
}
|
||||
|
||||
boolean test(Template template, Comment comment, Option option) throws IOException {
|
||||
if (option == Option.ON && !comment.hasScript) {
|
||||
// skip --allowScriptInComments if comment does not contain JavaScript
|
||||
return false;
|
||||
}
|
||||
|
||||
String test = template + "-" + comment + "-" + option;
|
||||
out.println("Test: " + test);
|
||||
|
||||
File dir = new File(test);
|
||||
dir.mkdirs();
|
||||
File srcDir = new File(dir, "src");
|
||||
File outDir = new File(dir, "out");
|
||||
|
||||
String alert = "alert(\"" + test + "\");";
|
||||
for (String src: template.sources) {
|
||||
writeFile(template.getSrcFile(srcDir, src),
|
||||
src.replace("#COMMENT",
|
||||
"/** " + comment.text.replace("#ALERT", alert) + " **/"));
|
||||
}
|
||||
|
||||
List<String> opts = new ArrayList<String>();
|
||||
opts.add("-sourcepath");
|
||||
opts.add(srcDir.getPath());
|
||||
opts.add("-d");
|
||||
opts.add(outDir.getPath());
|
||||
if (option.text != null)
|
||||
opts.add(option.text);
|
||||
for (String opt: template.getOpts(srcDir)) {
|
||||
opts.add(opt.replace("#COMMENT", comment.text.replace("#ALERT", alert)));
|
||||
}
|
||||
opts.addAll(comment.opts);
|
||||
opts.add("-noindex"); // index not required; save time/space writing files
|
||||
opts.add("p");
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
int rc = javadoc(opts, pw);
|
||||
pw.close();
|
||||
String log = sw.toString();
|
||||
writeFile(new File(dir, "log.txt"), log);
|
||||
|
||||
out.println("opts: " + opts);
|
||||
out.println(" rc: " + rc);
|
||||
out.println(" log:");
|
||||
out.println(log);
|
||||
|
||||
String ERROR = "Use --allow-script-in-comment";
|
||||
File outFile = template.getOutFile(outDir);
|
||||
|
||||
boolean expectErrors = comment.hasScript && (option == Option.OFF);
|
||||
|
||||
if (expectErrors) {
|
||||
check(rc != 0, "unexpected exit code: " + rc);
|
||||
check(log.contains(ERROR), "expected error message not found");
|
||||
check(!outFile.exists(), "output file found unexpectedly");
|
||||
} else {
|
||||
check(rc == 0, "unexpected exit code: " + rc);
|
||||
check(!log.contains(ERROR), "error message found");
|
||||
check(outFile.exists(), "output file not found");
|
||||
}
|
||||
|
||||
out.println();
|
||||
return true;
|
||||
}
|
||||
|
||||
int javadoc(List<String> opts, PrintWriter pw) {
|
||||
return jdk.javadoc.internal.tool.Main.execute(opts.toArray(new String[opts.size()]), pw);
|
||||
}
|
||||
|
||||
File writeFile(File f, String text) throws IOException {
|
||||
f.getParentFile().mkdirs();
|
||||
FileWriter fw = new FileWriter(f);
|
||||
try {
|
||||
fw.write(text);
|
||||
} finally {
|
||||
fw.close();
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
void check(boolean cond, String errMessage) {
|
||||
if (!cond) {
|
||||
error(errMessage);
|
||||
}
|
||||
}
|
||||
|
||||
void error(String message) {
|
||||
out.println("Error: " + message);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors = 0;
|
||||
}
|
||||
|
100
langtools/test/jdk/javadoc/tool/treeapi/TestDocTrees.java
Normal file
100
langtools/test/jdk/javadoc/tool/treeapi/TestDocTrees.java
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8157611
|
||||
* @summary test DocTrees is working correctly relative to HTML access
|
||||
* @modules
|
||||
* jdk.javadoc/jdk.javadoc.internal.api
|
||||
* jdk.javadoc/jdk.javadoc.internal.tool
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib
|
||||
* @build toolbox.ToolBox toolbox.TestRunner
|
||||
* @run main TestDocTrees
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import toolbox.*;
|
||||
import toolbox.Task.Expect;
|
||||
|
||||
import static toolbox.Task.OutputKind.*;
|
||||
|
||||
/**
|
||||
* This class is used to test DocTrees functionality relating to
|
||||
* package and overview HTML files.
|
||||
*/
|
||||
public class TestDocTrees extends TestRunner {
|
||||
final ToolBox tb;
|
||||
final File testFile;
|
||||
final File testSrc;
|
||||
final File overviewFile;
|
||||
|
||||
TestDocTrees() throws IOException {
|
||||
super(System.err);
|
||||
tb = new ToolBox();
|
||||
testSrc = new File(System.getProperty("test.src"));
|
||||
testFile = new File(testSrc, "TestDocTrees.java");
|
||||
overviewFile = new File(testSrc, "overview.html");
|
||||
}
|
||||
|
||||
protected void runTests() throws Exception {
|
||||
runTests(m -> new Object[]{Paths.get(m.getName())});
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new TestDocTrees().runTests();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverviewWithRelease8(Path out) {
|
||||
execTask("-d", out.toString(),
|
||||
"--release", "8",
|
||||
"-Xdoclint:all",
|
||||
"-Xdoclint:-missing",
|
||||
"-sourcepath", testSrc.getAbsolutePath(),
|
||||
testFile.getAbsolutePath(),
|
||||
"-overview", overviewFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverviewWithoutRelease(Path out) throws Exception {
|
||||
execTask("-d", out.toString(),
|
||||
"-Xdoclint:all",
|
||||
"-Xdoclint:-missing",
|
||||
"-sourcepath", testSrc.getAbsolutePath(),
|
||||
testFile.getAbsolutePath(),
|
||||
"-overview", overviewFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
private Task.Result execTask(String... args) {
|
||||
JavadocTask et = new JavadocTask(tb, Task.Mode.CMDLINE);
|
||||
//args.forEach((a -> System.err.println("arg: " + a)));
|
||||
return et.options(args).run();
|
||||
}
|
||||
}
|
27
langtools/test/jdk/javadoc/tool/treeapi/overview.html
Normal file
27
langtools/test/jdk/javadoc/tool/treeapi/overview.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!--
|
||||
Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
This code is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 only, as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
version 2 for more details (a copy is included in the LICENSE file that
|
||||
accompanied this code).
|
||||
|
||||
You should have received a copy of the GNU General Public License version
|
||||
along with this work; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
or visit www.oracle.com if you need additional information or have any
|
||||
questions.
|
||||
-->
|
||||
<html>
|
||||
<body>
|
||||
<b>{@link omg.what.gives}</b>
|
||||
</body>
|
||||
</html>
|
@ -24,7 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @summary Testing external editor.
|
||||
* @bug 8143955 8080843 8163816 8143006 8169828
|
||||
* @bug 8143955 8080843 8163816 8143006 8169828 8171130
|
||||
* @modules jdk.jshell/jdk.internal.jshell.tool
|
||||
* @build ReplToolTesting CustomEditor EditorTestBase
|
||||
* @run testng ExternalEditorTest
|
||||
@ -50,6 +50,7 @@ import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
public class ExternalEditorTest extends EditorTestBase {
|
||||
@ -119,6 +120,28 @@ public class ExternalEditorTest extends EditorTestBase {
|
||||
super.testEditor(defaultStartup, args, t);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatementSemicolonAddition() {
|
||||
testEditor(
|
||||
a -> assertCommand(a, "if (true) {}", ""),
|
||||
a -> assertCommand(a, "if (true) {} else {}", ""),
|
||||
a -> assertCommand(a, "Object o", "o ==> null"),
|
||||
a -> assertCommand(a, "if (true) o = new Object() { int x; }", ""),
|
||||
a -> assertCommand(a, "if (true) o = new Object() { int y; }", ""),
|
||||
a -> assertCommand(a, "System.err.flush()", ""), // test still ; for expression statement
|
||||
a -> assertEditOutput(a, "/ed", "", () -> {
|
||||
assertEquals(getSource(),
|
||||
"if (true) {}\n" +
|
||||
"if (true) {} else {}\n" +
|
||||
"Object o;\n" +
|
||||
"if (true) o = new Object() { int x; };\n" +
|
||||
"if (true) o = new Object() { int y; };\n" +
|
||||
"System.err.flush();\n");
|
||||
exit();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean isWindows() {
|
||||
return System.getProperty("os.name").startsWith("Windows");
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8157395 8157393 8157517 8158738 8167128 8163840 8167637 8170368 8172102
|
||||
* @bug 8157395 8157393 8157517 8158738 8167128 8163840 8167637 8170368 8172102 8172179
|
||||
* @summary Tests of jshell comand options, and undoing operations
|
||||
* @modules jdk.jshell/jdk.internal.jshell.tool
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
@ -273,14 +273,13 @@ public class ToolCommandOptionTest extends ReplToolTesting {
|
||||
(a) -> assertCommand(a, "/set start DEFAULT PRINTING",
|
||||
""),
|
||||
(a) -> assertCommandOutputContains(a, "/set start",
|
||||
"void println", "import java.util.*"),
|
||||
"/set start DEFAULT PRINTING", "void println", "import java.util.*"),
|
||||
(a) -> assertCommand(a, "/set start " + startup.toString(),
|
||||
""),
|
||||
(a) -> assertCommand(a, "/set start",
|
||||
"| startup.jsh:\n" +
|
||||
"| int iAmHere = 1234;\n" +
|
||||
"| \n" +
|
||||
"| /set start startup.jsh"),
|
||||
(a) -> assertCommandOutputContains(a, "/set start",
|
||||
"| /set start " + startup + "\n" +
|
||||
"| ---- " + startup + " @ ", " ----\n" +
|
||||
"| int iAmHere = 1234;\n"),
|
||||
(a) -> assertCommand(a, "/se sta -no",
|
||||
""),
|
||||
(a) -> assertCommand(a, "/set start",
|
||||
@ -322,11 +321,18 @@ public class ToolCommandOptionTest extends ReplToolTesting {
|
||||
"| /set start -retain -none"),
|
||||
(a) -> assertCommand(a, "/set start -retain " + startup.toString(),
|
||||
""),
|
||||
(a) -> assertCommand(a, "/set start",
|
||||
"| startup.jsh:\n" +
|
||||
"| int iAmHere = 1234;\n" +
|
||||
"| \n" +
|
||||
"| /set start -retain startup.jsh")
|
||||
(a) -> assertCommand(a, "/set start DEFAULT PRINTING",
|
||||
""),
|
||||
(a) -> assertCommandOutputStartsWith(a, "/set start",
|
||||
"| /set start -retain " + startup.toString() + "\n" +
|
||||
"| /set start DEFAULT PRINTING\n" +
|
||||
"| ---- " + startup.toString() + " @ "),
|
||||
(a) -> assertCommandOutputContains(a, "/set start",
|
||||
"| ---- DEFAULT ----\n",
|
||||
"| ---- PRINTING ----\n",
|
||||
"| int iAmHere = 1234;\n",
|
||||
"| void println(String s)",
|
||||
"| import java.io.*;")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840 8166637 8161969
|
||||
* @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840 8166637 8161969 8173007
|
||||
* @summary Tests for output customization
|
||||
* @library /tools/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
@ -38,8 +38,6 @@ import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
@ -140,6 +138,66 @@ public class ToolFormatTest extends ReplToolTesting {
|
||||
);
|
||||
}
|
||||
|
||||
public void testSetFormatSelectorSample() {
|
||||
test(
|
||||
(a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet",
|
||||
"| Created new feedback mode: ate"),
|
||||
(a) -> assertCommand(a, "/set feedback ate", ""),
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---replaced,modified,added-primary---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++replaced,modified,added-primary+++' replaced,modified,added-primary", ""),
|
||||
(a) -> assertCommand(a, "\"replaced,modified,added-primary\"", "+++replaced,modified,added-primary+++"),
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---added-primary,update---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++added-primary,update+++' added-primary,update", ""),
|
||||
(a) -> assertCommand(a, "\"added-primary,update\"", "+++added-primary,update+++"),
|
||||
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---method-replaced-primary---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++method-replaced-primary+++' method-replaced-primary", ""),
|
||||
(a) -> assertCommand(a, "\"method-replaced-primary\"", "---method-replaced-primary---"),
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---method-replaced-update---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++method-replaced-update+++' method-replaced-update", ""),
|
||||
(a) -> assertCommand(a, "\"method-replaced-update\"", "---method-replaced-update---"),
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---method-added-update---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++method-added-update+++' method-added-update", ""),
|
||||
(a) -> assertCommand(a, "\"method-added-update\"", "---method-added-update---"),
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---method-added---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++method-added+++' method-added", ""),
|
||||
(a) -> assertCommand(a, "\"method-added\"", "---method-added---"),
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---class-modified,added-primary,update---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++class-modified,added-primary,update+++' class-modified,added-primary,update", ""),
|
||||
(a) -> assertCommand(a, "\"class-modified,added-primary,update\"", "---class-modified,added-primary,update---"),
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---class-modified,added-primary---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++class-modified,added-primary+++' class-modified,added-primary", ""),
|
||||
(a) -> assertCommand(a, "\"class-modified,added-primary\"", "---class-modified,added-primary---"),
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---class-modified,added-update---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++class-modified,added-update+++' class-modified,added-update", ""),
|
||||
(a) -> assertCommand(a, "\"class-modified,added-update\"", "---class-modified,added-update---"),
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---replaced,added---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++replaced,added+++' replaced,added", ""),
|
||||
(a) -> assertCommand(a, "\"replaced,added\"", "+++replaced,added+++"),
|
||||
|
||||
(a) -> assertCommand(a, "/set format ate display '---replaced-primary,update---'", ""),
|
||||
(a) -> assertCommand(a, "/set format ate display '+++replaced-primary,update+++' replaced-primary,update", ""),
|
||||
(a) -> assertCommand(a, "\"replaced-primary,update\"", "---replaced-primary,update---"),
|
||||
|
||||
(a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal")
|
||||
);
|
||||
}
|
||||
|
||||
// This test is exhaustive and takes to long for routine testing -- disabled.
|
||||
// A sampling of these has been added (above: testSetFormatSelectorSample).
|
||||
// See 8173007
|
||||
// Save for possible future deep testing or debugging
|
||||
@Test(enabled = false)
|
||||
public void testSetFormatSelector() {
|
||||
List<ReplTest> tests = new ArrayList<>();
|
||||
tests.add((a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet",
|
||||
@ -202,6 +260,11 @@ public class ToolFormatTest extends ReplToolTesting {
|
||||
tests.add((a) -> assertCommand(a, "/set format ate display '" + no + "'", ""));
|
||||
tests.add((a) -> assertCommand(a, "/set format ate display '" + yes + "' " + select, ""));
|
||||
tests.add((a) -> assertCommand(a, "\"" + select + "\"", expect));
|
||||
/**** for sample generation ****
|
||||
System.err.println(" (a) -> assertCommand(a, \"/set format ate display '" + no + "'\", \"\"),");
|
||||
System.err.println(" (a) -> assertCommand(a, \"/set format ate display '" + yes + "' " + select + "\", \"\"),");
|
||||
System.err.println(" (a) -> assertCommand(a, \"\\\"" + select + "\\\"\", \"" + expect + "\"),\n");
|
||||
****/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,7 @@ OtherTagsTest.java:20: error: element not allowed in documentation comments: <me
|
||||
OtherTagsTest.java:21: error: element not allowed in documentation comments: <noframes>
|
||||
* <noframes> </noframes>
|
||||
^
|
||||
OtherTagsTest.java:22: error: element not allowed in documentation comments: <script>
|
||||
* <script> </script>
|
||||
^
|
||||
OtherTagsTest.java:23: error: element not allowed in documentation comments: <title>
|
||||
* <title> </title>
|
||||
^
|
||||
9 errors
|
||||
8 errors
|
||||
|
@ -143,6 +143,7 @@ public class ParameterNamesAreNotCopiedToAnonymousInitTest {
|
||||
Arrays.asList(new File(System.getProperty("test.src"),
|
||||
this.getClass().getName() + ".java")));
|
||||
java.util.List<String> options = Arrays.asList(
|
||||
"--add-modules", "jdk.jdeps",
|
||||
"--add-exports", "jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED",
|
||||
"--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
|
||||
"--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,7 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @summary Module attribute tests
|
||||
* @bug 8080878 8161906 8162713
|
||||
* @bug 8080878 8161906 8162713 8170250
|
||||
* @modules java.compiler
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
@ -52,6 +52,28 @@ public class ModuleTest extends ModuleTestBase {
|
||||
testModuleAttribute(base, moduleDescriptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenEmptyModule(Path base) throws Exception {
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m", ModuleFlag.OPEN)
|
||||
.write(base);
|
||||
compile(base);
|
||||
testModuleAttribute(base, moduleDescriptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModuleName(Path base) throws Exception {
|
||||
testName("module.name", base.resolve("dot"));
|
||||
testName("module.exports.component.subcomponent.more.dots", base.resolve("dots"));
|
||||
testName("moduleName", base.resolve("noDots"));
|
||||
}
|
||||
|
||||
private void testName(String name, Path path) throws Exception{
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor(name)
|
||||
.write(path);
|
||||
compile(path);
|
||||
testModuleAttribute(path, moduleDescriptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExports(Path base) throws Exception {
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
|
||||
@ -91,16 +113,6 @@ public class ModuleTest extends ModuleTestBase {
|
||||
testModuleAttribute(base, moduleDescriptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifiedDynamicExports(Path base) throws Exception {
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
|
||||
.exportsTo("pack", "jdk.compiler")
|
||||
.write(base);
|
||||
tb.writeJavaFiles(base, "package pack; public class A { }");
|
||||
compile(base);
|
||||
testModuleAttribute(base, moduleDescriptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSeveralQualifiedExports(Path base) throws Exception {
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
|
||||
@ -120,6 +132,47 @@ public class ModuleTest extends ModuleTestBase {
|
||||
testModuleAttribute(base, moduleDescriptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpens(Path base) throws Exception {
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("module.name")
|
||||
.opens("pack")
|
||||
.write(base);
|
||||
tb.writeJavaFiles(base, "package pack; public class C extends java.util.ArrayList{ }");
|
||||
compile(base);
|
||||
testModuleAttribute(base, moduleDescriptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifiedOpens(Path base) throws Exception {
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
|
||||
.opensTo("pack", "jdk.compiler")
|
||||
.write(base);
|
||||
tb.writeJavaFiles(base, "package pack; public class A { }");
|
||||
compile(base);
|
||||
testModuleAttribute(base, moduleDescriptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSeveralOpens(Path base) throws Exception {
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("module.m1.name")
|
||||
.opensTo("pack", "jdk.compiler, jdk.jdeps")
|
||||
.opensTo("pack2", "jdk.jdeps")
|
||||
.opensTo("pack3", "jdk.compiler")
|
||||
.opensTo("pack4", "jdk.compiler, jdk.jdeps")
|
||||
.opensTo("pack5", "jdk.compiler")
|
||||
.opens("pack6")
|
||||
.write(base);
|
||||
tb.writeJavaFiles(base,
|
||||
"package pack; public class A {}",
|
||||
"package pack2; public class B {}",
|
||||
"package pack3; public class C {}",
|
||||
"package pack4; public class C {}",
|
||||
"package pack5; public class C {}",
|
||||
"package pack6; public class C {}");
|
||||
compile(base);
|
||||
testModuleAttribute(base, moduleDescriptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequires(Path base) throws Exception {
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
|
||||
@ -182,10 +235,12 @@ public class ModuleTest extends ModuleTestBase {
|
||||
.provides("java.util.Collection", "pack2.D")
|
||||
.provides("java.util.List", "pack2.D")
|
||||
.requires("jdk.compiler")
|
||||
.provides("javax.tools.FileObject", "pack2.E")
|
||||
.provides("com.sun.tools.javac.Main", "pack2.C")
|
||||
.write(base);
|
||||
tb.writeJavaFiles(base, "package pack2; public class D extends java.util.ArrayList{ }",
|
||||
"package pack2; public class C extends com.sun.tools.javac.Main{ }");
|
||||
"package pack2; public class C extends com.sun.tools.javac.Main{ }",
|
||||
"package pack2; public class E extends javax.tools.SimpleJavaFileObject{ public E(){ super(null,null); } }");
|
||||
compile(base);
|
||||
testModuleAttribute(base, moduleDescriptor);
|
||||
}
|
||||
@ -203,9 +258,10 @@ public class ModuleTest extends ModuleTestBase {
|
||||
public void testSeveralUses(Path base) throws Exception {
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
|
||||
.uses("java.util.List")
|
||||
.uses("java.util.Collection")
|
||||
.uses("java.util.Collection") // from java.base
|
||||
.requires("jdk.compiler")
|
||||
.uses("javax.tools.JavaCompiler")
|
||||
.uses("javax.tools.JavaCompiler") // from java.compiler
|
||||
.uses("com.sun.tools.javac.Main") // from jdk.compiler
|
||||
.write(base);
|
||||
compile(base);
|
||||
testModuleAttribute(base, moduleDescriptor);
|
||||
@ -216,9 +272,52 @@ public class ModuleTest extends ModuleTestBase {
|
||||
Path m1 = base.resolve("m1x");
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m1x")
|
||||
.exports("pack1")
|
||||
.exports("pack3")
|
||||
.opens("pack3")
|
||||
.exportsTo("packTo1", "m2x")
|
||||
.opensTo("packTo1", "m2x") // the same as exportsTo
|
||||
.opensTo("packTo3", "m3x")
|
||||
.requires("jdk.compiler")
|
||||
.requires("m2x", RequiresFlag.TRANSITIVE)
|
||||
.requires("m3x", RequiresFlag.STATIC)
|
||||
.requires("m4x", RequiresFlag.TRANSITIVE, RequiresFlag.STATIC)
|
||||
.provides("java.util.List", "pack1.C", "pack2.D")
|
||||
.uses("java.util.List")
|
||||
.uses("java.nio.file.Path")
|
||||
.requires("jdk.jdeps", RequiresFlag.STATIC, RequiresFlag.TRANSITIVE)
|
||||
.requires("m5x", RequiresFlag.STATIC)
|
||||
.requires("m6x", RequiresFlag.TRANSITIVE)
|
||||
.requires("java.compiler")
|
||||
.opensTo("packTo4", "java.compiler")
|
||||
.exportsTo("packTo2", "java.compiler")
|
||||
.opens("pack2") // same as exports
|
||||
.opens("pack4")
|
||||
.exports("pack2")
|
||||
.write(m1);
|
||||
tb.writeJavaFiles(m1, "package pack1; public class C extends java.util.ArrayList{ }",
|
||||
"package pack2; public class D extends java.util.ArrayList{ }",
|
||||
"package pack3; public class D extends java.util.ArrayList{ }",
|
||||
"package pack4; public class D extends java.util.ArrayList{ }");
|
||||
tb.writeJavaFiles(m1,
|
||||
"package packTo1; public class T1 {}",
|
||||
"package packTo2; public class T2 {}",
|
||||
"package packTo3; public class T3 {}",
|
||||
"package packTo4; public class T4 {}");
|
||||
tb.writeJavaFiles(base.resolve("m2x"), "module m2x { }");
|
||||
tb.writeJavaFiles(base.resolve("m3x"), "module m3x { }");
|
||||
tb.writeJavaFiles(base.resolve("m4x"), "module m4x { }");
|
||||
tb.writeJavaFiles(base.resolve("m5x"), "module m5x { }");
|
||||
tb.writeJavaFiles(base.resolve("m6x"), "module m6x { }");
|
||||
compile(base, "--module-source-path", base.toString(),
|
||||
"-d", base.toString());
|
||||
testModuleAttribute(m1, moduleDescriptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenComplexModule(Path base) throws Exception {
|
||||
Path m1 = base.resolve("m1x");
|
||||
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m1x", ModuleFlag.OPEN)
|
||||
.exports("pack1")
|
||||
.exportsTo("packTo1", "m2x")
|
||||
.exportsTo("packTo3", "m3x")
|
||||
.requires("jdk.compiler")
|
||||
.requires("m2x", RequiresFlag.TRANSITIVE)
|
||||
.requires("m3x", RequiresFlag.STATIC)
|
||||
@ -230,9 +329,7 @@ public class ModuleTest extends ModuleTestBase {
|
||||
.requires("m5x", RequiresFlag.STATIC)
|
||||
.requires("m6x", RequiresFlag.TRANSITIVE)
|
||||
.requires("java.compiler")
|
||||
.exportsTo("packTo4", "java.compiler")
|
||||
.exportsTo("packTo2", "java.compiler")
|
||||
.exports("pack4")
|
||||
.exports("pack2")
|
||||
.write(m1);
|
||||
tb.writeJavaFiles(m1, "package pack1; public class C extends java.util.ArrayList{ }",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,6 @@ import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Module_attribute;
|
||||
import com.sun.tools.javac.util.Pair;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
@ -36,11 +35,11 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -74,20 +73,30 @@ public class ModuleTestBase {
|
||||
ClassFile classFile = ClassFile.read(modulePath.resolve("module-info.class"));
|
||||
Module_attribute moduleAttribute = (Module_attribute) classFile.getAttribute("Module");
|
||||
ConstantPool constantPool = classFile.constant_pool;
|
||||
|
||||
testModuleName(moduleDescriptor, moduleAttribute, constantPool);
|
||||
testModuleFlags(moduleDescriptor, moduleAttribute);
|
||||
testRequires(moduleDescriptor, moduleAttribute, constantPool);
|
||||
testExports(moduleDescriptor, moduleAttribute, constantPool);
|
||||
testOpens(moduleDescriptor, moduleAttribute, constantPool);
|
||||
testProvides(moduleDescriptor, moduleAttribute, constantPool);
|
||||
testUses(moduleDescriptor, moduleAttribute, constantPool);
|
||||
}
|
||||
|
||||
private void testModuleName(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
|
||||
tr.checkEquals(constantPool.getModuleInfo(module.module_name).getName(), moduleDescriptor.name, "Unexpected module name");
|
||||
}
|
||||
|
||||
private void testModuleFlags(ModuleDescriptor moduleDescriptor, Module_attribute module) {
|
||||
tr.checkEquals(module.module_flags, moduleDescriptor.flags, "Unexpected module flags");
|
||||
}
|
||||
|
||||
private void testRequires(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
|
||||
tr.checkEquals(module.requires_count, moduleDescriptor.requires.size(), "Wrong amount of requires.");
|
||||
|
||||
List<Pair<String, Integer>> actualRequires = new ArrayList<>();
|
||||
List<Requires> actualRequires = new ArrayList<>();
|
||||
for (Module_attribute.RequiresEntry require : module.requires) {
|
||||
actualRequires.add(Pair.of(
|
||||
require.getRequires(constantPool).replace('/', '.'),
|
||||
actualRequires.add(new Requires(
|
||||
require.getRequires(constantPool),
|
||||
require.requires_flags));
|
||||
}
|
||||
tr.checkContains(actualRequires, moduleDescriptor.requires, "Lists of requires don't match");
|
||||
@ -104,18 +113,36 @@ public class ModuleTestBase {
|
||||
tr.checkEquals(export.exports_to_count, expectedTo.size(), "Wrong amount of exports to");
|
||||
List<String> actualTo = new ArrayList<>();
|
||||
for (int toIdx : export.exports_to_index) {
|
||||
actualTo.add(constantPool.getModuleInfo(toIdx).getName().replace('/', '.'));
|
||||
actualTo.add(constantPool.getModuleInfo(toIdx).getName());
|
||||
}
|
||||
tr.checkContains(actualTo, expectedTo, "Lists of \"exports to\" don't match.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testOpens(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
|
||||
tr.checkEquals(module.opens_count, moduleDescriptor.opens.size(), "Wrong amount of opens.");
|
||||
for (Module_attribute.OpensEntry open : module.opens) {
|
||||
String pkg = constantPool.getPackageInfo(open.opens_index).getName();
|
||||
if (tr.checkTrue(moduleDescriptor.opens.containsKey(pkg), "Unexpected open " + pkg)) {
|
||||
Open expectedOpen = moduleDescriptor.opens.get(pkg);
|
||||
tr.checkEquals(expectedOpen.mask, open.opens_flags, "Wrong open flags");
|
||||
List<String> expectedTo = expectedOpen.to;
|
||||
tr.checkEquals(open.opens_to_count, expectedTo.size(), "Wrong amount of opens to");
|
||||
List<String> actualTo = new ArrayList<>();
|
||||
for (int toIdx : open.opens_to_index) {
|
||||
actualTo.add(constantPool.getModuleInfo(toIdx).getName());
|
||||
}
|
||||
tr.checkContains(actualTo, expectedTo, "Lists of \"opens to\" don't match.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testUses(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
|
||||
tr.checkEquals(module.uses_count, moduleDescriptor.uses.size(), "Wrong amount of uses.");
|
||||
List<String> actualUses = new ArrayList<>();
|
||||
for (int usesIdx : module.uses_index) {
|
||||
String uses = constantPool.getClassInfo(usesIdx).getBaseName().replace('/', '.');
|
||||
String uses = constantPool.getClassInfo(usesIdx).getBaseName();
|
||||
actualUses.add(uses);
|
||||
}
|
||||
tr.checkContains(actualUses, moduleDescriptor.uses, "Lists of uses don't match");
|
||||
@ -131,10 +158,10 @@ public class ModuleTestBase {
|
||||
tr.checkEquals(moduleProvidesCount, moduleDescriptorProvidesCount, "Wrong amount of provides.");
|
||||
Map<String, List<String>> actualProvides = new HashMap<>();
|
||||
for (Module_attribute.ProvidesEntry provide : module.provides) {
|
||||
String provides = constantPool.getClassInfo(provide.provides_index).getBaseName().replace('/', '.');
|
||||
String provides = constantPool.getClassInfo(provide.provides_index).getBaseName();
|
||||
List<String> impls = new ArrayList<>();
|
||||
for (int i = 0; i < provide.with_count; i++) {
|
||||
String with = constantPool.getClassInfo(provide.with_index[i]).getBaseName().replace('/', '.');
|
||||
String with = constantPool.getClassInfo(provide.with_index[i]).getBaseName();
|
||||
impls.add(with);
|
||||
}
|
||||
actualProvides.put(provides, impls);
|
||||
@ -163,9 +190,27 @@ public class ModuleTestBase {
|
||||
int getMask();
|
||||
}
|
||||
|
||||
public enum ModuleFlag implements Mask {
|
||||
OPEN("open", Module_attribute.ACC_OPEN);
|
||||
|
||||
private final String token;
|
||||
private final int mask;
|
||||
|
||||
ModuleFlag(String token, int mask) {
|
||||
this.token = token;
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMask() {
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
|
||||
public enum RequiresFlag implements Mask {
|
||||
TRANSITIVE("transitive", Module_attribute.ACC_TRANSITIVE),
|
||||
STATIC("static", Module_attribute.ACC_STATIC_PHASE);
|
||||
STATIC("static", Module_attribute.ACC_STATIC_PHASE),
|
||||
MANDATED("", Module_attribute.ACC_MANDATED);
|
||||
|
||||
private final String token;
|
||||
private final int mask;
|
||||
@ -181,13 +226,30 @@ public class ModuleTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
public enum ExportFlag implements Mask {
|
||||
public enum ExportsFlag implements Mask {
|
||||
SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
|
||||
|
||||
private final String token;
|
||||
private final int mask;
|
||||
|
||||
ExportFlag(String token, int mask) {
|
||||
ExportsFlag(String token, int mask) {
|
||||
this.token = token;
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMask() {
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
|
||||
public enum OpensFlag implements Mask {
|
||||
SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
|
||||
|
||||
private final String token;
|
||||
private final int mask;
|
||||
|
||||
OpensFlag(String token, int mask) {
|
||||
this.token = token;
|
||||
this.mask = mask;
|
||||
}
|
||||
@ -199,27 +261,64 @@ public class ModuleTestBase {
|
||||
}
|
||||
|
||||
private class Export {
|
||||
String pkg;
|
||||
int mask;
|
||||
List<String> to = new ArrayList<>();
|
||||
private final String pkg;
|
||||
private final int mask;
|
||||
private final List<String> to = new ArrayList<>();
|
||||
|
||||
public Export(String pkg, int mask) {
|
||||
Export(String pkg, int mask) {
|
||||
this.pkg = pkg;
|
||||
this.mask = mask;
|
||||
}
|
||||
}
|
||||
|
||||
private class Open {
|
||||
private final String pkg;
|
||||
private final int mask;
|
||||
private final List<String> to = new ArrayList<>();
|
||||
|
||||
Open(String pkg, int mask) {
|
||||
this.pkg = pkg;
|
||||
this.mask = mask;
|
||||
}
|
||||
}
|
||||
|
||||
private class Requires {
|
||||
private final String module;
|
||||
private final int mask;
|
||||
|
||||
Requires(String module, int mask) {
|
||||
this.module = module;
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Requires requires = (Requires) o;
|
||||
return mask == requires.mask &&
|
||||
Objects.equals(module, requires.module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(module, mask);
|
||||
}
|
||||
}
|
||||
|
||||
protected class ModuleDescriptor {
|
||||
|
||||
private final String name;
|
||||
//pair is name of module and flag(public,mandated,synthetic)
|
||||
private final List<Pair<String, Integer>> requires = new ArrayList<>();
|
||||
private final int flags;
|
||||
|
||||
private final List<Requires> requires = new ArrayList<>();
|
||||
|
||||
{
|
||||
requires.add(new Pair<>("java.base", Module_attribute.ACC_MANDATED));
|
||||
requires.add(new Requires("java.base", computeMask(RequiresFlag.MANDATED)));
|
||||
}
|
||||
|
||||
private final Map<String, Export> exports = new HashMap<>();
|
||||
private final Map<String, Open> opens = new HashMap<>();
|
||||
|
||||
//List of service and implementation
|
||||
private final Map<String, List<String>> provides = new LinkedHashMap<>();
|
||||
@ -227,22 +326,26 @@ public class ModuleTestBase {
|
||||
|
||||
private static final String LINE_END = ";\n";
|
||||
|
||||
StringBuilder content = new StringBuilder("module ");
|
||||
StringBuilder content = new StringBuilder("");
|
||||
|
||||
public ModuleDescriptor(String moduleName) {
|
||||
public ModuleDescriptor(String moduleName, ModuleFlag... flags) {
|
||||
this.name = moduleName;
|
||||
content.append(name).append('{').append('\n');
|
||||
this.flags = computeMask(flags);
|
||||
for (ModuleFlag flag : flags) {
|
||||
content.append(flag.token).append(" ");
|
||||
}
|
||||
content.append("module ").append(moduleName).append('{').append('\n');
|
||||
}
|
||||
|
||||
public ModuleDescriptor requires(String module) {
|
||||
this.requires.add(Pair.of(module, 0));
|
||||
this.requires.add(new Requires(module, 0));
|
||||
content.append(" requires ").append(module).append(LINE_END);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModuleDescriptor requires(String module, RequiresFlag... flags) {
|
||||
this.requires.add(new Pair<>(module, computeMask(flags)));
|
||||
this.requires.add(new Requires(module, computeMask(flags)));
|
||||
|
||||
content.append(" requires ");
|
||||
for (RequiresFlag flag : flags) {
|
||||
@ -253,26 +356,52 @@ public class ModuleTestBase {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModuleDescriptor exports(String pkg, ExportFlag... flags) {
|
||||
this.exports.putIfAbsent(pkg, new Export(pkg, computeMask(flags)));
|
||||
public ModuleDescriptor exports(String pkg, ExportsFlag... flags) {
|
||||
this.exports.put(toInternalForm(pkg), new Export(toInternalForm(pkg), computeMask(flags)));
|
||||
content.append(" exports ");
|
||||
for (ExportFlag flag : flags) {
|
||||
for (ExportsFlag flag : flags) {
|
||||
content.append(flag.token).append(" ");
|
||||
}
|
||||
content.append(pkg).append(LINE_END);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModuleDescriptor exportsTo(String pkg, String to, ExportFlag... flags) {
|
||||
public ModuleDescriptor exportsTo(String pkg, String to, ExportsFlag... flags) {
|
||||
List<String> tos = Pattern.compile(",")
|
||||
.splitAsStream(to)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toList());
|
||||
this.exports.computeIfAbsent(pkg, k -> new Export(pkg, computeMask(flags)))
|
||||
this.exports.compute(toInternalForm(pkg), (k,v) -> new Export(k, computeMask(flags)))
|
||||
.to.addAll(tos);
|
||||
|
||||
content.append(" exports ");
|
||||
for (ExportFlag flag : flags) {
|
||||
for (ExportsFlag flag : flags) {
|
||||
content.append(flag.token).append(" ");
|
||||
}
|
||||
content.append(pkg).append(" to ").append(to).append(LINE_END);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModuleDescriptor opens(String pkg, OpensFlag... flags) {
|
||||
this.opens.put(toInternalForm(pkg), new Open(toInternalForm(pkg), computeMask(flags)));
|
||||
content.append(" opens ");
|
||||
for (OpensFlag flag : flags) {
|
||||
content.append(flag.token).append(" ");
|
||||
}
|
||||
content.append(pkg).append(LINE_END);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModuleDescriptor opensTo(String pkg, String to, OpensFlag... flags) {
|
||||
List<String> tos = Pattern.compile(",")
|
||||
.splitAsStream(to)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toList());
|
||||
this.opens.compute(toInternalForm(pkg), (k,v) -> new Open(toInternalForm(k), computeMask(flags)))
|
||||
.to.addAll(tos);
|
||||
|
||||
content.append(" opens ");
|
||||
for (OpensFlag flag : flags) {
|
||||
content.append(flag.token).append(" ");
|
||||
}
|
||||
content.append(pkg).append(" to ").append(to).append(LINE_END);
|
||||
@ -280,7 +409,10 @@ public class ModuleTestBase {
|
||||
}
|
||||
|
||||
public ModuleDescriptor provides(String provides, String... with) {
|
||||
this.provides.put(provides, Arrays.asList(with));
|
||||
List<String> impls = Arrays.stream(with)
|
||||
.map(this::toInternalForm)
|
||||
.collect(Collectors.toList());
|
||||
this.provides.put(toInternalForm(provides), impls);
|
||||
content.append(" provides ")
|
||||
.append(provides)
|
||||
.append(" with ")
|
||||
@ -290,8 +422,8 @@ public class ModuleTestBase {
|
||||
}
|
||||
|
||||
public ModuleDescriptor uses(String... uses) {
|
||||
Collections.addAll(this.uses, uses);
|
||||
for (String use : uses) {
|
||||
this.uses.add(toInternalForm(use));
|
||||
content.append(" uses ").append(use).append(LINE_END);
|
||||
}
|
||||
return this;
|
||||
@ -305,7 +437,11 @@ public class ModuleTestBase {
|
||||
return this;
|
||||
}
|
||||
|
||||
private int computeMask(Mask[] masks) {
|
||||
private String toInternalForm(String name) {
|
||||
return name.replace('.', '/');
|
||||
}
|
||||
|
||||
private int computeMask(Mask... masks) {
|
||||
return Arrays.stream(masks)
|
||||
.map(Mask::getMask)
|
||||
.reduce((a, b) -> a | b)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -82,7 +82,8 @@ public class TestResult extends TestBase {
|
||||
Set<?> copy = new HashSet<>(expected);
|
||||
copy.removeAll(found);
|
||||
if (!found.containsAll(expected)) {
|
||||
return checkTrue(false, message + " FAIL : not found elements : " + copy);
|
||||
return checkTrue(false, message + " FAIL : not found elements : " + copy + "\n" +
|
||||
"Actual: " + found);
|
||||
} else {
|
||||
return checkTrue(true, message + " PASS : all elements found");
|
||||
}
|
||||
|
124
langtools/test/tools/javac/classreader/FileSystemClosedTest.java
Normal file
124
langtools/test/tools/javac/classreader/FileSystemClosedTest.java
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8147414
|
||||
* @summary java.nio.file.ClosedFileSystemException in javadoc
|
||||
* @library /tools/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @build toolbox.JarTask toolbox.JavacTask toolbox.ToolBox
|
||||
* @run main FileSystemClosedTest
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.ClosedFileSystemException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
import toolbox.ToolBox;
|
||||
import toolbox.JarTask;
|
||||
import toolbox.JavacTask;
|
||||
|
||||
public class FileSystemClosedTest {
|
||||
public static void main(String... args) throws Exception {
|
||||
new FileSystemClosedTest().run();
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
ToolBox tb = new ToolBox();
|
||||
Path jar = createJar(tb);
|
||||
|
||||
Path src = Paths.get("src");
|
||||
tb.writeJavaFiles(src, "class C { p1.C1 c1; }");
|
||||
|
||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
||||
PrintWriter out = new PrintWriter(System.err, true);
|
||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
||||
List<String> options = Arrays.asList("-classpath", jar.toString());
|
||||
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(src.resolve("C.java"));
|
||||
com.sun.source.util.JavacTask task =
|
||||
(com.sun.source.util.JavacTask) comp.getTask(out, fm, null, options, null, files);
|
||||
task.parse();
|
||||
|
||||
Elements elems = task.getElements();
|
||||
|
||||
try {
|
||||
// Use p1, p1.C1 as a control to verify normal behavior
|
||||
PackageElement p1 = elems.getPackageElement("p1");
|
||||
TypeElement p1C1 = elems.getTypeElement("p1.C1");
|
||||
System.err.println("p1: " + p1 + "; p1C1: " + p1C1);
|
||||
if (p1C1 == null) {
|
||||
throw new Exception("p1.C1 not found");
|
||||
}
|
||||
|
||||
// Now repeat for p2, p2.C2, closing the file manager early
|
||||
PackageElement p2 = elems.getPackageElement("p2");
|
||||
System.err.println("closing file manager");
|
||||
fm.close();
|
||||
TypeElement p2C2 = elems.getTypeElement("p2.C2");
|
||||
System.err.println("p2: " + p2 + "; p2C2: " + p2C2);
|
||||
if (p2C2 != null) {
|
||||
throw new Exception("p1.C1 found unexpectedly");
|
||||
}
|
||||
} catch (ClosedFileSystemException e) {
|
||||
throw new Exception("unexpected exception thrown", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Path createJar(ToolBox tb) throws IOException {
|
||||
Path jarSrc = Paths.get("jarSrc");
|
||||
Path jarClasses = Paths.get("jarClasses");
|
||||
Path jar = Paths.get("jar.jar");
|
||||
Files.createDirectories(jarClasses);
|
||||
|
||||
tb.writeJavaFiles(jarSrc,
|
||||
"package p1; public class C1 { }",
|
||||
"package p2; public class C2 { }");
|
||||
|
||||
new JavacTask(tb)
|
||||
.outdir(jarClasses)
|
||||
.files(tb.findJavaFiles(jarSrc))
|
||||
.run()
|
||||
.writeAll();
|
||||
new JarTask(tb)
|
||||
.run("cf", jar.toString(), "-C", jarClasses.toString(), "p1", "p2");
|
||||
|
||||
return jar;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -66,6 +66,7 @@ class Example implements Comparable<Example> {
|
||||
modulePathFiles = new ArrayList<File>();
|
||||
classPathFiles = new ArrayList<File>();
|
||||
additionalFiles = new ArrayList<File>();
|
||||
nonEmptySrcFiles = new ArrayList<File>();
|
||||
|
||||
findFiles(file, srcFiles);
|
||||
for (File f: srcFiles) {
|
||||
@ -99,11 +100,11 @@ class Example implements Comparable<Example> {
|
||||
}
|
||||
}
|
||||
} else if (f.isFile()) {
|
||||
if (f.getName().endsWith(".java")) {
|
||||
files.add(f);
|
||||
} else if (f.getName().equals("modulesourcepath")) {
|
||||
moduleSourcePathDir = f;
|
||||
}
|
||||
if (f.getName().endsWith(".java")) {
|
||||
files.add(f);
|
||||
} else if (f.getName().equals("modulesourcepath")) {
|
||||
moduleSourcePathDir = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,8 +133,10 @@ class Example implements Comparable<Example> {
|
||||
foundInfo(f);
|
||||
runOpts = Arrays.asList(runMatch.group(1).trim().split(" +"));
|
||||
}
|
||||
if (javaPat.matcher(line).matches())
|
||||
if (javaPat.matcher(line).matches()) {
|
||||
nonEmptySrcFiles.add(f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error(e);
|
||||
@ -236,6 +239,7 @@ class Example implements Comparable<Example> {
|
||||
// source for import statements or a magic comment
|
||||
for (File pf: procFiles) {
|
||||
if (pf.getName().equals("CreateBadClassFile.java")) {
|
||||
pOpts.add("--add-modules=jdk.jdeps");
|
||||
pOpts.add("--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED");
|
||||
}
|
||||
}
|
||||
@ -263,7 +267,9 @@ class Example implements Comparable<Example> {
|
||||
if (moduleSourcePathDir != null) {
|
||||
opts.add("--module-source-path");
|
||||
opts.add(moduleSourcePathDir.getPath());
|
||||
files = moduleSourcePathFiles;
|
||||
files = new ArrayList<>();
|
||||
files.addAll(moduleSourcePathFiles);
|
||||
files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
|
||||
}
|
||||
|
||||
if (additionalFiles.size() > 0) {
|
||||
@ -343,6 +349,7 @@ class Example implements Comparable<Example> {
|
||||
List<File> modulePathFiles;
|
||||
List<File> classPathFiles;
|
||||
List<File> additionalFiles;
|
||||
List<File> nonEmptySrcFiles;
|
||||
File infoFile;
|
||||
private List<String> runOpts;
|
||||
private List<String> options;
|
||||
|
@ -103,6 +103,7 @@ compiler.warn.annotation.method.not.found.reason # ClassReader
|
||||
compiler.warn.big.major.version # ClassReader
|
||||
compiler.warn.future.attr # ClassReader
|
||||
compiler.warn.illegal.char.for.encoding
|
||||
compiler.warn.incubating.modules # requires adjusted classfile
|
||||
compiler.warn.invalid.archive.file
|
||||
compiler.warn.override.bridge
|
||||
compiler.warn.position.overflow # CRTable: caused by files with long lines >= 1024 chars
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,5 +24,3 @@
|
||||
// key: compiler.warn.dir.path.element.not.directory
|
||||
// options: -Xlint:path
|
||||
// run: simple
|
||||
|
||||
class DirPathElementNotDirectory { }
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,5 +22,3 @@
|
||||
*/
|
||||
|
||||
// key: compiler.err.unnamed.pkg.not.allowed.named.modules
|
||||
|
||||
class UnnamedPackageInNamedModule {}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user