This commit is contained in:
Jonathan Gibbons 2016-05-26 10:46:21 -07:00
commit a8abf4d482
19 changed files with 514 additions and 142 deletions
langtools
.hgtags
make
src
java.compiler/share/classes/javax/annotation/processing
jdk.compiler/share/classes/com/sun/tools/javac
jdk.jshell/share/classes/jdk/internal/jshell/jdi
test

@ -362,3 +362,4 @@ cba09a2e6ae969b029783eb59bb01017b78f8eef jdk-9+114
59adcdd0cd3b6724b4fc0083c258bf4682689f2f jdk-9+117
59a16fa5dedea9ff5bea0a501e4d0d40193426f3 jdk-9+118
6347efd1be03b4fdcf18f64c4fe4be5f60c0831a jdk-9+119
0f81cdd51b42ad38fbceae40985e9bd0bca12180 jdk-9+120

@ -89,11 +89,17 @@
</pathconvert>
<pathconvert property="xpatch.rest" pathsep=" -Xpatch:">
<regexpmapper from="${file.separator}([^${file.separator}]+)$" to='\1="${build.modules}${file.separator}\1"' />
<dirset dir="${src.dir}" includes="*.*"/>
</pathconvert>
<pathconvert property="xpatch.noquotes.rest" pathsep=" -Xpatch:">
<regexpmapper from="${file.separator}([^${file.separator}]+)$" to="\1=${build.modules}${file.separator}\1" />
<dirset dir="${src.dir}" includes="*.*"/>
</pathconvert>
<property name="xpatch.cmd" value="-Xpatch:${xpatch.rest}"/>
<property name="xpatch.noquotes.cmd" value="-Xpatch:${xpatch.noquotes.rest}"/>
<!-- java.marker is set to a marker file to check for within a Java install dir.
The best file to check for across Solaris/Linux/Windows/MacOS is one of the
@ -341,7 +347,7 @@
jdk="@{jdk}"
agentvm="@{agentvm}" verbose="@{verbose}"
failonerror="false" resultproperty="jtreg.@{name}.result"
vmoptions="${coverage.options} @{extra.jvmargs} ${xpatch.cmd}">
vmoptions="${coverage.options} @{extra.jvmargs} ${xpatch.noquotes.cmd}">
<arg value="-debug:@{jpda.jvmargs}"/>
<arg line="@{keywords}"/>
<arg line="@{options}"/>

@ -2,7 +2,7 @@
<configuration default="false" name="javac" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javac.Main" />
<option name="VM_PARAMETERS" value="@XPATCH@" />
<option name="VM_PARAMETERS" value='@XPATCH@' />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />

@ -2,7 +2,7 @@
<configuration default="false" name="javadoc" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javadoc.Main" />
<option name="VM_PARAMETERS" value="@XPATCH@" />
<option name="VM_PARAMETERS" value='@XPATCH@' />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />

@ -2,7 +2,7 @@
<configuration default="false" name="javah" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javah.Main" />
<option name="VM_PARAMETERS" value="@XPATCH@ -XaddExports:jdk.compiler/com.sun.tools.javah=ALL-UNNAMED" />
<option name="VM_PARAMETERS" value='@XPATCH@ -XaddExports:jdk.compiler/com.sun.tools.javah=ALL-UNNAMED' />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />

@ -2,7 +2,7 @@
<configuration default="false" name="javap" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javap.Main" />
<option name="VM_PARAMETERS" value="@XPATCH@ -XaddExports:jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED" />
<option name="VM_PARAMETERS" value='@XPATCH@ -XaddExports:jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED' />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />

@ -2,7 +2,7 @@
<configuration default="false" name="jshell" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="jdk.internal.jshell.tool.JShellTool" />
<option name="VM_PARAMETERS" value="@XPATCH@ -XaddExports:jdk.jshell/jdk.internal.jshell.tool=ALL-UNNAMED" />
<option name="VM_PARAMETERS" value='@XPATCH@ -XaddExports:jdk.jshell/jdk.internal.jshell.tool=ALL-UNNAMED' />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />

@ -2,7 +2,7 @@
<configuration default="false" name="sjavac" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.sun.tools.sjavac.Main" />
<option name="VM_PARAMETERS" value="@XPATCH@ -XaddExports:jdk.compiler/com.sun.tools.sjavac=ALL-UNNAMED" />
<option name="VM_PARAMETERS" value='@XPATCH@ -XaddExports:jdk.compiler/com.sun.tools.sjavac=ALL-UNNAMED' />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />

@ -48,4 +48,4 @@ done
unset DUALCASE
IFS=$nl
"#TARGET_JAVA#" "#XPATCH#" ${ea} ${javaOpts} #PROGRAM# ${toolOpts}
"#TARGET_JAVA#" #XPATCH# ${ea} ${javaOpts} #PROGRAM# ${toolOpts}

@ -27,6 +27,8 @@ package javax.annotation.processing;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import java.util.LinkedHashSet;
import java.util.Collections;
import java.util.Set;
import java.lang.annotation.Annotation;
@ -91,6 +93,38 @@ public interface RoundEnvironment {
*/
Set<? extends Element> getElementsAnnotatedWith(TypeElement a);
/**
* Returns the elements annotated with one or more of the given
* annotation types.
*
* @apiNote This method may be useful when processing repeating
* annotations by looking for an annotation type and its
* containing annotation type at the same time.
*
* @implSpec The default implementation of this method creates an
* empty result set, iterates over the annotations in the argument
* set calling {@link #getElementsAnnotatedWith(TypeElement)} on
* each annotation and adding those results to the result
* set. Finally, the contents of the result set are returned as an
* unmodifiable set.
*
* @param annotations annotation types being requested
* @return the elements annotated with one or more of the given
* annotation types, or an empty set if there are none
* @throws IllegalArgumentException if the any elements of the
* argument set do not represent an annotation type
* @jls 9.6.3 Repeatable Annotation Types
* @since 9
*/
default Set<? extends Element> getElementsAnnotatedWithAny(TypeElement... annotations){
// Use LinkedHashSet rather than HashSet for predictability
Set<Element> result = new LinkedHashSet<>();
for (TypeElement annotation : annotations) {
result.addAll(getElementsAnnotatedWith(annotation));
}
return Collections.unmodifiableSet(result);
}
/**
* Returns the elements annotated with the given annotation type.
* The annotation may appear directly or be inherited. Only
@ -110,4 +144,36 @@ public interface RoundEnvironment {
* represent an annotation type
*/
Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a);
/**
* Returns the elements annotated with one or more of the given
* annotation types.
*
* @apiNote This method may be useful when processing repeating
* annotations by looking for an annotation type and its
* containing annotation type at the same time.
*
* @implSpec The default implementation of this method creates an
* empty result set, iterates over the annotations in the argument
* set calling {@link #getElementsAnnotatedWith(Class)} on
* each annotation and adding those results to the result
* set. Finally, the contents of the result set are returned as an
* unmodifiable set.
*
* @param annotations annotation types being requested
* @return the elements annotated with one or more of the given
* annotation types, or an empty set if there are none
* @throws IllegalArgumentException if the any elements of the
* argument set do not represent an annotation type
* @jls 9.6.3 Repeatable Annotation Types
* @since 9
*/
default Set<? extends Element> getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations){
// Use LinkedHashSet rather than HashSet for predictability
Set<Element> result = new LinkedHashSet<>();
for (Class<? extends Annotation> annotation : annotations) {
result.addAll(getElementsAnnotatedWith(annotation));
}
return Collections.unmodifiableSet(result);
}
}

@ -811,6 +811,7 @@ public class Attr extends JCTree.Visitor {
DiagnosticPosition prevLintPos
= deferredLintHandler.setPos(variable.pos());
final JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
try {
Type itype = attribExpr(variable.init, env, type);
if (itype.constValue() != null) {
@ -819,6 +820,7 @@ public class Attr extends JCTree.Visitor {
return null;
}
} finally {
log.useSource(prevSource);
deferredLintHandler.setPos(prevLintPos);
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 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
@ -51,6 +51,7 @@ public class JavacRoundEnvironment implements RoundEnvironment {
private final boolean processingOver;
private final boolean errorRaised;
private final ProcessingEnvironment processingEnv;
private final Elements eltUtils;
// Caller must pass in an immutable set
private final Set<? extends Element> rootElements;
@ -63,6 +64,7 @@ public class JavacRoundEnvironment implements RoundEnvironment {
this.errorRaised = errorRaised;
this.rootElements = rootElements;
this.processingEnv = processingEnv;
this.eltUtils = processingEnv.getElementUtils();
}
public String toString() {
@ -100,9 +102,6 @@ public class JavacRoundEnvironment implements RoundEnvironment {
return rootElements;
}
private static final String NOT_AN_ANNOTATION_TYPE =
"The argument does not represent an annotation type: ";
/**
* Returns the elements annotated with the given annotation type.
* Only type elements <i>included</i> in this round of annotation
@ -117,10 +116,9 @@ public class JavacRoundEnvironment implements RoundEnvironment {
*/
@DefinedBy(Api.ANNOTATION_PROCESSING)
public Set<? extends Element> getElementsAnnotatedWith(TypeElement a) {
Set<Element> result = Collections.emptySet();
if (a.getKind() != ElementKind.ANNOTATION_TYPE)
throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
throwIfNotAnnotation(a);
Set<Element> result = Collections.emptySet();
ElementScanner9<Set<Element>, TypeElement> scanner =
new AnnotationSetScanner(result);
@ -130,41 +128,93 @@ public class JavacRoundEnvironment implements RoundEnvironment {
return result;
}
@DefinedBy(Api.ANNOTATION_PROCESSING)
public Set<? extends Element> getElementsAnnotatedWithAny(TypeElement... annotations) {
// Don't bother to special-case annotations.length == 1 as
// return getElementsAnnotatedWith(annotations[0]);
Set<TypeElement> annotationSet = new LinkedHashSet<>(annotations.length);
for (TypeElement annotation : annotations) {
throwIfNotAnnotation(annotation);
annotationSet.add(annotation);
}
Set<Element> result = Collections.emptySet();
ElementScanner9<Set<Element>, Set<TypeElement>> scanner =
new AnnotationSetMultiScanner(result);
for (Element element : rootElements)
result = scanner.scan(element, annotationSet);
return result;
}
// Could be written as a local class inside getElementsAnnotatedWith
private class AnnotationSetScanner extends
ElementScanner9<Set<Element>, TypeElement> {
ElementScanningIncludingTypeParameters<Set<Element>, TypeElement> {
// Insertion-order preserving set
Set<Element> annotatedElements = new LinkedHashSet<>();
private Set<Element> annotatedElements = new LinkedHashSet<>();
AnnotationSetScanner(Set<Element> defaultSet) {
super(defaultSet);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public Set<Element> visitType(TypeElement e, TypeElement p) {
public Set<Element> scan(Element e, TypeElement annotation) {
for (AnnotationMirror annotMirror : eltUtils.getAllAnnotationMirrors(e)) {
if (annotation.equals(mirrorAsElement(annotMirror))) {
annotatedElements.add(e);
break;
}
}
e.accept(this, annotation);
return annotatedElements;
}
}
// Could be written as a local class inside getElementsAnnotatedWithAny
private class AnnotationSetMultiScanner extends
ElementScanningIncludingTypeParameters<Set<Element>, Set<TypeElement>> {
// Insertion-order preserving set
private Set<Element> annotatedElements = new LinkedHashSet<>();
AnnotationSetMultiScanner(Set<Element> defaultSet) {
super(defaultSet);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public Set<Element> scan(Element e, Set<TypeElement> annotations) {
for (AnnotationMirror annotMirror : eltUtils.getAllAnnotationMirrors(e)) {
if (annotations.contains(mirrorAsElement(annotMirror))) {
annotatedElements.add(e);
break;
}
}
e.accept(this, annotations);
return annotatedElements;
}
}
private static abstract class ElementScanningIncludingTypeParameters<R, P>
extends ElementScanner9<R, P> {
protected ElementScanningIncludingTypeParameters(R defaultValue) {
super(defaultValue);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public R visitType(TypeElement e, P p) {
// Type parameters are not considered to be enclosed by a type
scan(e.getTypeParameters(), p);
return super.visitType(e, p);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public Set<Element> visitExecutable(ExecutableElement e, TypeElement p) {
public R visitExecutable(ExecutableElement e, P p) {
// Type parameters are not considered to be enclosed by an executable
scan(e.getTypeParameters(), p);
return super.visitExecutable(e, p);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public Set<Element> scan(Element e, TypeElement p) {
java.util.List<? extends AnnotationMirror> annotationMirrors =
processingEnv.getElementUtils().getAllAnnotationMirrors(e);
for (AnnotationMirror annotationMirror : annotationMirrors) {
if (p.equals(annotationMirror.getAnnotationType().asElement()))
annotatedElements.add(e);
}
e.accept(this, p);
return annotatedElements;
}
}
/**
@ -172,17 +222,48 @@ public class JavacRoundEnvironment implements RoundEnvironment {
*/
@DefinedBy(Api.ANNOTATION_PROCESSING)
public Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a) {
if (!a.isAnnotation())
throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
throwIfNotAnnotation(a);
String name = a.getCanonicalName();
if (name == null)
return Collections.emptySet();
else {
TypeElement annotationType = processingEnv.getElementUtils().getTypeElement(name);
TypeElement annotationType = eltUtils.getTypeElement(name);
if (annotationType == null)
return Collections.emptySet();
else
return getElementsAnnotatedWith(annotationType);
}
}
@DefinedBy(Api.ANNOTATION_PROCESSING)
public Set<? extends Element> getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations) {
List<TypeElement> annotationsAsElements = new ArrayList<>(annotations.size());
for (Class<? extends Annotation> annotation : annotations) {
throwIfNotAnnotation(annotation);
String name = annotation.getCanonicalName();
if (name == null)
continue;
annotationsAsElements.add(eltUtils.getTypeElement(name));
}
return getElementsAnnotatedWithAny(annotationsAsElements.toArray(new TypeElement[0]));
}
private Element mirrorAsElement(AnnotationMirror annotationMirror) {
return annotationMirror.getAnnotationType().asElement();
}
private static final String NOT_AN_ANNOTATION_TYPE =
"The argument does not represent an annotation type: ";
private void throwIfNotAnnotation(Class<? extends Annotation> a) {
if (!a.isAnnotation())
throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
}
private void throwIfNotAnnotation(TypeElement a) {
if (a.getKind() != ElementKind.ANNOTATION_TYPE)
throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
}
}

@ -50,6 +50,7 @@ import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
class JDIConnection {
private VirtualMachine vm;
private boolean active = true;
private Process process = null;
private int outputCompleteCount = 0;
@ -175,6 +176,11 @@ class JDIConnection {
return process != null && process.isAlive();
}
// Beginning shutdown, ignore any random dying squeals
void beginShutdown() {
active = false;
}
public synchronized void disposeVM() {
try {
if (vm != null) {
@ -233,14 +239,19 @@ class JDIConnection {
int i;
try {
while ((i = in.read()) != -1) {
pStream.print((char) i);
// directly copy input to output, but skip if asked to close
if (active) {
pStream.print((char) i);
}
}
} catch (IOException ex) {
String s = ex.getMessage();
if (!s.startsWith("Bad file number")) {
if (active && !s.startsWith("Bad file number")) {
throw ex;
}
// else we got a Bad file number IOException which just means
// else we are being shutdown (and don't want any spurious death
// throws to ripple) or
// we got a Bad file number IOException which just means
// that the debuggee has gone away. We'll just treat it the
// same as if we got an EOF.
}

@ -109,11 +109,14 @@ public class JDIExecutionControl implements ExecutionControl {
@Override
public void close() {
try {
JDIConnection c = jdiEnv.connection();
if (c != null) {
c.beginShutdown();
}
if (remoteOut != null) {
remoteOut.writeInt(CMD_EXIT);
remoteOut.flush();
}
JDIConnection c = jdiEnv.connection();
if (c != null) {
c.disposeVM();
}

@ -34,7 +34,6 @@
*/
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
@ -48,85 +47,76 @@ import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class StartOptionTest {
private ByteArrayOutputStream out;
private ByteArrayOutputStream err;
private ByteArrayOutputStream cmdout;
private ByteArrayOutputStream cmderr;
private ByteArrayOutputStream console;
private ByteArrayOutputStream userout;
private ByteArrayOutputStream usererr;
private JShellTool getShellTool() {
class NoOutputAllowedStream extends OutputStream {
private final String label;
NoOutputAllowedStream(String label) {
this.label = label;
}
@Override
public void write(int b) { fail("Unexpected output to: " + label); }
}
return new JShellTool(
new TestingInputStream(),
new PrintStream(out),
new PrintStream(err),
new PrintStream(new NoOutputAllowedStream("console")),
new PrintStream(cmdout),
new PrintStream(cmderr),
new PrintStream(console),
new TestingInputStream(),
new PrintStream(new NoOutputAllowedStream("userout")),
new PrintStream(new NoOutputAllowedStream("usererr")),
new PrintStream(userout),
new PrintStream(usererr),
new ReplToolTesting.MemoryPreferences(),
Locale.ROOT);
}
private String getOutput() {
byte[] bytes = out.toByteArray();
out.reset();
return new String(bytes, StandardCharsets.UTF_8);
}
private String getError() {
byte[] bytes = err.toByteArray();
err.reset();
return new String(bytes, StandardCharsets.UTF_8);
private void check(ByteArrayOutputStream str, Consumer<String> checkOut, String label) {
byte[] bytes = str.toByteArray();
str.reset();
String out = new String(bytes, StandardCharsets.UTF_8);
if (checkOut != null) {
checkOut.accept(out);
} else {
assertEquals("", out, label + ": Expected empty -- ");
}
}
private void start(Consumer<String> checkOutput, Consumer<String> checkError, String... args) throws Exception {
JShellTool tool = getShellTool();
tool.start(args);
if (checkOutput != null) {
checkOutput.accept(getOutput());
} else {
assertEquals("", getOutput(), "Output: ");
}
if (checkError != null) {
checkError.accept(getError());
} else {
assertEquals("", getError(), "Error: ");
}
check(cmdout, checkOutput, "cmdout");
check(cmderr, checkError, "cmderr");
check(console, null, "console");
check(userout, null, "userout");
check(usererr, null, "usererr");
}
private void start(String expectedOutput, String expectedError, String... args) throws Exception {
start(s -> assertEquals(s.trim(), expectedOutput, "Output: "), s -> assertEquals(s.trim(), expectedError, "Error: "), args);
start(s -> assertEquals(s.trim(), expectedOutput, "cmdout: "), s -> assertEquals(s.trim(), expectedError, "cmderr: "), args);
}
@BeforeMethod
public void setUp() {
out = new ByteArrayOutputStream();
err = new ByteArrayOutputStream();
cmdout = new ByteArrayOutputStream();
cmderr = new ByteArrayOutputStream();
console = new ByteArrayOutputStream();
userout = new ByteArrayOutputStream();
usererr = new ByteArrayOutputStream();
}
@Test
public void testUsage() throws Exception {
start(s -> {
assertTrue(s.split("\n").length >= 7, s);
assertTrue(s.startsWith("Usage: jshell <options>"), s);
assertTrue(s.split("\n").length >= 7, "Not enough usage lines: " + s);
assertTrue(s.startsWith("Usage: jshell <options>"), "Unexpect usage start: " + s);
}, null, "-help");
}
@Test
public void testUnknown() throws Exception {
start(s -> {
assertTrue(s.split("\n").length >= 7, s);
assertTrue(s.startsWith("Usage: jshell <options>"), s);
assertTrue(s.split("\n").length >= 7, "Not enough usage lines (unknown): " + s);
assertTrue(s.startsWith("Usage: jshell <options>"), "Unexpect usage start (unknown): " + s);
}, s -> assertEquals(s.trim(), "Unknown option: -unknown"), "-unknown");
}
@ -157,12 +147,15 @@ public class StartOptionTest {
@Test
public void testVersion() throws Exception {
start(s -> assertTrue(s.startsWith("jshell")), null, "-version");
start(s -> assertTrue(s.startsWith("jshell"), "unexpected version: " + s), null, "-version");
}
@AfterMethod
public void tearDown() {
out = null;
err = null;
cmdout = null;
cmderr = null;
console = null;
userout = null;
usererr = null;
}
}

@ -0,0 +1,33 @@
/*
* 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 8154052
* @summary Java compiler error displays line from the wrong file
* @compile/fail/ref=EagerInitCheck.out -XDrawDiagnostics EagerInitCheck.java
*/
public class EagerInitCheck implements IEagerInitCheck {
float x = VAL;
}

@ -0,0 +1,2 @@
IEagerInitCheck.java:25:17: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: double, float)
1 error

@ -0,0 +1,26 @@
/*
* 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.
*/
public interface IEagerInitCheck {
float VAL = 1.0;
}

@ -23,7 +23,7 @@
/*
* @test
* @bug 6397298 6400986 6425592 6449798 6453386 6508401 6498938 6911854 8030049 8038080
* @bug 6397298 6400986 6425592 6449798 6453386 6508401 6498938 6911854 8030049 8038080 8032230
* @summary Tests that getElementsAnnotatedWith works properly.
* @author Joseph D. Darcy
* @library /tools/javac/lib
@ -51,69 +51,183 @@ import java.util.Collections;
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;
import java.util.Objects;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
import static javax.lang.model.util.ElementFilter.*;
/**
* This processor verifies that the information returned by
* getElementsAnnotatedWith is consistent with the expected results
* stored in an AnnotatedElementInfo annotation.
* getElementsAnnotatedWith and getElementsAnnotatedWithAny is
* consistent with the expected results stored in an
* AnnotatedElementInfo annotation.
*/
@AnnotatedElementInfo(annotationName="java.lang.SuppressWarnings", expectedSize=0, names={})
public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor {
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnvironment) {
TypeElement annotatedElementInfoElement =
elements.getTypeElement("AnnotatedElementInfo");
Set<? extends Element> resultsMeta = Collections.emptySet();
Set<? extends Element> resultsBase = Collections.emptySet();
RoundEnvironment roundEnv) {
// First check sets of annotated elements using the round
// environment from the annotation processing tool framework.
checkSetOfAnnotatedElements(roundEnv);
if (!roundEnvironment.processingOver()) {
testNonAnnotations(roundEnvironment);
// Next check sets of annotated elements using a round
// environment which uses the default implementations of the
// getElementsAnnotatedWithAny methods from the interface.
checkSetOfAnnotatedElements(new TestingRoundEnvironment(roundEnv));
return true;
}
/**
* To allow testing of the executable code of the default methods
* for the two overloaded getElementsAnnotatedWithAny methods
* defined in the RoundEnvironment interface, this class delegates
* the non-default methods of RoundEnvironment to a given
* RoundEnvironment object and then explicitly calls the default
* methods of the interface instead of relying on the object's
* implementation of those methods.
*/
private class TestingRoundEnvironment implements RoundEnvironment {
private RoundEnvironment re;
public TestingRoundEnvironment(RoundEnvironment re) {
this.re = re;
}
@Override
public boolean errorRaised() {
return re.errorRaised();
}
@Override
public Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a) {
return re.getElementsAnnotatedWith(a);
}
@Override
public Set<? extends Element> getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> a) {
// Default method defined in the interface
return RoundEnvironment.super.getElementsAnnotatedWithAny(a);
}
@Override
public Set<? extends Element> getElementsAnnotatedWith(TypeElement a) {
return re.getElementsAnnotatedWith(a);
}
@Override
public Set<? extends Element> getElementsAnnotatedWithAny(TypeElement... a) {
// Default method defined in the interface
return RoundEnvironment.super.getElementsAnnotatedWithAny(a);
}
@Override
public Set<? extends Element> getRootElements() {
return re.getRootElements();
}
@Override
public boolean processingOver() {
return re.processingOver();
}
}
/**
* The method checks the following conditions:
*
* 1) The sets of elements found are equal for the TypeElement and
* Class<? extends Annotation> methods on logically equivalent
* arguments.
*
* 2) getElementsAnnotatedWithAny(X) is equal to
* getElementsAnnotatedWith(X') where X is a set/var-args array
* with one element and X' is the element.
*
* 3) Verify the result of getElementsAnnotatedWithAny({X, Y}) is equal to
* getElementsAnnotatedWith(X) UNION getElementsAnnotatedWith(Y).
*/
void checkSetOfAnnotatedElements(RoundEnvironment re) {
TypeElement annotatedElemInfoElem = elements.getTypeElement("AnnotatedElementInfo");
// For the "Any" methods, search for both the expected
// annotation and AnnotatedElementInfo and verify the return
// set is the union of searching for AnnotatedElementInfo and
// the other annotation
Set<? extends Element> resultsMeta = Collections.emptySet();
Set<? extends Element> resultsMetaAny = Collections.emptySet();
Set<Element> resultsMetaMulti = new HashSet<>();
Set<? extends Element> resultsMetaAnyMulti = Collections.emptySet();
Set<? extends Element> resultsBase = Collections.emptySet();
Set<? extends Element> resultsBaseAny = Collections.emptySet();
Set<? extends Element> resultsBaseAnyMulti = Collections.emptySet();
if (!re.processingOver()) {
testNonAnnotations(re);
// Verify AnnotatedElementInfo is present on the first
// specified type.
TypeElement firstType = typesIn(roundEnvironment.getRootElements()).iterator().next();
TypeElement firstType = typesIn(re.getRootElements()).iterator().next();
AnnotatedElementInfo annotatedElementInfo = firstType.getAnnotation(AnnotatedElementInfo.class);
AnnotatedElementInfo annotatedElemInfo =
firstType.getAnnotation(AnnotatedElementInfo.class);
boolean failed = false;
if (annotatedElementInfo == null)
throw new IllegalArgumentException("Missing AnnotatedElementInfo annotation on " +
firstType);
else {
// Verify that the annotation information is as
// expected.
Objects.requireNonNull(annotatedElemInfo,
"Missing AnnotatedElementInfo annotation on " + firstType);
Set<String> expectedNames = new HashSet<String>(Arrays.asList(annotatedElementInfo.names()));
// Verify that the annotation information is as expected.
Set<String> expectedNames =
new HashSet<>(Arrays.asList(annotatedElemInfo.names()));
resultsMeta =
roundEnvironment.
getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName()));
String annotationName = annotatedElemInfo.annotationName();
TypeElement annotationTypeElem = elements.getTypeElement(annotationName);
if (!resultsMeta.isEmpty())
System.err.println("Results: " + resultsMeta);
resultsMeta = re.getElementsAnnotatedWith(annotationTypeElem);
resultsMetaAny = re.getElementsAnnotatedWithAny(annotationTypeElem);
resultsMetaMulti.addAll(resultsMeta);
resultsMetaMulti.addAll(re.getElementsAnnotatedWith(annotatedElemInfoElem));
resultsMetaAnyMulti = re.getElementsAnnotatedWithAny(annotationTypeElem, annotatedElemInfoElem);
if (resultsMeta.size() != annotatedElementInfo.expectedSize()) {
failed = true;
System.err.printf("Bad number of elements; expected %d, got %d%n",
annotatedElementInfo.expectedSize(), resultsMeta.size());
} else {
for(Element element : resultsMeta) {
String simpleName = element.getSimpleName().toString();
if (!expectedNames.contains(simpleName) ) {
failed = true;
System.err.println("Name ``" + simpleName + "'' not expected.");
}
if (!resultsMeta.isEmpty())
System.err.println("Results: " + resultsMeta);
if (!resultsMeta.equals(resultsMetaAny)) {
failed = true;
System.err.printf("Inconsistent Meta with vs withAny results");
}
if (resultsMeta.size() != annotatedElemInfo.expectedSize()) {
failed = true;
System.err.printf("Bad number of elements; expected %d, got %d%n",
annotatedElemInfo.expectedSize(), resultsMeta.size());
} else {
for(Element element : resultsMeta) {
String simpleName = element.getSimpleName().toString();
if (!expectedNames.contains(simpleName) ) {
failed = true;
System.err.println("Name ``" + simpleName + "'' not expected.");
}
}
}
resultsBase = computeResultsBase(roundEnvironment, annotatedElementInfo.annotationName());
resultsBase = computeResultsBase(re, annotationName);
resultsBaseAny = computeResultsBaseAny(re, annotationName);
try {
Set<Class<? extends Annotation>> tmp = new HashSet<>();
tmp.add(AnnotatedElementInfo.class);
tmp.add(Class.forName(annotationName).asSubclass(Annotation.class));
resultsBaseAnyMulti = re.getElementsAnnotatedWithAny(tmp);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
if (!resultsBase.equals(resultsBaseAny)) {
failed = true;
System.err.printf("Inconsistent Base with vs withAny results");
}
if (!resultsMeta.equals(resultsBase)) {
failed = true;
@ -121,29 +235,53 @@ public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor {
"\nbase: " + resultsBase);
}
if (!resultsMetaAnyMulti.equals(resultsMetaMulti)) {
failed = true;
System.err.println("MetaMultAny and MetaMulti sets unequal;\n meta: " + resultsMeta +
"\nbase: " + resultsBase);
}
if (!resultsBaseAnyMulti.equals(resultsMetaAnyMulti)) {
failed = true;
System.err.println("BaseMulti and MetaMulti sets unequal;\n meta: " + resultsMeta +
"\nbase: " + resultsBase);
}
if (failed) {
System.err.println("AnnotatedElementInfo: " + annotatedElementInfo);
System.err.println("AnnotatedElementInfo: " + annotatedElemInfo);
throw new RuntimeException();
}
} else {
// If processing is over without an error, the specified
// elements should be empty so an empty set should be returned.
resultsMeta = roundEnvironment.getElementsAnnotatedWith(annotatedElementInfoElement);
resultsBase = roundEnvironment.getElementsAnnotatedWith(AnnotatedElementInfo.class);
if (!resultsMeta.isEmpty())
throw new RuntimeException("Nonempty resultsMeta: " + resultsMeta);
if (!resultsBase.isEmpty())
throw new RuntimeException("Nonempty resultsBase: " + resultsBase);
// elements should be empty so an empty set should be
// returned.
throwOnNonEmpty(re.getElementsAnnotatedWith(annotatedElemInfoElem), "resultsMeta");
throwOnNonEmpty(re.getElementsAnnotatedWithAny(annotatedElemInfoElem), "resultsMetaAny");
throwOnNonEmpty(re.getElementsAnnotatedWith(AnnotatedElementInfo.class), "resultsBase");
throwOnNonEmpty(re.getElementsAnnotatedWithAny(Set.of(AnnotatedElementInfo.class)), "resultsBaseAny");
}
return true;
}
private Set<? extends Element> computeResultsBase(RoundEnvironment roundEnvironment, String name) {
private void throwOnNonEmpty(Set<? extends Element> results, String message) {
if (!results.isEmpty()) {
throw new RuntimeException("Nonempty " + message + "\t" + results);
}
}
private Set<? extends Element> computeResultsBase(RoundEnvironment roundEnv, String name) {
try {
return roundEnvironment.
return roundEnv.
getElementsAnnotatedWith(Class.forName(name).asSubclass(Annotation.class));
} catch(ClassNotFoundException cnfe) {
} catch (ClassNotFoundException cnfe) {
throw new RuntimeException(cnfe);
}
}
private Set<? extends Element> computeResultsBaseAny(RoundEnvironment roundEnv, String name) {
try {
return roundEnv.
getElementsAnnotatedWithAny(Set.of(Class.forName(name).asSubclass(Annotation.class)));
} catch (ClassNotFoundException cnfe) {
throw new RuntimeException(cnfe);
}
}
@ -152,18 +290,28 @@ public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor {
* Verify non-annotation types result in
* IllegalArgumentExceptions.
*/
private void testNonAnnotations(RoundEnvironment roundEnvironment) {
private void testNonAnnotations(RoundEnvironment roundEnv) {
Class objectClass = (Class)Object.class;
Set<? extends Element> elements;
try {
Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith((Class)Object.class );
elements = roundEnv.getElementsAnnotatedWith(objectClass);
throw new RuntimeException("Illegal argument exception not thrown");
} catch(IllegalArgumentException iae) {}
} catch (IllegalArgumentException iae) {}
try {
Set<? extends Element> elements =
roundEnvironment.getElementsAnnotatedWith(processingEnv.
getElementUtils().
getTypeElement("java.lang.Object") );
elements = roundEnv.getElementsAnnotatedWithAny(Set.of(objectClass));
throw new RuntimeException("Illegal argument exception not thrown");
} catch(IllegalArgumentException iae) {}
} catch (IllegalArgumentException iae) {}
TypeElement objectElement = processingEnv.getElementUtils().getTypeElement("java.lang.Object");
try {
elements = roundEnv.getElementsAnnotatedWith(objectElement);
throw new RuntimeException("Illegal argument exception not thrown");
} catch (IllegalArgumentException iae) {}
try {
elements = roundEnv.getElementsAnnotatedWithAny(objectElement);
throw new RuntimeException("Illegal argument exception not thrown");
} catch (IllegalArgumentException iae) {}
}
}