8005167: execution time of combo tests in javac should be improved
Reviewed-by: jjg, jjh
This commit is contained in:
parent
5ee942d5a8
commit
9d4f6a0ebe
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,14 +26,19 @@
|
|||||||
* @bug 6769027
|
* @bug 6769027
|
||||||
* @summary Source line should be displayed immediately after the first diagnostic line
|
* @summary Source line should be displayed immediately after the first diagnostic line
|
||||||
* @author Maurizio Cimadamore
|
* @author Maurizio Cimadamore
|
||||||
|
* @library ../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
* @run main/othervm T6769027
|
* @run main/othervm T6769027
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import javax.tools.*;
|
import javax.tools.*;
|
||||||
import com.sun.tools.javac.util.*;
|
import com.sun.tools.javac.util.*;
|
||||||
|
|
||||||
public class T6769027 {
|
public class T6769027
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
|
implements Runnable {
|
||||||
|
|
||||||
enum OutputKind {
|
enum OutputKind {
|
||||||
RAW("rawDiagnostics","rawDiagnostics"),
|
RAW("rawDiagnostics","rawDiagnostics"),
|
||||||
@ -314,7 +319,7 @@ public class T6769027 {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected java.io.PrintWriter getWriterForDiagnosticType(JCDiagnostic.DiagnosticType dt) {
|
protected java.io.PrintWriter getWriterForDiagnosticType(JCDiagnostic.DiagnosticType dt) {
|
||||||
return new java.io.PrintWriter(System.out);
|
return outWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -323,13 +328,42 @@ public class T6769027 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int nerrors = 0;
|
OutputKind outputKind;
|
||||||
|
ErrorKind errorKind;
|
||||||
|
MultilineKind multiKind;
|
||||||
|
MultilinePolicy multiPolicy;
|
||||||
|
PositionKind posKind;
|
||||||
|
XDiagsSource xdiagsSource;
|
||||||
|
XDiagsCompact xdiagsCompact;
|
||||||
|
CaretKind caretKind;
|
||||||
|
SourceLineKind sourceLineKind;
|
||||||
|
IndentKind summaryIndent;
|
||||||
|
IndentKind detailsIndent;
|
||||||
|
IndentKind sourceIndent;
|
||||||
|
IndentKind subdiagsIndent;
|
||||||
|
|
||||||
void exec(OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
|
T6769027(OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
|
||||||
MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
|
MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
|
||||||
XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
|
XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
|
||||||
IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
|
IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
|
||||||
IndentKind subdiagsIndent) {
|
IndentKind subdiagsIndent) {
|
||||||
|
this.outputKind = outputKind;
|
||||||
|
this.errorKind = errorKind;
|
||||||
|
this.multiKind = multiKind;
|
||||||
|
this.multiPolicy = multiPolicy;
|
||||||
|
this.posKind = posKind;
|
||||||
|
this.xdiagsSource = xdiagsSource;
|
||||||
|
this.xdiagsCompact = xdiagsCompact;
|
||||||
|
this.caretKind = caretKind;
|
||||||
|
this.sourceLineKind = sourceLineKind;
|
||||||
|
this.summaryIndent = summaryIndent;
|
||||||
|
this.detailsIndent = detailsIndent;
|
||||||
|
this.sourceIndent = sourceIndent;
|
||||||
|
this.subdiagsIndent = subdiagsIndent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
Context ctx = new Context();
|
Context ctx = new Context();
|
||||||
Options options = Options.instance(ctx);
|
Options options = Options.instance(ctx);
|
||||||
outputKind.init(options);
|
outputKind.init(options);
|
||||||
@ -362,23 +396,10 @@ public class T6769027 {
|
|||||||
d = new JCDiagnostic.MultilineDiagnostic(d, subdiags);
|
d = new JCDiagnostic.MultilineDiagnostic(d, subdiags);
|
||||||
}
|
}
|
||||||
String diag = log.getDiagnosticFormatter().format(d, messages.getCurrentLocale());
|
String diag = log.getDiagnosticFormatter().format(d, messages.getCurrentLocale());
|
||||||
checkOutput(diag,
|
checkOutput(diag);
|
||||||
outputKind,
|
|
||||||
errorKind,
|
|
||||||
multiKind,
|
|
||||||
multiPolicy,
|
|
||||||
posKind,
|
|
||||||
xdiagsSource,
|
|
||||||
xdiagsCompact,
|
|
||||||
caretKind,
|
|
||||||
sourceLineKind,
|
|
||||||
summaryIndent,
|
|
||||||
detailsIndent,
|
|
||||||
sourceIndent,
|
|
||||||
subdiagsIndent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test() {
|
public static void main(String[] args) throws Exception {
|
||||||
for (OutputKind outputKind : OutputKind.values()) {
|
for (OutputKind outputKind : OutputKind.values()) {
|
||||||
for (ErrorKind errKind : ErrorKind.values()) {
|
for (ErrorKind errKind : ErrorKind.values()) {
|
||||||
for (MultilineKind multiKind : MultilineKind.values()) {
|
for (MultilineKind multiKind : MultilineKind.values()) {
|
||||||
@ -392,7 +413,7 @@ public class T6769027 {
|
|||||||
for (IndentKind detailsIndent : IndentKind.values()) {
|
for (IndentKind detailsIndent : IndentKind.values()) {
|
||||||
for (IndentKind sourceIndent : IndentKind.values()) {
|
for (IndentKind sourceIndent : IndentKind.values()) {
|
||||||
for (IndentKind subdiagsIndent : IndentKind.values()) {
|
for (IndentKind subdiagsIndent : IndentKind.values()) {
|
||||||
exec(outputKind,
|
pool.execute(new T6769027(outputKind,
|
||||||
errKind,
|
errKind,
|
||||||
multiKind,
|
multiKind,
|
||||||
multiPolicy,
|
multiPolicy,
|
||||||
@ -404,7 +425,7 @@ public class T6769027 {
|
|||||||
summaryIndent,
|
summaryIndent,
|
||||||
detailsIndent,
|
detailsIndent,
|
||||||
sourceIndent,
|
sourceIndent,
|
||||||
subdiagsIndent);
|
subdiagsIndent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -418,15 +439,11 @@ public class T6769027 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nerrors != 0)
|
|
||||||
throw new AssertionError(nerrors + " errors found");
|
checkAfterExec(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printInfo(String msg, OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
|
void printInfo(String msg, String errorLine) {
|
||||||
MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
|
|
||||||
XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
|
|
||||||
IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
|
|
||||||
IndentKind subdiagsIndent, String errorLine) {
|
|
||||||
String sep = "*********************************************************";
|
String sep = "*********************************************************";
|
||||||
String desc = "raw=" + outputKind + " pos=" + posKind + " key=" + errorKind.key() +
|
String desc = "raw=" + outputKind + " pos=" + posKind + " key=" + errorKind.key() +
|
||||||
" multiline=" + multiKind +" multiPolicy=" + multiPolicy.value +
|
" multiline=" + multiKind +" multiPolicy=" + multiPolicy.value +
|
||||||
@ -434,18 +451,14 @@ public class T6769027 {
|
|||||||
" caret=" + caretKind + " sourcePosition=" + sourceLineKind +
|
" caret=" + caretKind + " sourcePosition=" + sourceLineKind +
|
||||||
" summaryIndent=" + summaryIndent + " detailsIndent=" + detailsIndent +
|
" summaryIndent=" + summaryIndent + " detailsIndent=" + detailsIndent +
|
||||||
" sourceIndent=" + sourceIndent + " subdiagsIndent=" + subdiagsIndent;
|
" sourceIndent=" + sourceIndent + " subdiagsIndent=" + subdiagsIndent;
|
||||||
System.out.println(sep);
|
errWriter.println(sep);
|
||||||
System.out.println(desc);
|
errWriter.println(desc);
|
||||||
System.out.println(sep);
|
errWriter.println(sep);
|
||||||
System.out.println(msg);
|
errWriter.println(msg);
|
||||||
System.out.println("Diagnostic formatting problem - expected diagnostic...\n" + errorLine);
|
errWriter.println("Diagnostic formatting problem - expected diagnostic...\n" + errorLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkOutput(String msg, OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
|
void checkOutput(String msg) {
|
||||||
MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
|
|
||||||
XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
|
|
||||||
IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
|
|
||||||
IndentKind subdiagsIndent) {
|
|
||||||
boolean shouldPrintSource = posKind == PositionKind.POS &&
|
boolean shouldPrintSource = posKind == PositionKind.POS &&
|
||||||
xdiagsSource != XDiagsSource.NO_SOURCE &&
|
xdiagsSource != XDiagsSource.NO_SOURCE &&
|
||||||
(xdiagsSource == XDiagsSource.SOURCE ||
|
(xdiagsSource == XDiagsSource.SOURCE ||
|
||||||
@ -453,7 +466,8 @@ public class T6769027 {
|
|||||||
String errorLine = posKind.getOutput(outputKind) +
|
String errorLine = posKind.getOutput(outputKind) +
|
||||||
errorKind.getOutput(outputKind, summaryIndent, detailsIndent);
|
errorKind.getOutput(outputKind, summaryIndent, detailsIndent);
|
||||||
if (xdiagsCompact != XDiagsCompact.COMPACT)
|
if (xdiagsCompact != XDiagsCompact.COMPACT)
|
||||||
errorLine += multiKind.getOutput(outputKind, errorKind, multiPolicy, summaryIndent, detailsIndent, subdiagsIndent);
|
errorLine += multiKind.getOutput(outputKind, errorKind, multiPolicy,
|
||||||
|
summaryIndent, detailsIndent, subdiagsIndent);
|
||||||
String[] lines = errorLine.split("\n");
|
String[] lines = errorLine.split("\n");
|
||||||
if (xdiagsCompact == XDiagsCompact.COMPACT) {
|
if (xdiagsCompact == XDiagsCompact.COMPACT) {
|
||||||
errorLine = lines[0];
|
errorLine = lines[0];
|
||||||
@ -474,26 +488,9 @@ public class T6769027 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!msg.equals(errorLine)) {
|
if (!msg.equals(errorLine)) {
|
||||||
printInfo(msg,
|
printInfo(msg, errorLine);
|
||||||
outputKind,
|
errCount.incrementAndGet();
|
||||||
errorKind,
|
|
||||||
multiKind,
|
|
||||||
multiPolicy,
|
|
||||||
posKind,
|
|
||||||
xdiagsSource,
|
|
||||||
xdiagsCompact,
|
|
||||||
caretKind,
|
|
||||||
sourceLineKind,
|
|
||||||
summaryIndent,
|
|
||||||
detailsIndent,
|
|
||||||
sourceIndent,
|
|
||||||
subdiagsIndent,
|
|
||||||
errorLine);
|
|
||||||
nerrors++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
|
||||||
new T6769027().test();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,35 +25,29 @@
|
|||||||
* @test
|
* @test
|
||||||
* @bug 7093325
|
* @bug 7093325
|
||||||
* @summary Redundant entry in bytecode exception table
|
* @summary Redundant entry in bytecode exception table
|
||||||
|
* @library lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main T7093325
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import com.sun.tools.classfile.Attribute;
|
|
||||||
import com.sun.tools.classfile.ClassFile;
|
|
||||||
import com.sun.tools.classfile.Code_attribute;
|
|
||||||
import com.sun.tools.classfile.ConstantPool.*;
|
|
||||||
import com.sun.tools.classfile.Method;
|
|
||||||
import com.sun.tools.javac.api.JavacTool;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
import javax.tools.ToolProvider;
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
import com.sun.source.util.JavacTask;
|
||||||
|
import com.sun.tools.classfile.Attribute;
|
||||||
|
import com.sun.tools.classfile.ClassFile;
|
||||||
|
import com.sun.tools.classfile.Code_attribute;
|
||||||
|
import com.sun.tools.classfile.ConstantPool.*;
|
||||||
|
import com.sun.tools.classfile.Method;
|
||||||
|
|
||||||
public class T7093325 {
|
public class T7093325
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
/** global decls ***/
|
implements Runnable {
|
||||||
|
|
||||||
// Create a single file manager and reuse it for each compile to save time.
|
|
||||||
static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
//statistics
|
|
||||||
static int checkCount = 0;
|
|
||||||
|
|
||||||
enum StatementKind {
|
enum StatementKind {
|
||||||
THROW("throw new RuntimeException();", false, false),
|
THROW("throw new RuntimeException();", false, false),
|
||||||
@ -89,7 +83,8 @@ public class T7093325 {
|
|||||||
if (this.ordinal() == 0) {
|
if (this.ordinal() == 0) {
|
||||||
return catchStr;
|
return catchStr;
|
||||||
} else {
|
} else {
|
||||||
return CatchArity.values()[this.ordinal() - 1].catchers() + catchStr;
|
return CatchArity.values()[this.ordinal() - 1].catchers() +
|
||||||
|
catchStr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,31 +93,36 @@ public class T7093325 {
|
|||||||
for (CatchArity ca : CatchArity.values()) {
|
for (CatchArity ca : CatchArity.values()) {
|
||||||
for (StatementKind stmt0 : StatementKind.values()) {
|
for (StatementKind stmt0 : StatementKind.values()) {
|
||||||
if (ca.ordinal() == 0) {
|
if (ca.ordinal() == 0) {
|
||||||
new T7093325(ca, stmt0).compileAndCheck();
|
pool.execute(new T7093325(ca, stmt0));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (StatementKind stmt1 : StatementKind.values()) {
|
for (StatementKind stmt1 : StatementKind.values()) {
|
||||||
if (ca.ordinal() == 1) {
|
if (ca.ordinal() == 1) {
|
||||||
new T7093325(ca, stmt0, stmt1).compileAndCheck();
|
pool.execute(new T7093325(ca, stmt0, stmt1));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (StatementKind stmt2 : StatementKind.values()) {
|
for (StatementKind stmt2 : StatementKind.values()) {
|
||||||
if (ca.ordinal() == 2) {
|
if (ca.ordinal() == 2) {
|
||||||
new T7093325(ca, stmt0, stmt1, stmt2).compileAndCheck();
|
pool.execute(new T7093325(ca, stmt0, stmt1, stmt2));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (StatementKind stmt3 : StatementKind.values()) {
|
for (StatementKind stmt3 : StatementKind.values()) {
|
||||||
if (ca.ordinal() == 3) {
|
if (ca.ordinal() == 3) {
|
||||||
new T7093325(ca, stmt0, stmt1, stmt2, stmt3).compileAndCheck();
|
pool.execute(
|
||||||
|
new T7093325(ca, stmt0, stmt1, stmt2, stmt3));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (StatementKind stmt4 : StatementKind.values()) {
|
for (StatementKind stmt4 : StatementKind.values()) {
|
||||||
if (ca.ordinal() == 4) {
|
if (ca.ordinal() == 4) {
|
||||||
new T7093325(ca, stmt0, stmt1, stmt2, stmt3, stmt4).compileAndCheck();
|
pool.execute(
|
||||||
|
new T7093325(ca, stmt0, stmt1,
|
||||||
|
stmt2, stmt3, stmt4));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (StatementKind stmt5 : StatementKind.values()) {
|
for (StatementKind stmt5 : StatementKind.values()) {
|
||||||
new T7093325(ca, stmt0, stmt1, stmt2, stmt3, stmt4, stmt5).compileAndCheck();
|
pool.execute(
|
||||||
|
new T7093325(ca, stmt0, stmt1, stmt2,
|
||||||
|
stmt3, stmt4, stmt5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,7 +131,7 @@ public class T7093325 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Total checks made: " + checkCount);
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** instance decls **/
|
/** instance decls **/
|
||||||
@ -144,17 +144,18 @@ public class T7093325 {
|
|||||||
this.stmts = stmts;
|
this.stmts = stmts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compileAndCheck() throws Exception {
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int id = checkCount.incrementAndGet();
|
||||||
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
||||||
JavaSource source = new JavaSource();
|
JavaSource source = new JavaSource(id);
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, null,
|
JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), null,
|
||||||
null, null, Arrays.asList(source));
|
null, null, Arrays.asList(source));
|
||||||
ct.call();
|
ct.call();
|
||||||
verifyBytecode(source);
|
verifyBytecode(source, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void verifyBytecode(JavaSource source) {
|
void verifyBytecode(JavaSource source, int id) {
|
||||||
checkCount++;
|
|
||||||
boolean lastInlined = false;
|
boolean lastInlined = false;
|
||||||
boolean hasCode = false;
|
boolean hasCode = false;
|
||||||
int gapsCount = 0;
|
int gapsCount = 0;
|
||||||
@ -172,11 +173,12 @@ public class T7093325 {
|
|||||||
|
|
||||||
//System.out.printf("gaps %d \n %s \n", gapsCount, source.toString());
|
//System.out.printf("gaps %d \n %s \n", gapsCount, source.toString());
|
||||||
|
|
||||||
File compiledTest = new File("Test.class");
|
File compiledTest = new File(String.format("Test%s.class", id));
|
||||||
try {
|
try {
|
||||||
ClassFile cf = ClassFile.read(compiledTest);
|
ClassFile cf = ClassFile.read(compiledTest);
|
||||||
if (cf == null) {
|
if (cf == null) {
|
||||||
throw new Error("Classfile not found: " + compiledTest.getName());
|
throw new Error("Classfile not found: " +
|
||||||
|
compiledTest.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
Method test_method = null;
|
Method test_method = null;
|
||||||
@ -232,7 +234,7 @@ public class T7093325 {
|
|||||||
"class C extends RuntimeException {} \n" +
|
"class C extends RuntimeException {} \n" +
|
||||||
"class D extends RuntimeException {} \n" +
|
"class D extends RuntimeException {} \n" +
|
||||||
"class E extends RuntimeException {} \n" +
|
"class E extends RuntimeException {} \n" +
|
||||||
"class Test {\n" +
|
"class Test#ID {\n" +
|
||||||
" void test() {\n" +
|
" void test() {\n" +
|
||||||
" try { #S0 } #C finally { System.out.println(); }\n" +
|
" try { #S0 } #C finally { System.out.println(); }\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
@ -240,10 +242,12 @@ public class T7093325 {
|
|||||||
|
|
||||||
String source;
|
String source;
|
||||||
|
|
||||||
public JavaSource() {
|
public JavaSource(int id) {
|
||||||
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
super(URI.create(String.format("myfo:/Test%s.java", id)),
|
||||||
|
JavaFileObject.Kind.SOURCE);
|
||||||
source = source_template.replace("#C", ca.catchers());
|
source = source_template.replace("#C", ca.catchers());
|
||||||
source = source.replace("#S0", stmts[0].stmt);
|
source = source.replace("#S0", stmts[0].stmt);
|
||||||
|
source = source.replace("#ID", String.valueOf(id));
|
||||||
for (int i = 1; i < ca.ordinal() + 1; i++) {
|
for (int i = 1; i < ca.ordinal() + 1; i++) {
|
||||||
source = source.replace("#S" + i, stmts[i].stmt);
|
source = source.replace("#S" + i, stmts[i].stmt);
|
||||||
}
|
}
|
||||||
@ -259,4 +263,5 @@ public class T7093325 {
|
|||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,23 +25,26 @@
|
|||||||
* @test
|
* @test
|
||||||
* @bug 8002099
|
* @bug 8002099
|
||||||
* @summary Add support for intersection types in cast expression
|
* @summary Add support for intersection types in cast expression
|
||||||
|
* @library ../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main/timeout=360 IntersectionTypeCastTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import com.sun.tools.javac.util.List;
|
|
||||||
import com.sun.tools.javac.util.ListBuffer;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
import javax.tools.ToolProvider;
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
public class IntersectionTypeCastTest {
|
import com.sun.source.util.JavacTask;
|
||||||
|
import com.sun.tools.javac.util.List;
|
||||||
|
import com.sun.tools.javac.util.ListBuffer;
|
||||||
|
|
||||||
static int checkCount = 0;
|
public class IntersectionTypeCastTest
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
|
implements Runnable {
|
||||||
|
|
||||||
interface Type {
|
interface Type {
|
||||||
boolean subtypeOf(Type that);
|
boolean subtypeOf(Type that);
|
||||||
@ -59,7 +62,8 @@ public class IntersectionTypeCastTest {
|
|||||||
String typeStr;
|
String typeStr;
|
||||||
InterfaceKind superInterface;
|
InterfaceKind superInterface;
|
||||||
|
|
||||||
InterfaceKind(String declStr, String typeStr, InterfaceKind superInterface) {
|
InterfaceKind(String declStr, String typeStr,
|
||||||
|
InterfaceKind superInterface) {
|
||||||
this.declStr = declStr;
|
this.declStr = declStr;
|
||||||
this.typeStr = typeStr;
|
this.typeStr = typeStr;
|
||||||
this.superInterface = superInterface;
|
this.superInterface = superInterface;
|
||||||
@ -67,7 +71,8 @@ public class IntersectionTypeCastTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean subtypeOf(Type that) {
|
public boolean subtypeOf(Type that) {
|
||||||
return this == that || superInterface == that || that == ClassKind.OBJECT;
|
return this == that || superInterface == that ||
|
||||||
|
that == ClassKind.OBJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -88,19 +93,27 @@ public class IntersectionTypeCastTest {
|
|||||||
|
|
||||||
enum ClassKind implements Type {
|
enum ClassKind implements Type {
|
||||||
OBJECT(null, "Object"),
|
OBJECT(null, "Object"),
|
||||||
CA("#M class CA implements A { }\n", "CA", InterfaceKind.A),
|
CA("#M class CA implements A { }\n", "CA",
|
||||||
CB("#M class CB implements B { }\n", "CB", InterfaceKind.B),
|
InterfaceKind.A),
|
||||||
CAB("#M class CAB implements A, B { }\n", "CAB", InterfaceKind.A, InterfaceKind.B),
|
CB("#M class CB implements B { }\n", "CB",
|
||||||
CC("#M class CC implements C { }\n", "CC", InterfaceKind.C, InterfaceKind.A),
|
InterfaceKind.B),
|
||||||
CCA("#M class CCA implements C, A { }\n", "CCA", InterfaceKind.C, InterfaceKind.A),
|
CAB("#M class CAB implements A, B { }\n", "CAB",
|
||||||
CCB("#M class CCB implements C, B { }\n", "CCB", InterfaceKind.C, InterfaceKind.A, InterfaceKind.B),
|
InterfaceKind.A, InterfaceKind.B),
|
||||||
CCAB("#M class CCAB implements C, A, B { }\n", "CCAB", InterfaceKind.C, InterfaceKind.A, InterfaceKind.B);
|
CC("#M class CC implements C { }\n", "CC",
|
||||||
|
InterfaceKind.C, InterfaceKind.A),
|
||||||
|
CCA("#M class CCA implements C, A { }\n", "CCA",
|
||||||
|
InterfaceKind.C, InterfaceKind.A),
|
||||||
|
CCB("#M class CCB implements C, B { }\n", "CCB",
|
||||||
|
InterfaceKind.C, InterfaceKind.A, InterfaceKind.B),
|
||||||
|
CCAB("#M class CCAB implements C, A, B { }\n", "CCAB",
|
||||||
|
InterfaceKind.C, InterfaceKind.A, InterfaceKind.B);
|
||||||
|
|
||||||
String declTemplate;
|
String declTemplate;
|
||||||
String typeStr;
|
String typeStr;
|
||||||
List<InterfaceKind> superInterfaces;
|
List<InterfaceKind> superInterfaces;
|
||||||
|
|
||||||
ClassKind(String declTemplate, String typeStr, InterfaceKind... superInterfaces) {
|
ClassKind(String declTemplate, String typeStr,
|
||||||
|
InterfaceKind... superInterfaces) {
|
||||||
this.declTemplate = declTemplate;
|
this.declTemplate = declTemplate;
|
||||||
this.typeStr = typeStr;
|
this.typeStr = typeStr;
|
||||||
this.superInterfaces = List.from(superInterfaces);
|
this.superInterfaces = List.from(superInterfaces);
|
||||||
@ -114,7 +127,8 @@ public class IntersectionTypeCastTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean subtypeOf(Type that) {
|
public boolean subtypeOf(Type that) {
|
||||||
return this == that || superInterfaces.contains(that) || that == OBJECT;
|
return this == that || superInterfaces.contains(that) ||
|
||||||
|
that == OBJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -170,9 +184,11 @@ public class IntersectionTypeCastTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String getCast() {
|
String getCast() {
|
||||||
String temp = kind.castTemplate.replaceAll("#C", types[0].asString());
|
String temp = kind.castTemplate.replaceAll("#C",
|
||||||
|
types[0].asString());
|
||||||
for (int i = 0; i < kind.interfaceBounds ; i++) {
|
for (int i = 0; i < kind.interfaceBounds ; i++) {
|
||||||
temp = temp.replace(String.format("#I%d", i), types[i + 1].asString());
|
temp = temp.replace(String.format("#I%d", i),
|
||||||
|
types[i + 1].asString());
|
||||||
}
|
}
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
@ -195,7 +211,8 @@ public class IntersectionTypeCastTest {
|
|||||||
t1.subtypeOf(t2) ||
|
t1.subtypeOf(t2) ||
|
||||||
t2.subtypeOf(t1) ||
|
t2.subtypeOf(t1) ||
|
||||||
(t1.isInterface() && t2.isInterface()) || //side-cast (1)
|
(t1.isInterface() && t2.isInterface()) || //side-cast (1)
|
||||||
(mod == ModifierKind.NONE && (t1.isInterface() != t2.isInterface())); //side-cast (2)
|
(mod == ModifierKind.NONE &&
|
||||||
|
(t1.isInterface() != t2.isInterface())); //side-cast (2)
|
||||||
if (!compat) return false;
|
if (!compat) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,18 +221,15 @@ public class IntersectionTypeCastTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
//create default shared JavaCompiler - reused across multiple compilations
|
|
||||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
|
||||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
for (ModifierKind mod : ModifierKind.values()) {
|
for (ModifierKind mod : ModifierKind.values()) {
|
||||||
for (CastInfo cast1 : allCastInfo()) {
|
for (CastInfo cast1 : allCastInfo()) {
|
||||||
for (CastInfo cast2 : allCastInfo()) {
|
for (CastInfo cast2 : allCastInfo()) {
|
||||||
new IntersectionTypeCastTest(mod, cast1, cast2).run(comp, fm);
|
pool.execute(
|
||||||
|
new IntersectionTypeCastTest(mod, cast1, cast2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Total check executed: " + checkCount);
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<CastInfo> allCastInfo() {
|
static List<CastInfo> allCastInfo() {
|
||||||
@ -235,11 +249,14 @@ public class IntersectionTypeCastTest {
|
|||||||
} else {
|
} else {
|
||||||
for (InterfaceKind intf2 : InterfaceKind.values()) {
|
for (InterfaceKind intf2 : InterfaceKind.values()) {
|
||||||
if (kind.interfaceBounds == 2) {
|
if (kind.interfaceBounds == 2) {
|
||||||
buf.append(new CastInfo(kind, clazz, intf1, intf2));
|
buf.append(
|
||||||
|
new CastInfo(kind, clazz, intf1, intf2));
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
for (InterfaceKind intf3 : InterfaceKind.values()) {
|
for (InterfaceKind intf3 : InterfaceKind.values()) {
|
||||||
buf.append(new CastInfo(kind, clazz, intf1, intf2, intf3));
|
buf.append(
|
||||||
|
new CastInfo(kind, clazz, intf1,
|
||||||
|
intf2, intf3));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,6 +282,22 @@ public class IntersectionTypeCastTest {
|
|||||||
this.diagChecker = new DiagnosticChecker();
|
this.diagChecker = new DiagnosticChecker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
||||||
|
|
||||||
|
JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), diagChecker,
|
||||||
|
Arrays.asList("-XDallowIntersectionTypes"),
|
||||||
|
null, Arrays.asList(source));
|
||||||
|
try {
|
||||||
|
ct.analyze();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
throw new AssertionError("Error thrown when compiling the following code:\n" +
|
||||||
|
source.getCharContent(true));
|
||||||
|
}
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
class JavaSource extends SimpleJavaFileObject {
|
class JavaSource extends SimpleJavaFileObject {
|
||||||
|
|
||||||
String bodyTemplate = "class Test {\n" +
|
String bodyTemplate = "class Test {\n" +
|
||||||
@ -282,7 +315,8 @@ public class IntersectionTypeCastTest {
|
|||||||
for (InterfaceKind ik : InterfaceKind.values()) {
|
for (InterfaceKind ik : InterfaceKind.values()) {
|
||||||
source += ik.declStr;
|
source += ik.declStr;
|
||||||
}
|
}
|
||||||
source += bodyTemplate.replaceAll("#C1", cast1.getCast()).replaceAll("#C2", cast2.getCast());
|
source += bodyTemplate.replaceAll("#C1", cast1.getCast()).
|
||||||
|
replaceAll("#C2", cast2.getCast());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -291,21 +325,11 @@ public class IntersectionTypeCastTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
|
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
|
|
||||||
Arrays.asList("-XDallowIntersectionTypes"), null, Arrays.asList(source));
|
|
||||||
try {
|
|
||||||
ct.analyze();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
|
|
||||||
}
|
|
||||||
check();
|
|
||||||
}
|
|
||||||
|
|
||||||
void check() {
|
void check() {
|
||||||
checkCount++;
|
checkCount.incrementAndGet();
|
||||||
|
|
||||||
boolean errorExpected = cast1.hasDuplicateTypes() || cast2.hasDuplicateTypes();
|
boolean errorExpected = cast1.hasDuplicateTypes() ||
|
||||||
|
cast2.hasDuplicateTypes();
|
||||||
|
|
||||||
errorExpected |= !cast2.compatibleWith(mod, cast1);
|
errorExpected |= !cast2.compatibleWith(mod, cast1);
|
||||||
|
|
||||||
@ -317,7 +341,8 @@ public class IntersectionTypeCastTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class DiagnosticChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
boolean errorFound;
|
boolean errorFound;
|
||||||
|
|
||||||
@ -327,4 +352,5 @@ public class IntersectionTypeCastTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,25 +24,25 @@
|
|||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @summary Automatic test for checking correctness of default super/this resolution
|
* @summary Automatic test for checking correctness of default super/this resolution
|
||||||
|
* @library ../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main TestDefaultSuperCall
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
import javax.tools.ToolProvider;
|
|
||||||
|
|
||||||
public class TestDefaultSuperCall {
|
import com.sun.source.util.JavacTask;
|
||||||
|
|
||||||
static int checkCount = 0;
|
public class TestDefaultSuperCall
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
|
implements Runnable {
|
||||||
|
|
||||||
enum InterfaceKind {
|
enum InterfaceKind {
|
||||||
DEFAULT("interface A extends B { default void m() { } }"),
|
DEFAULT("interface A extends B { default void m() { } }"),
|
||||||
@ -212,7 +212,7 @@ public class TestDefaultSuperCall {
|
|||||||
List<String> elementsWithMethod;
|
List<String> elementsWithMethod;
|
||||||
|
|
||||||
Shape(ElementKind... elements) {
|
Shape(ElementKind... elements) {
|
||||||
System.err.println("elements = " + Arrays.toString(elements));
|
errWriter.println("elements = " + Arrays.toString(elements));
|
||||||
enclosingElements = new ArrayList<>();
|
enclosingElements = new ArrayList<>();
|
||||||
enclosingNames = new ArrayList<>();
|
enclosingNames = new ArrayList<>();
|
||||||
elementsWithMethod = new ArrayList<>();
|
elementsWithMethod = new ArrayList<>();
|
||||||
@ -231,28 +231,26 @@ public class TestDefaultSuperCall {
|
|||||||
elementsWithMethod.add(prevName);
|
elementsWithMethod.add(prevName);
|
||||||
}
|
}
|
||||||
String element = ek.templateDecl.replaceAll("#N", name);
|
String element = ek.templateDecl.replaceAll("#N", name);
|
||||||
shapeStr = shapeStr == null ? element : shapeStr.replaceAll("#B", element);
|
shapeStr = shapeStr ==
|
||||||
|
null ? element : shapeStr.replaceAll("#B", element);
|
||||||
prevName = name;
|
prevName = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getShape(QualifierKind qk, ExprKind ek) {
|
String getShape(QualifierKind qk, ExprKind ek) {
|
||||||
String methName = ek == ExprKind.THIS ? "test" : "m";
|
String methName = ek == ExprKind.THIS ? "test" : "m";
|
||||||
String call = qk.getQualifier(this) + "." + ek.exprStr + "." + methName + "();";
|
String call = qk.getQualifier(this) + "." +
|
||||||
|
ek.exprStr + "." + methName + "();";
|
||||||
return shapeStr.replaceAll("#B", call);
|
return shapeStr.replaceAll("#B", call);
|
||||||
}
|
}
|
||||||
|
|
||||||
String enclosingAt(int index) {
|
String enclosingAt(int index) {
|
||||||
return index < enclosingNames.size() ? enclosingNames.get(index) : "BAD";
|
return index < enclosingNames.size() ?
|
||||||
|
enclosingNames.get(index) : "BAD";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
|
|
||||||
//create default shared JavaCompiler - reused across multiple compilations
|
|
||||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
|
||||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
for (InterfaceKind ik : InterfaceKind.values()) {
|
for (InterfaceKind ik : InterfaceKind.values()) {
|
||||||
for (PruneKind pk : PruneKind.values()) {
|
for (PruneKind pk : PruneKind.values()) {
|
||||||
for (ElementKind ek1 : ElementKind.values()) {
|
for (ElementKind ek1 : ElementKind.values()) {
|
||||||
@ -264,10 +262,14 @@ public class TestDefaultSuperCall {
|
|||||||
for (ElementKind ek4 : ElementKind.values()) {
|
for (ElementKind ek4 : ElementKind.values()) {
|
||||||
if (!ek4.isAllowedEnclosing(ek3, false)) continue;
|
if (!ek4.isAllowedEnclosing(ek3, false)) continue;
|
||||||
for (ElementKind ek5 : ElementKind.values()) {
|
for (ElementKind ek5 : ElementKind.values()) {
|
||||||
if (!ek5.isAllowedEnclosing(ek4, false) || ek5.isClassDecl()) continue;
|
if (!ek5.isAllowedEnclosing(ek4, false) ||
|
||||||
|
ek5.isClassDecl()) continue;
|
||||||
for (QualifierKind qk : QualifierKind.values()) {
|
for (QualifierKind qk : QualifierKind.values()) {
|
||||||
for (ExprKind ek : ExprKind.values()) {
|
for (ExprKind ek : ExprKind.values()) {
|
||||||
new TestDefaultSuperCall(ik, pk, new Shape(ek1, ek2, ek3, ek4, ek5), qk, ek).run(comp, fm);
|
pool.execute(
|
||||||
|
new TestDefaultSuperCall(ik, pk,
|
||||||
|
new Shape(ek1, ek2, ek3,
|
||||||
|
ek4, ek5), qk, ek));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,7 +279,8 @@ public class TestDefaultSuperCall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Total check executed: " + checkCount);
|
|
||||||
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
InterfaceKind ik;
|
InterfaceKind ik;
|
||||||
@ -288,7 +291,8 @@ public class TestDefaultSuperCall {
|
|||||||
JavaSource source;
|
JavaSource source;
|
||||||
DiagnosticChecker diagChecker;
|
DiagnosticChecker diagChecker;
|
||||||
|
|
||||||
TestDefaultSuperCall(InterfaceKind ik, PruneKind pk, Shape sh, QualifierKind qk, ExprKind ek) {
|
TestDefaultSuperCall(InterfaceKind ik, PruneKind pk, Shape sh,
|
||||||
|
QualifierKind qk, ExprKind ek) {
|
||||||
this.ik = ik;
|
this.ik = ik;
|
||||||
this.pk = pk;
|
this.pk = pk;
|
||||||
this.sh = sh;
|
this.sh = sh;
|
||||||
@ -321,13 +325,14 @@ public class TestDefaultSuperCall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
|
public void run() {
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
|
JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
|
||||||
null, null, Arrays.asList(source));
|
null, null, Arrays.asList(source));
|
||||||
try {
|
try {
|
||||||
ct.analyze();
|
ct.analyze();
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
|
processException(ex);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
@ -370,7 +375,8 @@ public class TestDefaultSuperCall {
|
|||||||
|
|
||||||
int lastIdx = sh.enclosingElements.size() - 1;
|
int lastIdx = sh.enclosingElements.size() - 1;
|
||||||
boolean found = lastIdx == -1 ? false :
|
boolean found = lastIdx == -1 ? false :
|
||||||
sh.enclosingElements.get(lastIdx).hasSuper() && qk.allowSuperCall(ik, pk);
|
sh.enclosingElements.get(lastIdx).hasSuper() &&
|
||||||
|
qk.allowSuperCall(ik, pk);
|
||||||
|
|
||||||
errorExpected |= !found;
|
errorExpected |= !found;
|
||||||
if (!found) {
|
if (!found) {
|
||||||
@ -378,9 +384,10 @@ public class TestDefaultSuperCall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkCount++;
|
checkCount.incrementAndGet();
|
||||||
if (diagChecker.errorFound != errorExpected) {
|
if (diagChecker.errorFound != errorExpected) {
|
||||||
throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) +
|
throw new AssertionError("Problem when compiling source:\n" +
|
||||||
|
source.getCharContent(true) +
|
||||||
"\nenclosingElems: " + sh.enclosingElements +
|
"\nenclosingElems: " + sh.enclosingElements +
|
||||||
"\nenclosingNames: " + sh.enclosingNames +
|
"\nenclosingNames: " + sh.enclosingNames +
|
||||||
"\nelementsWithMethod: " + sh.elementsWithMethod +
|
"\nelementsWithMethod: " + sh.elementsWithMethod +
|
||||||
@ -392,15 +399,17 @@ public class TestDefaultSuperCall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class DiagnosticChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
boolean errorFound;
|
boolean errorFound;
|
||||||
|
|
||||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
||||||
System.err.println(diagnostic.getMessage(Locale.getDefault()));
|
errWriter.println(diagnostic.getMessage(Locale.getDefault()));
|
||||||
errorFound = true;
|
errorFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -21,7 +21,15 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.TaskEvent;
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6970584
|
||||||
|
* @summary assorted position errors in compiler syntax trees
|
||||||
|
* @library ../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main CheckAttributedTree -q -r -et ERRONEOUS .
|
||||||
|
*/
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
@ -34,6 +42,20 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Element;
|
||||||
import javax.swing.DefaultComboBoxModel;
|
import javax.swing.DefaultComboBoxModel;
|
||||||
import javax.swing.JComboBox;
|
import javax.swing.JComboBox;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
@ -49,23 +71,14 @@ import javax.swing.event.CaretListener;
|
|||||||
import javax.swing.text.BadLocationException;
|
import javax.swing.text.BadLocationException;
|
||||||
import javax.swing.text.DefaultHighlighter;
|
import javax.swing.text.DefaultHighlighter;
|
||||||
import javax.swing.text.Highlighter;
|
import javax.swing.text.Highlighter;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.DiagnosticListener;
|
import javax.tools.DiagnosticListener;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
|
|
||||||
import com.sun.source.tree.CompilationUnitTree;
|
import com.sun.source.tree.CompilationUnitTree;
|
||||||
|
import com.sun.source.util.TaskEvent;
|
||||||
import com.sun.source.util.JavacTask;
|
import com.sun.source.util.JavacTask;
|
||||||
import com.sun.source.util.TaskListener;
|
import com.sun.source.util.TaskListener;
|
||||||
import com.sun.tools.javac.api.JavacTool;
|
|
||||||
import com.sun.tools.javac.code.Symbol;
|
import com.sun.tools.javac.code.Symbol;
|
||||||
import com.sun.tools.javac.code.Type;
|
import com.sun.tools.javac.code.Type;
|
||||||
import com.sun.tools.javac.tree.EndPosTable;
|
import com.sun.tools.javac.tree.EndPosTable;
|
||||||
@ -76,11 +89,6 @@ import com.sun.tools.javac.tree.TreeInfo;
|
|||||||
import com.sun.tools.javac.tree.TreeScanner;
|
import com.sun.tools.javac.tree.TreeScanner;
|
||||||
import com.sun.tools.javac.util.Pair;
|
import com.sun.tools.javac.util.Pair;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.lang.model.element.Element;
|
|
||||||
|
|
||||||
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,13 +103,7 @@ import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
|||||||
* covering any new language features that may be tested in this test suite.
|
* covering any new language features that may be tested in this test suite.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
public class CheckAttributedTree extends JavacTestingAbstractThreadedTest {
|
||||||
* @test
|
|
||||||
* @bug 6970584
|
|
||||||
* @summary assorted position errors in compiler syntax trees
|
|
||||||
* @run main CheckAttributedTree -q -r -et ERRONEOUS .
|
|
||||||
*/
|
|
||||||
public class CheckAttributedTree {
|
|
||||||
/**
|
/**
|
||||||
* Main entry point.
|
* Main entry point.
|
||||||
* If test.src is set, program runs in jtreg mode, and will throw an Error
|
* If test.src is set, program runs in jtreg mode, and will throw an Error
|
||||||
@ -110,9 +112,10 @@ public class CheckAttributedTree {
|
|||||||
* args is the value of ${test.src}. In jtreg mode, the -r option can be
|
* args is the value of ${test.src}. In jtreg mode, the -r option can be
|
||||||
* given to change the default base directory to the root test directory.
|
* given to change the default base directory to the root test directory.
|
||||||
*/
|
*/
|
||||||
public static void main(String... args) {
|
public static void main(String... args) throws Exception {
|
||||||
String testSrc = System.getProperty("test.src");
|
String testSrc = System.getProperty("test.src");
|
||||||
File baseDir = (testSrc == null) ? null : new File(testSrc);
|
File baseDir = (testSrc == null) ? null : new File(testSrc);
|
||||||
|
throwAssertionOnError = false;
|
||||||
boolean ok = new CheckAttributedTree().run(baseDir, args);
|
boolean ok = new CheckAttributedTree().run(baseDir, args);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
if (testSrc != null) // jtreg mode
|
if (testSrc != null) // jtreg mode
|
||||||
@ -130,7 +133,7 @@ public class CheckAttributedTree {
|
|||||||
* @param args command line args
|
* @param args command line args
|
||||||
* @return true if successful or in gui mode
|
* @return true if successful or in gui mode
|
||||||
*/
|
*/
|
||||||
boolean run(File baseDir, String... args) {
|
boolean run(File baseDir, String... args) throws Exception {
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
usage(System.out);
|
usage(System.out);
|
||||||
return true;
|
return true;
|
||||||
@ -145,8 +148,10 @@ public class CheckAttributedTree {
|
|||||||
gui = true;
|
gui = true;
|
||||||
else if (arg.equals("-q"))
|
else if (arg.equals("-q"))
|
||||||
quiet = true;
|
quiet = true;
|
||||||
else if (arg.equals("-v"))
|
else if (arg.equals("-v")) {
|
||||||
verbose = true;
|
verbose = true;
|
||||||
|
printAll = true;
|
||||||
|
}
|
||||||
else if (arg.equals("-t") && i + 1 < args.length)
|
else if (arg.equals("-t") && i + 1 < args.length)
|
||||||
tags.add(args[++i]);
|
tags.add(args[++i]);
|
||||||
else if (arg.equals("-ef") && i + 1 < args.length)
|
else if (arg.equals("-ef") && i + 1 < args.length)
|
||||||
@ -179,12 +184,11 @@ public class CheckAttributedTree {
|
|||||||
error("File not found: " + file);
|
error("File not found: " + file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileCount != 1)
|
if (fileCount.get() != 1)
|
||||||
System.err.println(fileCount + " files read");
|
errWriter.println(fileCount + " files read");
|
||||||
if (errors > 0)
|
checkAfterExec(false);
|
||||||
System.err.println(errors + " errors");
|
|
||||||
|
|
||||||
return (gui || errors == 0);
|
return (gui || errCount.get() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,7 +219,7 @@ public class CheckAttributedTree {
|
|||||||
* for java files.
|
* for java files.
|
||||||
* @param file the file or directory to test
|
* @param file the file or directory to test
|
||||||
*/
|
*/
|
||||||
void test(File file) {
|
void test(final File file) {
|
||||||
if (excludeFiles.contains(file)) {
|
if (excludeFiles.contains(file)) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
error("File " + file + " excluded");
|
error("File " + file + " excluded");
|
||||||
@ -230,20 +234,24 @@ public class CheckAttributedTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (file.isFile() && file.getName().endsWith(".java")) {
|
if (file.isFile() && file.getName().endsWith(".java")) {
|
||||||
try {
|
pool.execute(new Runnable() {
|
||||||
if (verbose)
|
@Override
|
||||||
System.err.println(file);
|
public void run() {
|
||||||
fileCount++;
|
try {
|
||||||
NPETester p = new NPETester();
|
if (verbose)
|
||||||
p.test(read(file));
|
errWriter.println(file);
|
||||||
} catch (AttributionException e) {
|
fileCount.incrementAndGet();
|
||||||
if (!quiet) {
|
NPETester p = new NPETester();
|
||||||
error("Error attributing " + file + "\n" + e.getMessage());
|
p.test(read(file));
|
||||||
|
} catch (AttributionException e) {
|
||||||
|
if (!quiet) {
|
||||||
|
error("Error attributing " + file + "\n" + e.getMessage());
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
error("Error reading " + file + ": " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
});
|
||||||
error("Error reading " + file + ": " + e);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
@ -254,8 +262,6 @@ public class CheckAttributedTree {
|
|||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
Reporter r = new Reporter(pw);
|
Reporter r = new Reporter(pw);
|
||||||
JavacTool tool = JavacTool.create();
|
|
||||||
StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a file.
|
* Read a file.
|
||||||
@ -265,11 +271,10 @@ public class CheckAttributedTree {
|
|||||||
* @throws TreePosTest.ParseException if any errors occur while parsing the file
|
* @throws TreePosTest.ParseException if any errors occur while parsing the file
|
||||||
*/
|
*/
|
||||||
List<Pair<JCCompilationUnit, JCTree>> read(File file) throws IOException, AttributionException {
|
List<Pair<JCCompilationUnit, JCTree>> read(File file) throws IOException, AttributionException {
|
||||||
JavacTool tool = JavacTool.create();
|
|
||||||
r.errors = 0;
|
r.errors = 0;
|
||||||
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(file);
|
Iterable<? extends JavaFileObject> files = fm.get().getJavaFileObjects(file);
|
||||||
String[] opts = { "-XDshouldStopPolicy=ATTR", "-XDverboseCompilePolicy" };
|
String[] opts = { "-XDshouldStopPolicy=ATTR", "-XDverboseCompilePolicy" };
|
||||||
JavacTask task = tool.getTask(pw, fm, r, Arrays.asList(opts), null, files);
|
JavacTask task = (JavacTask)comp.getTask(pw, fm.get(), r, Arrays.asList(opts), null, files);
|
||||||
final List<Element> analyzedElems = new ArrayList<>();
|
final List<Element> analyzedElems = new ArrayList<>();
|
||||||
task.setTaskListener(new TaskListener() {
|
task.setTaskListener(new TaskListener() {
|
||||||
public void started(TaskEvent e) {
|
public void started(TaskEvent e) {
|
||||||
@ -308,13 +313,9 @@ public class CheckAttributedTree {
|
|||||||
*/
|
*/
|
||||||
void error(String msg) {
|
void error(String msg) {
|
||||||
System.err.println(msg);
|
System.err.println(msg);
|
||||||
errors++;
|
errCount.incrementAndGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Number of files that have been analyzed. */
|
|
||||||
int fileCount;
|
|
||||||
/** Number of errors reported. */
|
|
||||||
int errors;
|
|
||||||
/** Flag: don't report irrelevant files. */
|
/** Flag: don't report irrelevant files. */
|
||||||
boolean quiet;
|
boolean quiet;
|
||||||
/** Flag: show errors in GUI viewer. */
|
/** Flag: show errors in GUI viewer. */
|
||||||
@ -385,7 +386,8 @@ public class CheckAttributedTree {
|
|||||||
viewer = new Viewer();
|
viewer = new Viewer();
|
||||||
viewer.addEntry(sourcefile, label, encl, self);
|
viewer.addEntry(sourcefile, label, encl, self);
|
||||||
}
|
}
|
||||||
error(label + self.toString() + " encl: " + encl.toString() + " in file: " + sourcefile + " " + self.tree);
|
error(label + self.toString() + " encl: " + encl.toString() +
|
||||||
|
" in file: " + sourcefile + " " + self.tree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,4 +756,8 @@ public class CheckAttributedTree {
|
|||||||
final Info self;
|
final Info self;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Number of files that have been analyzed. */
|
||||||
|
static AtomicInteger fileCount = new AtomicInteger();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,21 +25,21 @@
|
|||||||
* @test
|
* @test
|
||||||
* @bug 7046778
|
* @bug 7046778
|
||||||
* @summary Project Coin: problem with diamond and member inner classes
|
* @summary Project Coin: problem with diamond and member inner classes
|
||||||
|
* @library ../../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main DiamondAndInnerClassTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
import com.sun.source.util.JavacTask;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
import javax.tools.ToolProvider;
|
|
||||||
|
|
||||||
public class DiamondAndInnerClassTest {
|
public class DiamondAndInnerClassTest
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
static int checkCount = 0;
|
implements Runnable {
|
||||||
|
|
||||||
enum TypeArgumentKind {
|
enum TypeArgumentKind {
|
||||||
NONE(""),
|
NONE(""),
|
||||||
@ -151,11 +151,6 @@ public class DiamondAndInnerClassTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
|
|
||||||
//create default shared JavaCompiler - reused across multiple compilations
|
|
||||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
|
||||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
for (InnerClassDeclArity innerClassDeclArity : InnerClassDeclArity.values()) {
|
for (InnerClassDeclArity innerClassDeclArity : InnerClassDeclArity.values()) {
|
||||||
for (TypeQualifierArity declType : TypeQualifierArity.values()) {
|
for (TypeQualifierArity declType : TypeQualifierArity.values()) {
|
||||||
if (!declType.matches(innerClassDeclArity)) continue;
|
if (!declType.matches(innerClassDeclArity)) continue;
|
||||||
@ -168,53 +163,79 @@ public class DiamondAndInnerClassTest {
|
|||||||
//no diamond on decl site
|
//no diamond on decl site
|
||||||
if (taDecl1 == TypeArgumentKind.DIAMOND) continue;
|
if (taDecl1 == TypeArgumentKind.DIAMOND) continue;
|
||||||
for (TypeArgumentKind taSite1 : TypeArgumentKind.values()) {
|
for (TypeArgumentKind taSite1 : TypeArgumentKind.values()) {
|
||||||
boolean isSiteRaw = taSite1 == TypeArgumentKind.NONE;
|
boolean isSiteRaw =
|
||||||
|
taSite1 == TypeArgumentKind.NONE;
|
||||||
//diamond only allowed on the last type qualifier
|
//diamond only allowed on the last type qualifier
|
||||||
if (taSite1 == TypeArgumentKind.DIAMOND &&
|
if (taSite1 == TypeArgumentKind.DIAMOND &&
|
||||||
innerClassDeclArity != InnerClassDeclArity.ONE) continue;
|
innerClassDeclArity !=
|
||||||
|
InnerClassDeclArity.ONE)
|
||||||
|
continue;
|
||||||
for (ArgumentKind arg1 : ArgumentKind.values()) {
|
for (ArgumentKind arg1 : ArgumentKind.values()) {
|
||||||
if (innerClassDeclArity == innerClassDeclArity.ONE) {
|
if (innerClassDeclArity == innerClassDeclArity.ONE) {
|
||||||
new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
|
pool.execute(
|
||||||
argList, new TypeArgumentKind[] {taDecl1},
|
new DiamondAndInnerClassTest(
|
||||||
new TypeArgumentKind[] {taSite1}, new ArgumentKind[] {arg1}).run(comp, fm);
|
innerClassDeclArity, declType,
|
||||||
|
newClassType, argList,
|
||||||
|
new TypeArgumentKind[] {taDecl1},
|
||||||
|
new TypeArgumentKind[] {taSite1},
|
||||||
|
new ArgumentKind[] {arg1}));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (TypeArgumentKind taDecl2 : TypeArgumentKind.values()) {
|
for (TypeArgumentKind taDecl2 : TypeArgumentKind.values()) {
|
||||||
//no rare types
|
//no rare types
|
||||||
if (isDeclRaw != (taDecl2 == TypeArgumentKind.NONE)) continue;
|
if (isDeclRaw != (taDecl2 == TypeArgumentKind.NONE))
|
||||||
|
continue;
|
||||||
//no diamond on decl site
|
//no diamond on decl site
|
||||||
if (taDecl2 == TypeArgumentKind.DIAMOND) continue;
|
if (taDecl2 == TypeArgumentKind.DIAMOND)
|
||||||
|
continue;
|
||||||
for (TypeArgumentKind taSite2 : TypeArgumentKind.values()) {
|
for (TypeArgumentKind taSite2 : TypeArgumentKind.values()) {
|
||||||
//no rare types
|
//no rare types
|
||||||
if (isSiteRaw != (taSite2 == TypeArgumentKind.NONE)) continue;
|
if (isSiteRaw != (taSite2 == TypeArgumentKind.NONE))
|
||||||
|
continue;
|
||||||
//diamond only allowed on the last type qualifier
|
//diamond only allowed on the last type qualifier
|
||||||
if (taSite2 == TypeArgumentKind.DIAMOND &&
|
if (taSite2 == TypeArgumentKind.DIAMOND &&
|
||||||
innerClassDeclArity != InnerClassDeclArity.TWO) continue;
|
innerClassDeclArity != InnerClassDeclArity.TWO)
|
||||||
|
continue;
|
||||||
for (ArgumentKind arg2 : ArgumentKind.values()) {
|
for (ArgumentKind arg2 : ArgumentKind.values()) {
|
||||||
if (innerClassDeclArity == innerClassDeclArity.TWO) {
|
if (innerClassDeclArity == innerClassDeclArity.TWO) {
|
||||||
new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
|
pool.execute(
|
||||||
argList, new TypeArgumentKind[] {taDecl1, taDecl2},
|
new DiamondAndInnerClassTest(
|
||||||
|
innerClassDeclArity,
|
||||||
|
declType,
|
||||||
|
newClassType,
|
||||||
|
argList,
|
||||||
|
new TypeArgumentKind[] {taDecl1, taDecl2},
|
||||||
new TypeArgumentKind[] {taSite1, taSite2},
|
new TypeArgumentKind[] {taSite1, taSite2},
|
||||||
new ArgumentKind[] {arg1, arg2}).run(comp, fm);
|
new ArgumentKind[] {arg1, arg2}));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (TypeArgumentKind taDecl3 : TypeArgumentKind.values()) {
|
for (TypeArgumentKind taDecl3 : TypeArgumentKind.values()) {
|
||||||
//no rare types
|
//no rare types
|
||||||
if (isDeclRaw != (taDecl3 == TypeArgumentKind.NONE)) continue;
|
if (isDeclRaw != (taDecl3 == TypeArgumentKind.NONE))
|
||||||
|
continue;
|
||||||
//no diamond on decl site
|
//no diamond on decl site
|
||||||
if (taDecl3 == TypeArgumentKind.DIAMOND) continue;
|
if (taDecl3 == TypeArgumentKind.DIAMOND)
|
||||||
|
continue;
|
||||||
for (TypeArgumentKind taSite3 : TypeArgumentKind.values()) {
|
for (TypeArgumentKind taSite3 : TypeArgumentKind.values()) {
|
||||||
//no rare types
|
//no rare types
|
||||||
if (isSiteRaw != (taSite3 == TypeArgumentKind.NONE)) continue;
|
if (isSiteRaw != (taSite3 == TypeArgumentKind.NONE))
|
||||||
|
continue;
|
||||||
//diamond only allowed on the last type qualifier
|
//diamond only allowed on the last type qualifier
|
||||||
if (taSite3 == TypeArgumentKind.DIAMOND &&
|
if (taSite3 == TypeArgumentKind.DIAMOND &&
|
||||||
innerClassDeclArity != InnerClassDeclArity.THREE) continue;
|
innerClassDeclArity != InnerClassDeclArity.THREE)
|
||||||
|
continue;
|
||||||
for (ArgumentKind arg3 : ArgumentKind.values()) {
|
for (ArgumentKind arg3 : ArgumentKind.values()) {
|
||||||
if (innerClassDeclArity == innerClassDeclArity.THREE) {
|
if (innerClassDeclArity ==
|
||||||
new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
|
innerClassDeclArity.THREE) {
|
||||||
argList, new TypeArgumentKind[] {taDecl1, taDecl2, taDecl3},
|
pool.execute(
|
||||||
|
new DiamondAndInnerClassTest(
|
||||||
|
innerClassDeclArity,
|
||||||
|
declType,
|
||||||
|
newClassType,
|
||||||
|
argList,
|
||||||
|
new TypeArgumentKind[] {taDecl1, taDecl2, taDecl3},
|
||||||
new TypeArgumentKind[] {taSite1, taSite2, taSite3},
|
new TypeArgumentKind[] {taSite1, taSite2, taSite3},
|
||||||
new ArgumentKind[] {arg1, arg2, arg3}).run(comp, fm);
|
new ArgumentKind[] {arg1, arg2, arg3}));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,7 +251,8 @@ public class DiamondAndInnerClassTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Total check executed: " + checkCount);
|
|
||||||
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
InnerClassDeclArity innerClassDeclArity;
|
InnerClassDeclArity innerClassDeclArity;
|
||||||
@ -244,9 +266,9 @@ public class DiamondAndInnerClassTest {
|
|||||||
DiagnosticChecker diagChecker;
|
DiagnosticChecker diagChecker;
|
||||||
|
|
||||||
DiamondAndInnerClassTest(InnerClassDeclArity innerClassDeclArity,
|
DiamondAndInnerClassTest(InnerClassDeclArity innerClassDeclArity,
|
||||||
TypeQualifierArity declType, TypeQualifierArity siteType, ArgumentListArity argList,
|
TypeQualifierArity declType, TypeQualifierArity siteType,
|
||||||
TypeArgumentKind[] declTypeArgumentKinds, TypeArgumentKind[] siteTypeArgumentKinds,
|
ArgumentListArity argList, TypeArgumentKind[] declTypeArgumentKinds,
|
||||||
ArgumentKind[] argumentKinds) {
|
TypeArgumentKind[] siteTypeArgumentKinds, ArgumentKind[] argumentKinds) {
|
||||||
this.innerClassDeclArity = innerClassDeclArity;
|
this.innerClassDeclArity = innerClassDeclArity;
|
||||||
this.declType = declType;
|
this.declType = declType;
|
||||||
this.siteType = siteType;
|
this.siteType = siteType;
|
||||||
@ -267,9 +289,9 @@ public class DiamondAndInnerClassTest {
|
|||||||
public JavaSource() {
|
public JavaSource() {
|
||||||
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
||||||
source = innerClassDeclArity.classDeclStr.replace("#B", bodyTemplate)
|
source = innerClassDeclArity.classDeclStr.replace("#B", bodyTemplate)
|
||||||
.replace("#D", declType.getType(declTypeArgumentKinds))
|
.replace("#D", declType.getType(declTypeArgumentKinds))
|
||||||
.replace("#S", siteType.getType(siteTypeArgumentKinds))
|
.replace("#S", siteType.getType(siteTypeArgumentKinds))
|
||||||
.replace("#AL", argList.getArgs(argumentKinds));
|
.replace("#AL", argList.getArgs(argumentKinds));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -278,36 +300,39 @@ public class DiamondAndInnerClassTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
|
@Override
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
|
public void run() {
|
||||||
|
JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
|
||||||
null, null, Arrays.asList(source));
|
null, null, Arrays.asList(source));
|
||||||
try {
|
try {
|
||||||
ct.analyze();
|
ct.analyze();
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
|
throw new AssertionError("Error thrown when compiling the following code:\n" +
|
||||||
|
source.getCharContent(true));
|
||||||
}
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void check() {
|
void check() {
|
||||||
checkCount++;
|
checkCount.incrementAndGet();
|
||||||
|
|
||||||
boolean errorExpected = false;
|
boolean errorExpected = false;
|
||||||
|
|
||||||
TypeArgumentKind[] expectedArgKinds = new TypeArgumentKind[innerClassDeclArity.n];
|
TypeArgumentKind[] expectedArgKinds =
|
||||||
|
new TypeArgumentKind[innerClassDeclArity.n];
|
||||||
|
|
||||||
for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
|
for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
|
||||||
if (!declTypeArgumentKinds[i].compatible(siteTypeArgumentKinds[i])) {
|
if (!declTypeArgumentKinds[i].compatible(siteTypeArgumentKinds[i])) {
|
||||||
errorExpected = true;
|
errorExpected = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
expectedArgKinds[i] = siteTypeArgumentKinds[i] == TypeArgumentKind.DIAMOND ?
|
expectedArgKinds[i] = siteTypeArgumentKinds[i] ==
|
||||||
|
TypeArgumentKind.DIAMOND ?
|
||||||
declTypeArgumentKinds[i] : siteTypeArgumentKinds[i];
|
declTypeArgumentKinds[i] : siteTypeArgumentKinds[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!errorExpected) {
|
if (!errorExpected) {
|
||||||
for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
|
for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
|
||||||
//System.out.println("check " + expectedArgKinds[i] + " against " + argumentKinds[i]);
|
|
||||||
if (!expectedArgKinds[i].compatible(argumentKinds[i])) {
|
if (!expectedArgKinds[i].compatible(argumentKinds[i])) {
|
||||||
errorExpected = true;
|
errorExpected = true;
|
||||||
break;
|
break;
|
||||||
@ -323,7 +348,8 @@ public class DiamondAndInnerClassTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class DiagnosticChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
boolean errorFound;
|
boolean errorFound;
|
||||||
|
|
||||||
@ -333,4 +359,5 @@ public class DiamondAndInnerClassTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,22 +24,23 @@
|
|||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 7062745
|
* @bug 7062745
|
||||||
* @summary Regression: difference in overload resolution when two methods are maximally specific
|
* @summary Regression: difference in overload resolution when two methods
|
||||||
|
* are maximally specific
|
||||||
|
* @library ../../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main GenericOverrideTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
import com.sun.source.util.JavacTask;
|
||||||
import javax.tools.ToolProvider;
|
|
||||||
|
|
||||||
public class GenericOverrideTest {
|
public class GenericOverrideTest
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
static int checkCount = 0;
|
implements Runnable {
|
||||||
|
|
||||||
enum SignatureKind {
|
enum SignatureKind {
|
||||||
NON_GENERIC(""),
|
NON_GENERIC(""),
|
||||||
@ -126,11 +127,6 @@ public class GenericOverrideTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
|
|
||||||
//create default shared JavaCompiler - reused across multiple compilations
|
|
||||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
|
||||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
for (SignatureKind sig1 : SignatureKind.values()) {
|
for (SignatureKind sig1 : SignatureKind.values()) {
|
||||||
for (ReturnTypeKind rt1 : ReturnTypeKind.values()) {
|
for (ReturnTypeKind rt1 : ReturnTypeKind.values()) {
|
||||||
for (TypeArgumentKind ta1 : TypeArgumentKind.values()) {
|
for (TypeArgumentKind ta1 : TypeArgumentKind.values()) {
|
||||||
@ -141,8 +137,12 @@ public class GenericOverrideTest {
|
|||||||
if (!ta2.compatibleWith(sig2)) continue;
|
if (!ta2.compatibleWith(sig2)) continue;
|
||||||
for (ReturnTypeKind rt3 : ReturnTypeKind.values()) {
|
for (ReturnTypeKind rt3 : ReturnTypeKind.values()) {
|
||||||
for (TypeArgumentKind ta3 : TypeArgumentKind.values()) {
|
for (TypeArgumentKind ta3 : TypeArgumentKind.values()) {
|
||||||
if (!ta3.compatibleWith(SignatureKind.NON_GENERIC)) continue;
|
if (!ta3.compatibleWith(SignatureKind.NON_GENERIC))
|
||||||
new GenericOverrideTest(sig1, rt1, ta1, sig2, rt2, ta2, rt3, ta3).run(comp, fm);
|
continue;
|
||||||
|
pool.execute(
|
||||||
|
new GenericOverrideTest(sig1,
|
||||||
|
rt1, ta1, sig2, rt2,
|
||||||
|
ta2, rt3, ta3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,7 +151,8 @@ public class GenericOverrideTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Total check executed: " + checkCount);
|
|
||||||
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
SignatureKind sig1, sig2;
|
SignatureKind sig1, sig2;
|
||||||
@ -161,7 +162,8 @@ public class GenericOverrideTest {
|
|||||||
DiagnosticChecker diagChecker;
|
DiagnosticChecker diagChecker;
|
||||||
|
|
||||||
GenericOverrideTest(SignatureKind sig1, ReturnTypeKind rt1, TypeArgumentKind ta1,
|
GenericOverrideTest(SignatureKind sig1, ReturnTypeKind rt1, TypeArgumentKind ta1,
|
||||||
SignatureKind sig2, ReturnTypeKind rt2, TypeArgumentKind ta2, ReturnTypeKind rt3, TypeArgumentKind ta3) {
|
SignatureKind sig2, ReturnTypeKind rt2, TypeArgumentKind ta2,
|
||||||
|
ReturnTypeKind rt3, TypeArgumentKind ta3) {
|
||||||
this.sig1 = sig1;
|
this.sig1 = sig1;
|
||||||
this.sig2 = sig2;
|
this.sig2 = sig2;
|
||||||
this.rt1 = rt1;
|
this.rt1 = rt1;
|
||||||
@ -204,19 +206,21 @@ public class GenericOverrideTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
|
@Override
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
|
public void run() {
|
||||||
|
JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
|
||||||
null, null, Arrays.asList(source));
|
null, null, Arrays.asList(source));
|
||||||
try {
|
try {
|
||||||
ct.analyze();
|
ct.analyze();
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
|
throw new AssertionError("Error thrown when compiling the following code:\n" +
|
||||||
|
source.getCharContent(true));
|
||||||
}
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void check() {
|
void check() {
|
||||||
checkCount++;
|
checkCount.incrementAndGet();
|
||||||
|
|
||||||
boolean errorExpected = false;
|
boolean errorExpected = false;
|
||||||
int mostSpecific = 0;
|
int mostSpecific = 0;
|
||||||
@ -234,14 +238,17 @@ public class GenericOverrideTest {
|
|||||||
//check that either TA1 <= TA2 or TA2 <= TA1 (unless most specific return found above is raw)
|
//check that either TA1 <= TA2 or TA2 <= TA1 (unless most specific return found above is raw)
|
||||||
if (!errorExpected) {
|
if (!errorExpected) {
|
||||||
if (ta1 != ta2) {
|
if (ta1 != ta2) {
|
||||||
boolean useStrictCheck = ta1.moreSpecificThan(ta2, true) || ta2.moreSpecificThan(ta1, true);
|
boolean useStrictCheck = ta1.moreSpecificThan(ta2, true) ||
|
||||||
|
ta2.moreSpecificThan(ta1, true);
|
||||||
if (!ta1.moreSpecificThan(ta2, useStrictCheck) &&
|
if (!ta1.moreSpecificThan(ta2, useStrictCheck) &&
|
||||||
!ta2.moreSpecificThan(ta1, useStrictCheck)) {
|
!ta2.moreSpecificThan(ta1, useStrictCheck)) {
|
||||||
errorExpected = true;
|
errorExpected = true;
|
||||||
} else {
|
} else {
|
||||||
int mostSpecific2 = ta1.moreSpecificThan(ta2, useStrictCheck) ? 1 : 2;
|
int mostSpecific2 = ta1.moreSpecificThan(ta2, useStrictCheck) ? 1 : 2;
|
||||||
if (mostSpecific != 0 && mostSpecific2 != mostSpecific) {
|
if (mostSpecific != 0 && mostSpecific2 != mostSpecific) {
|
||||||
errorExpected = mostSpecific == 1 ? ta1 != TypeArgumentKind.NONE : ta2 != TypeArgumentKind.NONE;
|
errorExpected = mostSpecific == 1 ?
|
||||||
|
ta1 != TypeArgumentKind.NONE :
|
||||||
|
ta2 != TypeArgumentKind.NONE;
|
||||||
} else {
|
} else {
|
||||||
mostSpecific = mostSpecific2;
|
mostSpecific = mostSpecific2;
|
||||||
}
|
}
|
||||||
@ -273,7 +280,8 @@ public class GenericOverrideTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class DiagnosticChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
boolean errorFound;
|
boolean errorFound;
|
||||||
|
|
||||||
@ -283,4 +291,5 @@ public class GenericOverrideTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,20 +27,24 @@
|
|||||||
* @summary Add lambda tests
|
* @summary Add lambda tests
|
||||||
* perform several automated checks in lambda conversion, esp. around accessibility
|
* perform several automated checks in lambda conversion, esp. around accessibility
|
||||||
* @author Maurizio Cimadamore
|
* @author Maurizio Cimadamore
|
||||||
|
* @library ../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
* @run main FunctionalInterfaceConversionTest
|
* @run main FunctionalInterfaceConversionTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
import javax.tools.ToolProvider;
|
import javax.tools.ToolProvider;
|
||||||
|
import com.sun.source.util.JavacTask;
|
||||||
|
|
||||||
public class FunctionalInterfaceConversionTest {
|
public class FunctionalInterfaceConversionTest
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
|
implements Runnable {
|
||||||
|
|
||||||
enum PackageKind {
|
enum PackageKind {
|
||||||
NO_PKG(""),
|
NO_PKG(""),
|
||||||
@ -139,8 +143,6 @@ public class FunctionalInterfaceConversionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
|
||||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
|
||||||
for (PackageKind samPkg : PackageKind.values()) {
|
for (PackageKind samPkg : PackageKind.values()) {
|
||||||
for (ModifierKind modKind : ModifierKind.values()) {
|
for (ModifierKind modKind : ModifierKind.values()) {
|
||||||
for (SamKind samKind : SamKind.values()) {
|
for (SamKind samKind : SamKind.values()) {
|
||||||
@ -150,8 +152,11 @@ public class FunctionalInterfaceConversionTest {
|
|||||||
for (TypeKind argType : TypeKind.values()) {
|
for (TypeKind argType : TypeKind.values()) {
|
||||||
for (TypeKind thrownType : TypeKind.values()) {
|
for (TypeKind thrownType : TypeKind.values()) {
|
||||||
for (ExprKind exprKind : ExprKind.values()) {
|
for (ExprKind exprKind : ExprKind.values()) {
|
||||||
new FunctionalInterfaceConversionTest(samPkg, modKind, samKind,
|
pool.execute(
|
||||||
samMeth, clientMeth, retType, argType, thrownType, exprKind).test(comp, fm);
|
new FunctionalInterfaceConversionTest(
|
||||||
|
samPkg, modKind, samKind,
|
||||||
|
samMeth, clientMeth, retType,
|
||||||
|
argType, thrownType, exprKind));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,6 +166,8 @@ public class FunctionalInterfaceConversionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkAfterExec(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageKind samPkg;
|
PackageKind samPkg;
|
||||||
@ -175,24 +182,30 @@ public class FunctionalInterfaceConversionTest {
|
|||||||
DiagnosticChecker dc;
|
DiagnosticChecker dc;
|
||||||
|
|
||||||
SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
|
SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return template.replaceAll("#P", samPkg.getPkgDecl()).
|
return template.replaceAll("#P", samPkg.getPkgDecl()).
|
||||||
replaceAll("#C", samKind.getSam(samMeth.getMethod(retType, argType, thrownType)));
|
replaceAll("#C", samKind.getSam(
|
||||||
|
samMeth.getMethod(retType, argType, thrownType)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SourceFile pkgClassSourceFile = new SourceFile("PackageClass.java",
|
SourceFile pkgClassSourceFile =
|
||||||
"#P\n #M class PackageClass extends Exception { }") {
|
new SourceFile("PackageClass.java",
|
||||||
|
"#P\n #M class PackageClass extends Exception { }") {
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return template.replaceAll("#P", samPkg.getPkgDecl()).
|
return template.replaceAll("#P", samPkg.getPkgDecl()).
|
||||||
replaceAll("#M", modKind.modifier_str);
|
replaceAll("#M", modKind.modifier_str);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SourceFile clientSourceFile = new SourceFile("Client.java",
|
SourceFile clientSourceFile =
|
||||||
"#I\n abstract class Client { \n" +
|
new SourceFile("Client.java",
|
||||||
" Sam s = #E;\n" +
|
"#I\n abstract class Client { \n" +
|
||||||
" #M \n }") {
|
" Sam s = #E;\n" +
|
||||||
|
" #M \n }") {
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return template.replaceAll("#I", samPkg.getImportStat())
|
return template.replaceAll("#I", samPkg.getImportStat())
|
||||||
.replaceAll("#E", exprKind.exprStr)
|
.replaceAll("#E", exprKind.exprStr)
|
||||||
@ -200,9 +213,10 @@ public class FunctionalInterfaceConversionTest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FunctionalInterfaceConversionTest(PackageKind samPkg, ModifierKind modKind, SamKind samKind,
|
FunctionalInterfaceConversionTest(PackageKind samPkg, ModifierKind modKind,
|
||||||
MethodKind samMeth, MethodKind clientMeth, TypeKind retType, TypeKind argType,
|
SamKind samKind, MethodKind samMeth, MethodKind clientMeth,
|
||||||
TypeKind thrownType, ExprKind exprKind) {
|
TypeKind retType, TypeKind argType, TypeKind thrownType,
|
||||||
|
ExprKind exprKind) {
|
||||||
this.samPkg = samPkg;
|
this.samPkg = samPkg;
|
||||||
this.modKind = modKind;
|
this.modKind = modKind;
|
||||||
this.samKind = samKind;
|
this.samKind = samKind;
|
||||||
@ -215,12 +229,20 @@ public class FunctionalInterfaceConversionTest {
|
|||||||
this.dc = new DiagnosticChecker();
|
this.dc = new DiagnosticChecker();
|
||||||
}
|
}
|
||||||
|
|
||||||
void test(JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
|
@Override
|
||||||
JavacTask ct = (JavacTask)comp.getTask(null, fm, dc,
|
public void run() {
|
||||||
null, null, Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
|
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
||||||
ct.analyze();
|
|
||||||
|
JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), dc, null, null,
|
||||||
|
Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
|
||||||
|
try {
|
||||||
|
ct.analyze();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new AssertionError("Test failing with cause", ex.getCause());
|
||||||
|
}
|
||||||
if (dc.errorFound == checkSamConversion()) {
|
if (dc.errorFound == checkSamConversion()) {
|
||||||
throw new AssertionError(samSourceFile + "\n\n" + pkgClassSourceFile + "\n\n" + clientSourceFile);
|
throw new AssertionError(samSourceFile + "\n\n" +
|
||||||
|
pkgClassSourceFile + "\n\n" + clientSourceFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,13 +286,16 @@ public class FunctionalInterfaceConversionTest {
|
|||||||
return toString();
|
return toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public abstract String toString();
|
public abstract String toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class DiagnosticChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
boolean errorFound = false;
|
boolean errorFound = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
||||||
errorFound = true;
|
errorFound = true;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,21 +27,21 @@
|
|||||||
* @bug 8003280
|
* @bug 8003280
|
||||||
* @summary Add lambda tests
|
* @summary Add lambda tests
|
||||||
* Add parser support for lambda expressions
|
* Add parser support for lambda expressions
|
||||||
|
* @library ../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main LambdaParserTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
import com.sun.source.util.JavacTask;
|
||||||
import javax.tools.ToolProvider;
|
|
||||||
|
|
||||||
public class LambdaParserTest {
|
public class LambdaParserTest
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
static int checkCount = 0;
|
implements Runnable {
|
||||||
|
|
||||||
enum LambdaKind {
|
enum LambdaKind {
|
||||||
NILARY_EXPR("()->x"),
|
NILARY_EXPR("()->x"),
|
||||||
@ -173,25 +173,26 @@ public class LambdaParserTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
|
|
||||||
//create default shared JavaCompiler - reused across multiple compilations
|
|
||||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
|
||||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
for (LambdaKind lk : LambdaKind.values()) {
|
for (LambdaKind lk : LambdaKind.values()) {
|
||||||
for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
|
for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
|
||||||
if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT) continue;
|
if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT)
|
||||||
|
continue;
|
||||||
for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
|
for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
|
||||||
if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT) continue;
|
if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT)
|
||||||
|
continue;
|
||||||
for (ModifierKind mk1 : ModifierKind.values()) {
|
for (ModifierKind mk1 : ModifierKind.values()) {
|
||||||
if (mk1 != ModifierKind.NONE && lk.isShort()) continue;
|
if (mk1 != ModifierKind.NONE && lk.isShort())
|
||||||
if (lk.arity() < 1 && mk1 != ModifierKind.NONE) continue;
|
continue;
|
||||||
|
if (lk.arity() < 1 && mk1 != ModifierKind.NONE)
|
||||||
|
continue;
|
||||||
for (ModifierKind mk2 : ModifierKind.values()) {
|
for (ModifierKind mk2 : ModifierKind.values()) {
|
||||||
if (lk.arity() < 2 && mk2 != ModifierKind.NONE) continue;
|
if (lk.arity() < 2 && mk2 != ModifierKind.NONE)
|
||||||
|
continue;
|
||||||
for (SubExprKind sk : SubExprKind.values()) {
|
for (SubExprKind sk : SubExprKind.values()) {
|
||||||
for (ExprKind ek : ExprKind.values()) {
|
for (ExprKind ek : ExprKind.values()) {
|
||||||
new LambdaParserTest(pk1, pk2, mk1, mk2, lk, sk, ek)
|
pool.execute(
|
||||||
.run(comp, fm);
|
new LambdaParserTest(pk1, pk2, mk1,
|
||||||
|
mk2, lk, sk, ek));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,7 +200,8 @@ public class LambdaParserTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Total check executed: " + checkCount);
|
|
||||||
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
LambdaParameterKind pk1;
|
LambdaParameterKind pk1;
|
||||||
@ -212,8 +214,9 @@ public class LambdaParserTest {
|
|||||||
JavaSource source;
|
JavaSource source;
|
||||||
DiagnosticChecker diagChecker;
|
DiagnosticChecker diagChecker;
|
||||||
|
|
||||||
LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2, ModifierKind mk1,
|
LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2,
|
||||||
ModifierKind mk2, LambdaKind lk, SubExprKind sk, ExprKind ek) {
|
ModifierKind mk1, ModifierKind mk2, LambdaKind lk,
|
||||||
|
SubExprKind sk, ExprKind ek) {
|
||||||
this.pk1 = pk1;
|
this.pk1 = pk1;
|
||||||
this.pk2 = pk2;
|
this.pk2 = pk2;
|
||||||
this.mk1 = mk1;
|
this.mk1 = mk1;
|
||||||
@ -235,7 +238,8 @@ public class LambdaParserTest {
|
|||||||
|
|
||||||
public JavaSource() {
|
public JavaSource() {
|
||||||
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
||||||
source = template.replaceAll("#E", ek.expressionString(pk1, pk2, mk1, mk2, lk, sk));
|
source = template.replaceAll("#E",
|
||||||
|
ek.expressionString(pk1, pk2, mk1, mk2, lk, sk));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -244,19 +248,20 @@ public class LambdaParserTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
|
public void run() {
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
|
JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
|
||||||
null, null, Arrays.asList(source));
|
null, null, Arrays.asList(source));
|
||||||
try {
|
try {
|
||||||
ct.parse();
|
ct.parse();
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
throw new AssertionError("Error thrown when parsing the following source:\n" + source.getCharContent(true));
|
processException(ex);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void check() {
|
void check() {
|
||||||
checkCount++;
|
checkCount.incrementAndGet();
|
||||||
|
|
||||||
boolean errorExpected = (lk.arity() > 0 && !mk1.compatibleWith(pk1)) ||
|
boolean errorExpected = (lk.arity() > 0 && !mk1.compatibleWith(pk1)) ||
|
||||||
(lk.arity() > 1 && !mk2.compatibleWith(pk2));
|
(lk.arity() > 1 && !mk2.compatibleWith(pk2));
|
||||||
@ -275,7 +280,8 @@ public class LambdaParserTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class DiagnosticChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
boolean errorFound;
|
boolean errorFound;
|
||||||
|
|
||||||
@ -285,4 +291,5 @@ public class LambdaParserTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,21 +27,21 @@
|
|||||||
* @bug 8003280
|
* @bug 8003280
|
||||||
* @summary Add lambda tests
|
* @summary Add lambda tests
|
||||||
* Add parser support for method references
|
* Add parser support for method references
|
||||||
|
* @library ../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main MethodReferenceParserTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
import com.sun.source.util.JavacTask;
|
||||||
import javax.tools.ToolProvider;
|
|
||||||
|
|
||||||
public class MethodReferenceParserTest {
|
public class MethodReferenceParserTest
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
static int checkCount = 0;
|
implements Runnable {
|
||||||
|
|
||||||
enum ReferenceKind {
|
enum ReferenceKind {
|
||||||
METHOD_REF("#Q::#Gm"),
|
METHOD_REF("#Q::#Gm"),
|
||||||
@ -88,7 +88,8 @@ public class MethodReferenceParserTest {
|
|||||||
this.contextTemplate = contextTemplate;
|
this.contextTemplate = contextTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
String contextString(ExprKind ek, ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk) {
|
String contextString(ExprKind ek, ReferenceKind rk, QualifierKind qk,
|
||||||
|
GenericKind gk, SubExprKind sk) {
|
||||||
return contextTemplate.replaceAll("#E", ek.expressionString(rk, qk, gk, sk));
|
return contextTemplate.replaceAll("#E", ek.expressionString(rk, qk, gk, sk));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,25 +166,21 @@ public class MethodReferenceParserTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
|
|
||||||
//create default shared JavaCompiler - reused across multiple compilations
|
|
||||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
|
||||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
for (ReferenceKind rk : ReferenceKind.values()) {
|
for (ReferenceKind rk : ReferenceKind.values()) {
|
||||||
for (QualifierKind qk : QualifierKind.values()) {
|
for (QualifierKind qk : QualifierKind.values()) {
|
||||||
for (GenericKind gk : GenericKind.values()) {
|
for (GenericKind gk : GenericKind.values()) {
|
||||||
for (SubExprKind sk : SubExprKind.values()) {
|
for (SubExprKind sk : SubExprKind.values()) {
|
||||||
for (ExprKind ek : ExprKind.values()) {
|
for (ExprKind ek : ExprKind.values()) {
|
||||||
for (ContextKind ck : ContextKind.values()) {
|
for (ContextKind ck : ContextKind.values()) {
|
||||||
new MethodReferenceParserTest(rk, qk, gk, sk, ek, ck).run(comp, fm);
|
pool.execute(new MethodReferenceParserTest(rk, qk, gk, sk, ek, ck));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Total check executed: " + checkCount);
|
|
||||||
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReferenceKind rk;
|
ReferenceKind rk;
|
||||||
@ -227,19 +224,21 @@ public class MethodReferenceParserTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
|
@Override
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
|
public void run() {
|
||||||
|
JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
|
||||||
null, null, Arrays.asList(source));
|
null, null, Arrays.asList(source));
|
||||||
try {
|
try {
|
||||||
ct.parse();
|
ct.parse();
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
throw new AssertionError("Error thrown when parsing the following source:\n" + source.getCharContent(true));
|
processException(ex);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void check() {
|
void check() {
|
||||||
checkCount++;
|
checkCount.incrementAndGet();
|
||||||
|
|
||||||
if (diagChecker.errorFound != rk.erroneous()) {
|
if (diagChecker.errorFound != rk.erroneous()) {
|
||||||
throw new Error("invalid diagnostics for source:\n" +
|
throw new Error("invalid diagnostics for source:\n" +
|
||||||
@ -259,4 +258,5 @@ public class MethodReferenceParserTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,7 +28,9 @@
|
|||||||
* @bug 8003280
|
* @bug 8003280
|
||||||
* @summary Add lambda tests
|
* @summary Add lambda tests
|
||||||
* Add back-end support for invokedynamic
|
* Add back-end support for invokedynamic
|
||||||
*
|
* @library ../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main TestInvokeDynamic
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.tree.MethodInvocationTree;
|
import com.sun.source.tree.MethodInvocationTree;
|
||||||
@ -66,7 +68,6 @@ import java.util.Locale;
|
|||||||
|
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.JavaFileManager;
|
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
import javax.tools.StandardJavaFileManager;
|
||||||
@ -74,69 +75,80 @@ import javax.tools.ToolProvider;
|
|||||||
|
|
||||||
import static com.sun.tools.javac.jvm.ClassFile.*;
|
import static com.sun.tools.javac.jvm.ClassFile.*;
|
||||||
|
|
||||||
public class TestInvokeDynamic {
|
public class TestInvokeDynamic
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
static int checkCount = 0;
|
implements Runnable {
|
||||||
|
|
||||||
enum StaticArgumentKind {
|
enum StaticArgumentKind {
|
||||||
STRING("Hello!", "String", "Ljava/lang/String;") {
|
STRING("Hello!", "String", "Ljava/lang/String;") {
|
||||||
@Override
|
@Override
|
||||||
boolean check(CPInfo cpInfo) throws Exception {
|
boolean check(CPInfo cpInfo) throws Exception {
|
||||||
return (cpInfo instanceof CONSTANT_String_info) &&
|
return (cpInfo instanceof CONSTANT_String_info) &&
|
||||||
((CONSTANT_String_info)cpInfo).getString().equals(value);
|
((CONSTANT_String_info)cpInfo).getString()
|
||||||
|
.equals(value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CLASS(null, "Class<?>", "Ljava/lang/Class;") {
|
CLASS(null, "Class<?>", "Ljava/lang/Class;") {
|
||||||
@Override
|
@Override
|
||||||
boolean check(CPInfo cpInfo) throws Exception {
|
boolean check(CPInfo cpInfo) throws Exception {
|
||||||
return (cpInfo instanceof CONSTANT_Class_info) &&
|
return (cpInfo instanceof CONSTANT_Class_info) &&
|
||||||
((CONSTANT_Class_info)cpInfo).getName().equals("java/lang/String");
|
((CONSTANT_Class_info)cpInfo).getName()
|
||||||
|
.equals("java/lang/String");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
INTEGER(1, "int", "I") {
|
INTEGER(1, "int", "I") {
|
||||||
@Override
|
@Override
|
||||||
boolean check(CPInfo cpInfo) throws Exception {
|
boolean check(CPInfo cpInfo) throws Exception {
|
||||||
return (cpInfo instanceof CONSTANT_Integer_info) &&
|
return (cpInfo instanceof CONSTANT_Integer_info) &&
|
||||||
((CONSTANT_Integer_info)cpInfo).value == ((Integer)value).intValue();
|
((CONSTANT_Integer_info)cpInfo).value ==
|
||||||
|
((Integer)value).intValue();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
LONG(1L, "long", "J") {
|
LONG(1L, "long", "J") {
|
||||||
@Override
|
@Override
|
||||||
boolean check(CPInfo cpInfo) throws Exception {
|
boolean check(CPInfo cpInfo) throws Exception {
|
||||||
return (cpInfo instanceof CONSTANT_Long_info) &&
|
return (cpInfo instanceof CONSTANT_Long_info) &&
|
||||||
((CONSTANT_Long_info)cpInfo).value == ((Long)value).longValue();
|
((CONSTANT_Long_info)cpInfo).value ==
|
||||||
|
((Long)value).longValue();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
FLOAT(1.0f, "float", "F") {
|
FLOAT(1.0f, "float", "F") {
|
||||||
@Override
|
@Override
|
||||||
boolean check(CPInfo cpInfo) throws Exception {
|
boolean check(CPInfo cpInfo) throws Exception {
|
||||||
return (cpInfo instanceof CONSTANT_Float_info) &&
|
return (cpInfo instanceof CONSTANT_Float_info) &&
|
||||||
((CONSTANT_Float_info)cpInfo).value == ((Float)value).floatValue();
|
((CONSTANT_Float_info)cpInfo).value ==
|
||||||
|
((Float)value).floatValue();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DOUBLE(1.0, "double","D") {
|
DOUBLE(1.0, "double","D") {
|
||||||
@Override
|
@Override
|
||||||
boolean check(CPInfo cpInfo) throws Exception {
|
boolean check(CPInfo cpInfo) throws Exception {
|
||||||
return (cpInfo instanceof CONSTANT_Double_info) &&
|
return (cpInfo instanceof CONSTANT_Double_info) &&
|
||||||
((CONSTANT_Double_info)cpInfo).value == ((Double)value).doubleValue();
|
((CONSTANT_Double_info)cpInfo).value ==
|
||||||
|
((Double)value).doubleValue();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
METHOD_HANDLE(null, "MethodHandle", "Ljava/lang/invoke/MethodHandle;") {
|
METHOD_HANDLE(null, "MethodHandle", "Ljava/lang/invoke/MethodHandle;") {
|
||||||
@Override
|
@Override
|
||||||
boolean check(CPInfo cpInfo) throws Exception {
|
boolean check(CPInfo cpInfo) throws Exception {
|
||||||
if (!(cpInfo instanceof CONSTANT_MethodHandle_info)) return false;
|
if (!(cpInfo instanceof CONSTANT_MethodHandle_info))
|
||||||
CONSTANT_MethodHandle_info handleInfo = (CONSTANT_MethodHandle_info)cpInfo;
|
return false;
|
||||||
|
CONSTANT_MethodHandle_info handleInfo =
|
||||||
|
(CONSTANT_MethodHandle_info)cpInfo;
|
||||||
return handleInfo.getCPRefInfo().getClassName().equals("Array") &&
|
return handleInfo.getCPRefInfo().getClassName().equals("Array") &&
|
||||||
handleInfo.reference_kind == RefKind.REF_invokeVirtual &&
|
handleInfo.reference_kind == RefKind.REF_invokeVirtual &&
|
||||||
handleInfo.getCPRefInfo().getNameAndTypeInfo().getName().equals("clone") &&
|
handleInfo.getCPRefInfo()
|
||||||
handleInfo.getCPRefInfo().getNameAndTypeInfo().getType().equals("()Ljava/lang/Object;");
|
.getNameAndTypeInfo().getName().equals("clone") &&
|
||||||
|
handleInfo.getCPRefInfo()
|
||||||
|
.getNameAndTypeInfo().getType().equals("()Ljava/lang/Object;");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
METHOD_TYPE(null, "MethodType", "Ljava/lang/invoke/MethodType;") {
|
METHOD_TYPE(null, "MethodType", "Ljava/lang/invoke/MethodType;") {
|
||||||
@Override
|
@Override
|
||||||
boolean check(CPInfo cpInfo) throws Exception {
|
boolean check(CPInfo cpInfo) throws Exception {
|
||||||
return (cpInfo instanceof CONSTANT_MethodType_info) &&
|
return (cpInfo instanceof CONSTANT_MethodType_info) &&
|
||||||
((CONSTANT_MethodType_info)cpInfo).getType().equals("()Ljava/lang/Object;");
|
((CONSTANT_MethodType_info)cpInfo).getType()
|
||||||
|
.equals("()Ljava/lang/Object;");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,7 +156,8 @@ public class TestInvokeDynamic {
|
|||||||
String sourceTypeStr;
|
String sourceTypeStr;
|
||||||
String bytecodeTypeStr;
|
String bytecodeTypeStr;
|
||||||
|
|
||||||
StaticArgumentKind(Object value, String sourceTypeStr, String bytecodeTypeStr) {
|
StaticArgumentKind(Object value, String sourceTypeStr,
|
||||||
|
String bytecodeTypeStr) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.sourceTypeStr = sourceTypeStr;
|
this.sourceTypeStr = sourceTypeStr;
|
||||||
this.bytecodeTypeStr = bytecodeTypeStr;
|
this.bytecodeTypeStr = bytecodeTypeStr;
|
||||||
@ -163,7 +176,8 @@ public class TestInvokeDynamic {
|
|||||||
case CLASS:
|
case CLASS:
|
||||||
return syms.stringType.tsym;
|
return syms.stringType.tsym;
|
||||||
case METHOD_HANDLE:
|
case METHOD_HANDLE:
|
||||||
return new Pool.MethodHandle(REF_invokeVirtual, syms.arrayCloneMethod, types);
|
return new Pool.MethodHandle(REF_invokeVirtual,
|
||||||
|
syms.arrayCloneMethod, types);
|
||||||
case METHOD_TYPE:
|
case METHOD_TYPE:
|
||||||
return syms.arrayCloneMethod.type;
|
return syms.arrayCloneMethod.type;
|
||||||
default:
|
default:
|
||||||
@ -186,23 +200,21 @@ public class TestInvokeDynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
// Create a single file manager and compiler and reuse it for each compile to save time.
|
|
||||||
StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
|
|
||||||
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
|
||||||
for (StaticArgumentsArity arity : StaticArgumentsArity.values()) {
|
for (StaticArgumentsArity arity : StaticArgumentsArity.values()) {
|
||||||
if (arity.arity == 0) {
|
if (arity.arity == 0) {
|
||||||
new TestInvokeDynamic(arity).compileAndCheck(fm, tool);
|
pool.execute(new TestInvokeDynamic(arity));
|
||||||
} else {
|
} else {
|
||||||
for (StaticArgumentKind sak1 : StaticArgumentKind.values()) {
|
for (StaticArgumentKind sak1 : StaticArgumentKind.values()) {
|
||||||
if (arity.arity == 1) {
|
if (arity.arity == 1) {
|
||||||
new TestInvokeDynamic(arity, sak1).compileAndCheck(fm, tool);
|
pool.execute(new TestInvokeDynamic(arity, sak1));
|
||||||
} else {
|
} else {
|
||||||
for (StaticArgumentKind sak2 : StaticArgumentKind.values()) {
|
for (StaticArgumentKind sak2 : StaticArgumentKind.values()) {
|
||||||
if (arity.arity == 2) {
|
if (arity.arity == 2) {
|
||||||
new TestInvokeDynamic(arity, sak1, sak2).compileAndCheck(fm, tool);
|
pool.execute(new TestInvokeDynamic(arity, sak1, sak2));
|
||||||
} else {
|
} else {
|
||||||
for (StaticArgumentKind sak3 : StaticArgumentKind.values()) {
|
for (StaticArgumentKind sak3 : StaticArgumentKind.values()) {
|
||||||
new TestInvokeDynamic(arity, sak1, sak2, sak3).compileAndCheck(fm, tool);
|
pool.execute(
|
||||||
|
new TestInvokeDynamic(arity, sak1, sak2, sak3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,23 +223,23 @@ public class TestInvokeDynamic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Total checks made: " + checkCount);
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticArgumentsArity arity;
|
StaticArgumentsArity arity;
|
||||||
StaticArgumentKind[] saks;
|
StaticArgumentKind[] saks;
|
||||||
JavaSource source;
|
|
||||||
DiagChecker dc;
|
DiagChecker dc;
|
||||||
|
|
||||||
TestInvokeDynamic(StaticArgumentsArity arity, StaticArgumentKind... saks) {
|
TestInvokeDynamic(StaticArgumentsArity arity, StaticArgumentKind... saks) {
|
||||||
this.arity = arity;
|
this.arity = arity;
|
||||||
this.saks = saks;
|
this.saks = saks;
|
||||||
source = new JavaSource();
|
|
||||||
dc = new DiagChecker();
|
dc = new DiagChecker();
|
||||||
}
|
}
|
||||||
|
|
||||||
void compileAndCheck(JavaFileManager fm, JavaCompiler tool) throws Exception {
|
public void run() {
|
||||||
JavacTaskImpl ct = (JavacTaskImpl)tool.getTask(null, fm, dc,
|
int id = checkCount.incrementAndGet();
|
||||||
|
JavaSource source = new JavaSource(id);
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl)comp.getTask(null, fm.get(), dc,
|
||||||
null, null, Arrays.asList(source));
|
null, null, Arrays.asList(source));
|
||||||
Context context = ct.getContext();
|
Context context = ct.getContext();
|
||||||
Symtab syms = Symtab.instance(context);
|
Symtab syms = Symtab.instance(context);
|
||||||
@ -238,16 +250,20 @@ public class TestInvokeDynamic {
|
|||||||
ct.generate();
|
ct.generate();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
throw new AssertionError(String.format("Error thrown when compiling following code\n%s", source.source));
|
throw new AssertionError(
|
||||||
|
String.format("Error thrown when compiling following code\n%s",
|
||||||
|
source.source));
|
||||||
}
|
}
|
||||||
if (dc.diagFound) {
|
if (dc.diagFound) {
|
||||||
throw new AssertionError(String.format("Diags found when compiling following code\n%s\n\n%s", source.source, dc.printDiags()));
|
throw new AssertionError(
|
||||||
|
String.format("Diags found when compiling following code\n%s\n\n%s",
|
||||||
|
source.source, dc.printDiags()));
|
||||||
}
|
}
|
||||||
verifyBytecode();
|
verifyBytecode(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void verifyBytecode() {
|
void verifyBytecode(int id) {
|
||||||
File compiledTest = new File("Test.class");
|
File compiledTest = new File(String.format("Test%d.class", id));
|
||||||
try {
|
try {
|
||||||
ClassFile cf = ClassFile.read(compiledTest);
|
ClassFile cf = ClassFile.read(compiledTest);
|
||||||
Method testMethod = null;
|
Method testMethod = null;
|
||||||
@ -260,7 +276,8 @@ public class TestInvokeDynamic {
|
|||||||
if (testMethod == null) {
|
if (testMethod == null) {
|
||||||
throw new Error("Test method not found");
|
throw new Error("Test method not found");
|
||||||
}
|
}
|
||||||
Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code);
|
Code_attribute ea =
|
||||||
|
(Code_attribute)testMethod.attributes.get(Attribute.Code);
|
||||||
if (testMethod == null) {
|
if (testMethod == null) {
|
||||||
throw new Error("Code attribute for test() method not found");
|
throw new Error("Code attribute for test() method not found");
|
||||||
}
|
}
|
||||||
@ -270,10 +287,12 @@ public class TestInvokeDynamic {
|
|||||||
for (Instruction i : ea.getInstructions()) {
|
for (Instruction i : ea.getInstructions()) {
|
||||||
if (i.getMnemonic().equals("invokedynamic")) {
|
if (i.getMnemonic().equals("invokedynamic")) {
|
||||||
CONSTANT_InvokeDynamic_info indyInfo =
|
CONSTANT_InvokeDynamic_info indyInfo =
|
||||||
(CONSTANT_InvokeDynamic_info)cf.constant_pool.get(i.getShort(1));
|
(CONSTANT_InvokeDynamic_info)cf
|
||||||
|
.constant_pool.get(i.getShort(1));
|
||||||
bsmIdx = indyInfo.bootstrap_method_attr_index;
|
bsmIdx = indyInfo.bootstrap_method_attr_index;
|
||||||
if (!indyInfo.getNameAndTypeInfo().getType().equals("()V")) {
|
if (!indyInfo.getNameAndTypeInfo().getType().equals("()V")) {
|
||||||
throw new AssertionError("type mismatch for CONSTANT_InvokeDynamic_info");
|
throw new
|
||||||
|
AssertionError("type mismatch for CONSTANT_InvokeDynamic_info");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,34 +300,41 @@ public class TestInvokeDynamic {
|
|||||||
throw new Error("Missing invokedynamic in generated code");
|
throw new Error("Missing invokedynamic in generated code");
|
||||||
}
|
}
|
||||||
|
|
||||||
BootstrapMethods_attribute bsm_attr = (BootstrapMethods_attribute)cf.getAttribute(Attribute.BootstrapMethods);
|
BootstrapMethods_attribute bsm_attr =
|
||||||
|
(BootstrapMethods_attribute)cf
|
||||||
|
.getAttribute(Attribute.BootstrapMethods);
|
||||||
if (bsm_attr.bootstrap_method_specifiers.length != 1) {
|
if (bsm_attr.bootstrap_method_specifiers.length != 1) {
|
||||||
throw new Error("Bad number of method specifiers in BootstrapMethods attribute");
|
throw new Error("Bad number of method specifiers " +
|
||||||
|
"in BootstrapMethods attribute");
|
||||||
}
|
}
|
||||||
BootstrapMethods_attribute.BootstrapMethodSpecifier bsm_spec =
|
BootstrapMethods_attribute.BootstrapMethodSpecifier bsm_spec =
|
||||||
bsm_attr.bootstrap_method_specifiers[0];
|
bsm_attr.bootstrap_method_specifiers[0];
|
||||||
|
|
||||||
if (bsm_spec.bootstrap_arguments.length != arity.arity) {
|
if (bsm_spec.bootstrap_arguments.length != arity.arity) {
|
||||||
throw new Error("Bad number of static invokedynamic args in BootstrapMethod attribute");
|
throw new Error("Bad number of static invokedynamic args " +
|
||||||
|
"in BootstrapMethod attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (StaticArgumentKind sak : saks) {
|
for (StaticArgumentKind sak : saks) {
|
||||||
if (!sak.check(cf.constant_pool.get(bsm_spec.bootstrap_arguments[count]))) {
|
if (!sak.check(cf.constant_pool
|
||||||
|
.get(bsm_spec.bootstrap_arguments[count]))) {
|
||||||
throw new Error("Bad static argument value " + sak);
|
throw new Error("Bad static argument value " + sak);
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
CONSTANT_MethodHandle_info bsm_handle =
|
CONSTANT_MethodHandle_info bsm_handle =
|
||||||
(CONSTANT_MethodHandle_info)cf.constant_pool.get(bsm_spec.bootstrap_method_ref);
|
(CONSTANT_MethodHandle_info)cf.constant_pool
|
||||||
|
.get(bsm_spec.bootstrap_method_ref);
|
||||||
|
|
||||||
if (bsm_handle.reference_kind != RefKind.REF_invokeStatic) {
|
if (bsm_handle.reference_kind != RefKind.REF_invokeStatic) {
|
||||||
throw new Error("Bad kind on boostrap method handle");
|
throw new Error("Bad kind on boostrap method handle");
|
||||||
}
|
}
|
||||||
|
|
||||||
CONSTANT_Methodref_info bsm_ref =
|
CONSTANT_Methodref_info bsm_ref =
|
||||||
(CONSTANT_Methodref_info)cf.constant_pool.get(bsm_handle.reference_index);
|
(CONSTANT_Methodref_info)cf.constant_pool
|
||||||
|
.get(bsm_handle.reference_index);
|
||||||
|
|
||||||
if (!bsm_ref.getClassInfo().getName().equals("Bootstrap")) {
|
if (!bsm_ref.getClassInfo().getName().equals("Bootstrap")) {
|
||||||
throw new Error("Bad owner of boostrap method");
|
throw new Error("Bad owner of boostrap method");
|
||||||
@ -318,8 +344,11 @@ public class TestInvokeDynamic {
|
|||||||
throw new Error("Bad boostrap method name");
|
throw new Error("Bad boostrap method name");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bsm_ref.getNameAndTypeInfo().getType().equals(asBSMSignatureString())) {
|
if (!bsm_ref.getNameAndTypeInfo()
|
||||||
throw new Error("Bad boostrap method type" + bsm_ref.getNameAndTypeInfo().getType() + " " + asBSMSignatureString());
|
.getType().equals(asBSMSignatureString())) {
|
||||||
|
throw new Error("Bad boostrap method type" +
|
||||||
|
bsm_ref.getNameAndTypeInfo().getType() + " " +
|
||||||
|
asBSMSignatureString());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -341,20 +370,22 @@ public class TestInvokeDynamic {
|
|||||||
|
|
||||||
static final String source_template = "import java.lang.invoke.*;\n" +
|
static final String source_template = "import java.lang.invoke.*;\n" +
|
||||||
"class Bootstrap {\n" +
|
"class Bootstrap {\n" +
|
||||||
" public static CallSite bsm(MethodHandles.Lookup lookup, String name, MethodType methodType #SARGS) {\n" +
|
" public static CallSite bsm(MethodHandles.Lookup lookup, " +
|
||||||
|
"String name, MethodType methodType #SARGS) {\n" +
|
||||||
" return null;\n" +
|
" return null;\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}\n" +
|
"}\n" +
|
||||||
"class Test {\n" +
|
"class Test#ID {\n" +
|
||||||
" void m() { }\n" +
|
" void m() { }\n" +
|
||||||
" void test() { m(); }\n" +
|
" void test() { m(); }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
String source;
|
String source;
|
||||||
|
|
||||||
JavaSource() {
|
JavaSource(int id) {
|
||||||
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
||||||
source = source_template.replace("#SARGS", asSignatureString());
|
source = source_template.replace("#SARGS", asSignatureString())
|
||||||
|
.replace("#ID", String.valueOf(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -411,7 +442,8 @@ public class TestInvokeDynamic {
|
|||||||
for (int i = 0; i < arity.arity ; i++) {
|
for (int i = 0; i < arity.arity ; i++) {
|
||||||
staticArgs[i] = saks[i].getValue(syms, names, types);
|
staticArgs[i] = saks[i].getValue(syms, names, types);
|
||||||
}
|
}
|
||||||
ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name, oldSym.owner, REF_invokeStatic, bsm, oldSym.type, staticArgs);
|
ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name,
|
||||||
|
oldSym.owner, REF_invokeStatic, bsm, oldSym.type, staticArgs);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -426,7 +458,8 @@ public class TestInvokeDynamic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DiagChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class DiagChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
boolean diagFound;
|
boolean diagFound;
|
||||||
ArrayList<String> diags = new ArrayList<>();
|
ArrayList<String> diags = new ArrayList<>();
|
||||||
@ -445,4 +478,5 @@ public class TestInvokeDynamic {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,24 +26,23 @@
|
|||||||
* @bug 8003280
|
* @bug 8003280
|
||||||
* @summary Add lambda tests
|
* @summary Add lambda tests
|
||||||
* Automatic test for checking correctness of structural most specific test routine
|
* Automatic test for checking correctness of structural most specific test routine
|
||||||
* @run main/timeout=360 StructuralMostSpecificTest
|
* @library ../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main/timeout=600 StructuralMostSpecificTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import com.sun.tools.javac.api.ClientCodeWrapper;
|
|
||||||
import com.sun.tools.javac.util.JCDiagnostic;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
import com.sun.source.util.JavacTask;
|
||||||
import javax.tools.ToolProvider;
|
import com.sun.tools.javac.api.ClientCodeWrapper;
|
||||||
|
import com.sun.tools.javac.util.JCDiagnostic;
|
||||||
|
|
||||||
public class StructuralMostSpecificTest {
|
public class StructuralMostSpecificTest
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
static int checkCount = 0;
|
implements Runnable {
|
||||||
|
|
||||||
enum RetTypeKind {
|
enum RetTypeKind {
|
||||||
SHORT("short"),
|
SHORT("short"),
|
||||||
@ -105,7 +104,7 @@ public class StructuralMostSpecificTest {
|
|||||||
VOID("return;"),
|
VOID("return;"),
|
||||||
SHORT("return (short)0;"),
|
SHORT("return (short)0;"),
|
||||||
INT("return 0;"),
|
INT("return 0;"),
|
||||||
INTEGER("return (Integer)null"),
|
INTEGER("return (Integer)null;"),
|
||||||
NULL("return null;");
|
NULL("return null;");
|
||||||
|
|
||||||
String retStr;
|
String retStr;
|
||||||
@ -142,11 +141,6 @@ public class StructuralMostSpecificTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
|
|
||||||
//create default shared JavaCompiler - reused across multiple compilations
|
|
||||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
|
||||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
for (LambdaReturnKind lrk : LambdaReturnKind.values()) {
|
for (LambdaReturnKind lrk : LambdaReturnKind.values()) {
|
||||||
for (RetTypeKind rk1 : RetTypeKind.values()) {
|
for (RetTypeKind rk1 : RetTypeKind.values()) {
|
||||||
for (RetTypeKind rk2 : RetTypeKind.values()) {
|
for (RetTypeKind rk2 : RetTypeKind.values()) {
|
||||||
@ -154,7 +148,9 @@ public class StructuralMostSpecificTest {
|
|||||||
for (ExceptionKind ek2 : ExceptionKind.values()) {
|
for (ExceptionKind ek2 : ExceptionKind.values()) {
|
||||||
for (ArgTypeKind ak11 : ArgTypeKind.values()) {
|
for (ArgTypeKind ak11 : ArgTypeKind.values()) {
|
||||||
for (ArgTypeKind ak12 : ArgTypeKind.values()) {
|
for (ArgTypeKind ak12 : ArgTypeKind.values()) {
|
||||||
new StructuralMostSpecificTest(lrk, rk1, rk2, ek1, ek2, ak11, ak12).run(comp, fm);
|
pool.execute(
|
||||||
|
new StructuralMostSpecificTest(lrk, rk1,
|
||||||
|
rk2, ek1, ek2, ak11, ak12));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,7 +158,8 @@ public class StructuralMostSpecificTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Total check executed: " + checkCount);
|
|
||||||
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
LambdaReturnKind lrk;
|
LambdaReturnKind lrk;
|
||||||
@ -218,20 +215,22 @@ public class StructuralMostSpecificTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
|
public void run() {
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
|
JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
|
||||||
Arrays.asList("-XDverboseResolution=all,-predef,-internal,-object-init"),
|
Arrays.asList("-XDverboseResolution=all,-predef,-internal,-object-init"),
|
||||||
null, Arrays.asList(source));
|
null, Arrays.asList(source));
|
||||||
try {
|
try {
|
||||||
ct.analyze();
|
ct.analyze();
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
throw new AssertionError("Error thron when analyzing the following source:\n" + source.getCharContent(true));
|
throw new
|
||||||
|
AssertionError("Error thron when analyzing the following source:\n" +
|
||||||
|
source.getCharContent(true));
|
||||||
}
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void check() {
|
void check() {
|
||||||
checkCount++;
|
checkCount.incrementAndGet();
|
||||||
|
|
||||||
if (!lrk.compatibleWith(rt1) || !lrk.compatibleWith(rt2))
|
if (!lrk.compatibleWith(rt1) || !lrk.compatibleWith(rt2))
|
||||||
return;
|
return;
|
||||||
@ -265,8 +264,8 @@ public class StructuralMostSpecificTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean moreSpecific(RetTypeKind rk1, RetTypeKind rk2, ExceptionKind ek1, ExceptionKind ek2,
|
boolean moreSpecific(RetTypeKind rk1, RetTypeKind rk2, ExceptionKind ek1,
|
||||||
ArgTypeKind ak1, ArgTypeKind ak2) {
|
ExceptionKind ek2, ArgTypeKind ak1, ArgTypeKind ak2) {
|
||||||
if (!rk1.moreSpecificThan(rk2))
|
if (!rk1.moreSpecificThan(rk2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -276,7 +275,8 @@ public class StructuralMostSpecificTest {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class DiagnosticChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
boolean ambiguityFound;
|
boolean ambiguityFound;
|
||||||
String mostSpecificSig;
|
String mostSpecificSig;
|
||||||
@ -287,12 +287,16 @@ public class StructuralMostSpecificTest {
|
|||||||
diagnostic.getCode().equals("compiler.err.ref.ambiguous")) {
|
diagnostic.getCode().equals("compiler.err.ref.ambiguous")) {
|
||||||
ambiguityFound = true;
|
ambiguityFound = true;
|
||||||
} else if (diagnostic.getKind() == Diagnostic.Kind.NOTE &&
|
} else if (diagnostic.getKind() == Diagnostic.Kind.NOTE &&
|
||||||
diagnostic.getCode().equals("compiler.note.verbose.resolve.multi")) {
|
diagnostic.getCode()
|
||||||
|
.equals("compiler.note.verbose.resolve.multi")) {
|
||||||
ClientCodeWrapper.DiagnosticSourceUnwrapper dsu =
|
ClientCodeWrapper.DiagnosticSourceUnwrapper dsu =
|
||||||
(ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic;
|
(ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic;
|
||||||
JCDiagnostic.MultilineDiagnostic mdiag = (JCDiagnostic.MultilineDiagnostic)dsu.d;
|
JCDiagnostic.MultilineDiagnostic mdiag =
|
||||||
|
(JCDiagnostic.MultilineDiagnostic)dsu.d;
|
||||||
int mostSpecificIndex = (Integer)mdiag.getArgs()[2];
|
int mostSpecificIndex = (Integer)mdiag.getArgs()[2];
|
||||||
mostSpecificSig = ((JCDiagnostic)mdiag.getSubdiagnostics().get(mostSpecificIndex)).getArgs()[1].toString();
|
mostSpecificSig =
|
||||||
|
((JCDiagnostic)mdiag.getSubdiagnostics()
|
||||||
|
.get(mostSpecificIndex)).getArgs()[1].toString();
|
||||||
}
|
}
|
||||||
} catch (RuntimeException t) {
|
} catch (RuntimeException t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
@ -300,4 +304,5 @@ public class StructuralMostSpecificTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,22 +25,24 @@
|
|||||||
* @test
|
* @test
|
||||||
* @bug 8003280
|
* @bug 8003280
|
||||||
* @summary Add lambda tests
|
* @summary Add lambda tests
|
||||||
* perform automated checks in type inference in lambda expressions in different contexts
|
* perform automated checks in type inference in lambda expressions
|
||||||
|
* in different contexts
|
||||||
|
* @library ../../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
* @compile TypeInferenceComboTest.java
|
* @compile TypeInferenceComboTest.java
|
||||||
* @run main/timeout=360 TypeInferenceComboTest
|
* @run main/timeout=360 TypeInferenceComboTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.ToolProvider;
|
import com.sun.source.util.JavacTask;
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
|
|
||||||
public class TypeInferenceComboTest {
|
public class TypeInferenceComboTest
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
|
implements Runnable {
|
||||||
enum Context {
|
enum Context {
|
||||||
ASSIGNMENT("SAM#Type s = #LBody;"),
|
ASSIGNMENT("SAM#Type s = #LBody;"),
|
||||||
METHOD_CALL("#GenericDeclKind void method1(SAM#Type s) { }\n" +
|
METHOD_CALL("#GenericDeclKind void method1(SAM#Type s) { }\n" +
|
||||||
@ -59,27 +61,35 @@ public class TypeInferenceComboTest {
|
|||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getContext(SamKind sk, TypeKind samTargetT, Keyword kw, TypeKind parameterT, TypeKind returnT, LambdaKind lk, ParameterKind pk, GenericDeclKind gdk, LambdaBody lb) {
|
String getContext(SamKind sk, TypeKind samTargetT, Keyword kw,
|
||||||
|
TypeKind parameterT, TypeKind returnT, LambdaKind lk,
|
||||||
|
ParameterKind pk, GenericDeclKind gdk, LambdaBody lb) {
|
||||||
String result = context;
|
String result = context;
|
||||||
if (sk == SamKind.GENERIC) {
|
if (sk == SamKind.GENERIC) {
|
||||||
if(this == Context.METHOD_CALL) {
|
if(this == Context.METHOD_CALL) {
|
||||||
result = result.replaceAll("#GenericDeclKind", gdk.getGenericDeclKind(samTargetT));
|
result = result.replaceAll("#GenericDeclKind",
|
||||||
|
gdk.getGenericDeclKind(samTargetT));
|
||||||
if(gdk == GenericDeclKind.NON_GENERIC)
|
if(gdk == GenericDeclKind.NON_GENERIC)
|
||||||
result = result.replaceAll("#Type", "<" + samTargetT.typeStr + ">");
|
result = result.replaceAll("#Type", "<" +
|
||||||
|
samTargetT.typeStr + ">");
|
||||||
else //#GenericDeclKind is <T> or <T extends xxx>
|
else //#GenericDeclKind is <T> or <T extends xxx>
|
||||||
result = result.replaceAll("#Type", "<T>");
|
result = result.replaceAll("#Type", "<T>");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(kw == Keyword.VOID)
|
if(kw == Keyword.VOID)
|
||||||
result = result.replaceAll("#Type", "<" + samTargetT.typeStr + ">");
|
result = result.replaceAll("#Type", "<" +
|
||||||
|
samTargetT.typeStr + ">");
|
||||||
else
|
else
|
||||||
result = result.replaceAll("#Type", "<? " + kw.keyStr + " " + samTargetT.typeStr + ">");
|
result = result.replaceAll("#Type", "<? " + kw.keyStr +
|
||||||
|
" " + samTargetT.typeStr + ">");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = result.replaceAll("#Type", "").replaceAll("#GenericDeclKind", "");
|
result = result.replaceAll("#Type", "").
|
||||||
|
replaceAll("#GenericDeclKind", "");
|
||||||
|
|
||||||
return result.replaceAll("#LBody", lb.getLambdaBody(samTargetT, parameterT, returnT, lk, pk));
|
return result.replaceAll("#LBody",
|
||||||
|
lb.getLambdaBody(samTargetT, parameterT, returnT, lk, pk));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,8 +104,10 @@ public class TypeInferenceComboTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String getSam(TypeKind parameterT, TypeKind returnT) {
|
String getSam(TypeKind parameterT, TypeKind returnT) {
|
||||||
return sam_str.replaceAll("#ARG", parameterT == TypeKind.VOID ? "" : parameterT.typeStr + " arg")
|
return sam_str.replaceAll("#ARG",
|
||||||
.replaceAll("#R", returnT.typeStr);
|
parameterT == TypeKind.VOID ?
|
||||||
|
"" : parameterT.typeStr + " arg")
|
||||||
|
.replaceAll("#R", returnT.typeStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +116,8 @@ public class TypeInferenceComboTest {
|
|||||||
STRING("String", "\"hello\""),
|
STRING("String", "\"hello\""),
|
||||||
INTEGER("Integer", "1"),
|
INTEGER("Integer", "1"),
|
||||||
INT("int", "0"),
|
INT("int", "0"),
|
||||||
COMPARATOR("java.util.Comparator<String>", "(java.util.Comparator<String>)(a, b) -> a.length()-b.length()"),
|
COMPARATOR("java.util.Comparator<String>",
|
||||||
|
"(java.util.Comparator<String>)(a, b) -> a.length()-b.length()"),
|
||||||
SAM("SAM2", "null"),
|
SAM("SAM2", "null"),
|
||||||
GENERIC("T", null);
|
GENERIC("T", null);
|
||||||
|
|
||||||
@ -152,8 +165,10 @@ public class TypeInferenceComboTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum LambdaBody {
|
enum LambdaBody {
|
||||||
RETURN_VOID("() -> #RET"),//no parameters, return type is one of the TypeKind
|
//no parameters, return type is one of the TypeKind
|
||||||
RETURN_ARG("(#PK arg) -> #RET");//has parameters, return type is one of the TypeKind
|
RETURN_VOID("() -> #RET"),
|
||||||
|
//has parameters, return type is one of the TypeKind
|
||||||
|
RETURN_ARG("(#PK arg) -> #RET");
|
||||||
|
|
||||||
String bodyStr;
|
String bodyStr;
|
||||||
|
|
||||||
@ -161,12 +176,14 @@ public class TypeInferenceComboTest {
|
|||||||
this.bodyStr = bodyStr;
|
this.bodyStr = bodyStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getLambdaBody(TypeKind samTargetT, TypeKind parameterT, TypeKind returnT, LambdaKind lk, ParameterKind pk) {
|
String getLambdaBody(TypeKind samTargetT, TypeKind parameterT,
|
||||||
|
TypeKind returnT, LambdaKind lk, ParameterKind pk) {
|
||||||
String result = bodyStr.replaceAll("#PK", pk.paramTemplate);
|
String result = bodyStr.replaceAll("#PK", pk.paramTemplate);
|
||||||
|
|
||||||
if(result.contains("#TYPE")) {
|
if(result.contains("#TYPE")) {
|
||||||
if (parameterT == TypeKind.GENERIC && this != RETURN_VOID)
|
if (parameterT == TypeKind.GENERIC && this != RETURN_VOID)
|
||||||
result = result.replaceAll("#TYPE", samTargetT == null? "": samTargetT.typeStr);
|
result = result.replaceAll("#TYPE",
|
||||||
|
samTargetT == null? "": samTargetT.typeStr);
|
||||||
else
|
else
|
||||||
result = result.replaceAll("#TYPE", parameterT.typeStr);
|
result = result.replaceAll("#TYPE", parameterT.typeStr);
|
||||||
}
|
}
|
||||||
@ -174,9 +191,12 @@ public class TypeInferenceComboTest {
|
|||||||
return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", "arg"));
|
return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", "arg"));
|
||||||
else {
|
else {
|
||||||
if(returnT != TypeKind.GENERIC)
|
if(returnT != TypeKind.GENERIC)
|
||||||
return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", (returnT==TypeKind.VOID && lk==LambdaKind.EXPRESSION)? "{}" : returnT.valStr));
|
return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL",
|
||||||
|
(returnT==TypeKind.VOID &&
|
||||||
|
lk==LambdaKind.EXPRESSION) ? "{}" : returnT.valStr));
|
||||||
else
|
else
|
||||||
return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", samTargetT.valStr));
|
return result.replaceAll("#RET",
|
||||||
|
lk.stmt.replaceAll("#VAL", samTargetT.valStr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,8 +223,10 @@ public class TypeInferenceComboTest {
|
|||||||
}
|
}
|
||||||
else if (lambdaBodyType != LambdaBody.RETURN_ARG)
|
else if (lambdaBodyType != LambdaBody.RETURN_ARG)
|
||||||
return false;
|
return false;
|
||||||
if ( genericDeclKind == GenericDeclKind.GENERIC_NOBOUND || genericDeclKind == GenericDeclKind.GENERIC_BOUND ) {
|
if ( genericDeclKind == GenericDeclKind.GENERIC_NOBOUND ||
|
||||||
if ( parameterType == TypeKind.GENERIC && parameterKind == ParameterKind.IMPLICIT) //cyclic inference
|
genericDeclKind == GenericDeclKind.GENERIC_BOUND ) {
|
||||||
|
if ( parameterType == TypeKind.GENERIC &&
|
||||||
|
parameterKind == ParameterKind.IMPLICIT) //cyclic inference
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -216,7 +238,8 @@ public class TypeInferenceComboTest {
|
|||||||
"}\n";
|
"}\n";
|
||||||
SourceFile samSourceFile = new SourceFile("Sam.java", templateStr) {
|
SourceFile samSourceFile = new SourceFile("Sam.java", templateStr) {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return template.replaceAll("#C", samKind.getSam(parameterType, returnType));
|
return template.replaceAll("#C",
|
||||||
|
samKind.getSam(parameterType, returnType));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -225,22 +248,35 @@ public class TypeInferenceComboTest {
|
|||||||
" #Context\n" +
|
" #Context\n" +
|
||||||
"}") {
|
"}") {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return template.replaceAll("#Context", context.getContext(samKind, samTargetType, keyword, parameterType, returnType, lambdaKind, parameterKind, genericDeclKind, lambdaBodyType));
|
return template.replaceAll("#Context",
|
||||||
|
context.getContext(samKind, samTargetType, keyword,
|
||||||
|
parameterType, returnType, lambdaKind, parameterKind,
|
||||||
|
genericDeclKind, lambdaBodyType));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void test() throws Exception {
|
public void run() {
|
||||||
System.out.println("kk:");
|
outWriter.println("kk:");
|
||||||
StringBuilder sb = new StringBuilder("SamKind:");
|
StringBuilder sb = new StringBuilder("SamKind:");
|
||||||
sb.append(samKind).append(" SamTargetType:").append(samTargetType).append(" ParameterType:").append(parameterType)
|
sb.append(samKind).append(" SamTargetType:")
|
||||||
.append(" ReturnType:").append(returnType).append(" Context:").append(context).append(" LambdaKind:").append(lambdaKind)
|
.append(samTargetType).append(" ParameterType:").append(parameterType)
|
||||||
.append(" LambdaBodyType:").append(lambdaBodyType).append(" ParameterKind:").append(parameterKind).append(" Keyword:").append(keyword);
|
.append(" ReturnType:").append(returnType).append(" Context:")
|
||||||
System.out.println(sb);
|
.append(context).append(" LambdaKind:").append(lambdaKind)
|
||||||
|
.append(" LambdaBodyType:").append(lambdaBodyType)
|
||||||
|
.append(" ParameterKind:").append(parameterKind).append(" Keyword:")
|
||||||
|
.append(keyword);
|
||||||
|
outWriter.println(sb);
|
||||||
DiagnosticChecker dc = new DiagnosticChecker();
|
DiagnosticChecker dc = new DiagnosticChecker();
|
||||||
JavacTask ct = (JavacTask)comp.getTask(null, fm, dc, null, null, Arrays.asList(samSourceFile, clientSourceFile));
|
JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), dc,
|
||||||
ct.analyze();
|
null, null, Arrays.asList(samSourceFile, clientSourceFile));
|
||||||
|
try {
|
||||||
|
ct.analyze();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
processException(t);
|
||||||
|
}
|
||||||
if (dc.errorFound == checkTypeInference()) {
|
if (dc.errorFound == checkTypeInference()) {
|
||||||
throw new AssertionError(samSourceFile + "\n\n" + clientSourceFile + "\n" + parameterType + " " + returnType);
|
throw new AssertionError(samSourceFile + "\n\n" +
|
||||||
|
clientSourceFile + "\n" + parameterType + " " + returnType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +297,8 @@ public class TypeInferenceComboTest {
|
|||||||
public abstract String toString();
|
public abstract String toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class DiagnosticChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
boolean errorFound = false;
|
boolean errorFound = false;
|
||||||
|
|
||||||
@ -283,10 +320,9 @@ public class TypeInferenceComboTest {
|
|||||||
Keyword keyword;
|
Keyword keyword;
|
||||||
GenericDeclKind genericDeclKind;
|
GenericDeclKind genericDeclKind;
|
||||||
|
|
||||||
static JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
TypeInferenceComboTest(SamKind sk, TypeKind samTargetT, TypeKind parameterT,
|
||||||
static StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
TypeKind returnT, LambdaBody lb, Context c, LambdaKind lk,
|
||||||
|
ParameterKind pk, Keyword kw, GenericDeclKind gdk) {
|
||||||
TypeInferenceComboTest(SamKind sk, TypeKind samTargetT, TypeKind parameterT, TypeKind returnT, LambdaBody lb, Context c, LambdaKind lk, ParameterKind pk, Keyword kw, GenericDeclKind gdk) {
|
|
||||||
samKind = sk;
|
samKind = sk;
|
||||||
samTargetType = samTargetT;
|
samTargetType = samTargetT;
|
||||||
parameterType = parameterT;
|
parameterType = parameterT;
|
||||||
@ -308,24 +344,14 @@ public class TypeInferenceComboTest {
|
|||||||
for(LambdaKind lambdaK : LambdaKind.values()) {
|
for(LambdaKind lambdaK : LambdaKind.values()) {
|
||||||
for (SamKind sk : SamKind.values()) {
|
for (SamKind sk : SamKind.values()) {
|
||||||
if (sk == SamKind.NON_GENERIC) {
|
if (sk == SamKind.NON_GENERIC) {
|
||||||
if(parameterT != TypeKind.GENERIC && returnT != TypeKind.GENERIC )
|
generateNonGenericSAM(ct, returnT,
|
||||||
new TypeInferenceComboTest(sk, null, parameterT, returnT, lb, ct, lambdaK, parameterK, null, null).test();
|
parameterT, lb, parameterK,
|
||||||
|
lambdaK, sk);
|
||||||
}
|
}
|
||||||
else if (sk == SamKind.GENERIC) {
|
else if (sk == SamKind.GENERIC) {
|
||||||
for (Keyword kw : Keyword.values()) {
|
generateGenericSAM(ct, returnT,
|
||||||
for (TypeKind samTargetT : TypeKind.values()) {
|
parameterT, lb, parameterK,
|
||||||
if(samTargetT != TypeKind.VOID && samTargetT != TypeKind.INT && samTargetT != TypeKind.GENERIC
|
lambdaK, sk);
|
||||||
&& (parameterT == TypeKind.GENERIC || returnT == TypeKind.GENERIC)) {
|
|
||||||
if(ct != Context.METHOD_CALL) {
|
|
||||||
new TypeInferenceComboTest(sk, samTargetT, parameterT, returnT, lb, ct, lambdaK, parameterK, kw, null).test();
|
|
||||||
}
|
|
||||||
else {//Context.METHOD_CALL
|
|
||||||
for (GenericDeclKind gdk : GenericDeclKind.values())
|
|
||||||
new TypeInferenceComboTest(sk, samTargetT, parameterT, returnT, lb, ct, lambdaK, parameterK, kw, gdk).test();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,5 +360,44 @@ public class TypeInferenceComboTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkAfterExec(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void generateNonGenericSAM(Context ct, TypeKind returnT,
|
||||||
|
TypeKind parameterT, LambdaBody lb, ParameterKind parameterK,
|
||||||
|
LambdaKind lambdaK, SamKind sk) {
|
||||||
|
if(parameterT != TypeKind.GENERIC && returnT != TypeKind.GENERIC ) {
|
||||||
|
pool.execute(new TypeInferenceComboTest(sk, null, parameterT,
|
||||||
|
returnT, lb, ct, lambdaK, parameterK, null, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void generateGenericSAM(Context ct, TypeKind returnT,
|
||||||
|
TypeKind parameterT, LambdaBody lb, ParameterKind parameterK,
|
||||||
|
LambdaKind lambdaK, SamKind sk) {
|
||||||
|
for (Keyword kw : Keyword.values()) {
|
||||||
|
for (TypeKind samTargetT : TypeKind.values()) {
|
||||||
|
if(samTargetT != TypeKind.VOID &&
|
||||||
|
samTargetT != TypeKind.INT &&
|
||||||
|
samTargetT != TypeKind.GENERIC &&
|
||||||
|
(parameterT == TypeKind.GENERIC ||
|
||||||
|
returnT == TypeKind.GENERIC)) {
|
||||||
|
if(ct != Context.METHOD_CALL) {
|
||||||
|
pool.execute(
|
||||||
|
new TypeInferenceComboTest(sk, samTargetT, parameterT,
|
||||||
|
returnT, lb, ct, lambdaK, parameterK, kw, null));
|
||||||
|
} else {//Context.METHOD_CALL
|
||||||
|
for (GenericDeclKind gdk :
|
||||||
|
GenericDeclKind.values())
|
||||||
|
pool.execute(
|
||||||
|
new TypeInferenceComboTest(sk, samTargetT,
|
||||||
|
parameterT, returnT, lb, ct, lambdaK,
|
||||||
|
parameterK, kw, gdk));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2013, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.StandardJavaFileManager;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract superclass for threaded tests.
|
||||||
|
*
|
||||||
|
* This class will try to read a property named test.concurrency.
|
||||||
|
* The property can be provided by passing this option to jtreg:
|
||||||
|
* -javaoption:-Dtest.concurrency=#
|
||||||
|
*
|
||||||
|
* If the property is not set the class will use a heuristic to determine the
|
||||||
|
* maximum number of threads that can be fired to execute a given test.
|
||||||
|
*/
|
||||||
|
public abstract class JavacTestingAbstractThreadedTest {
|
||||||
|
|
||||||
|
protected static int getThreadPoolSize() {
|
||||||
|
Integer testConc = Integer.getInteger("test.concurrency");
|
||||||
|
if (testConc != null) return testConc;
|
||||||
|
int cores = Runtime.getRuntime().availableProcessors();
|
||||||
|
return Math.max(2, Math.min(8, cores / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void checkAfterExec() throws InterruptedException {
|
||||||
|
checkAfterExec(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
protected static boolean throwAssertionOnError = true;
|
||||||
|
|
||||||
|
protected static boolean printAll = false;
|
||||||
|
|
||||||
|
protected static StringWriter errSWriter = new StringWriter();
|
||||||
|
protected static PrintWriter errWriter = new PrintWriter(errSWriter);
|
||||||
|
|
||||||
|
protected static StringWriter outSWriter = new StringWriter();
|
||||||
|
protected static PrintWriter outWriter = new PrintWriter(outSWriter);
|
||||||
|
|
||||||
|
protected static void checkAfterExec(boolean printCheckCount)
|
||||||
|
throws InterruptedException {
|
||||||
|
pool.shutdown();
|
||||||
|
while (!pool.isTerminated()) {
|
||||||
|
Thread.sleep(10);
|
||||||
|
}
|
||||||
|
if (errCount.get() > 0) {
|
||||||
|
if (throwAssertionOnError) {
|
||||||
|
closePrinters();
|
||||||
|
System.err.println(errSWriter.toString());
|
||||||
|
throw new AssertionError(
|
||||||
|
String.format("%d errors found", errCount.get()));
|
||||||
|
} else {
|
||||||
|
System.err.println(
|
||||||
|
String.format("%d errors found", errCount.get()));
|
||||||
|
}
|
||||||
|
} else if (printCheckCount) {
|
||||||
|
outWriter.println("Total check executed: " + checkCount.get());
|
||||||
|
}
|
||||||
|
closePrinters();
|
||||||
|
if (printAll) {
|
||||||
|
System.out.println(errSWriter.toString());
|
||||||
|
System.out.println(outSWriter.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void closePrinters() {
|
||||||
|
errWriter.close();
|
||||||
|
outWriter.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void processException(Throwable t) {
|
||||||
|
errCount.incrementAndGet();
|
||||||
|
t.printStackTrace(errWriter);
|
||||||
|
pool.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
//number of checks executed
|
||||||
|
protected static AtomicInteger checkCount = new AtomicInteger();
|
||||||
|
|
||||||
|
//number of errors found while running combo tests
|
||||||
|
protected static AtomicInteger errCount = new AtomicInteger();
|
||||||
|
|
||||||
|
//create default shared JavaCompiler - reused across multiple compilations
|
||||||
|
protected static JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
||||||
|
|
||||||
|
protected static ExecutorService pool = Executors.newFixedThreadPool(
|
||||||
|
getThreadPoolSize(), new ThreadFactory() {
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
Thread t = new Thread(r);
|
||||||
|
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||||
|
@Override
|
||||||
|
public void uncaughtException(Thread t, Throwable e) {
|
||||||
|
pool.shutdown();
|
||||||
|
errCount.incrementAndGet();
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File manager is not thread-safe so it cannot be re-used across multiple
|
||||||
|
* threads. However we cache per-thread FileManager to avoid excessive
|
||||||
|
* object creation
|
||||||
|
*/
|
||||||
|
protected static final ThreadLocal<StandardJavaFileManager> fm =
|
||||||
|
new ThreadLocal<StandardJavaFileManager>() {
|
||||||
|
@Override protected StandardJavaFileManager initialValue() {
|
||||||
|
return comp.getStandardFileManager(null, null, null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,19 +25,21 @@
|
|||||||
* @test
|
* @test
|
||||||
* @bug 7030606
|
* @bug 7030606
|
||||||
* @summary Project-coin: multi-catch types should be pairwise disjoint
|
* @summary Project-coin: multi-catch types should be pairwise disjoint
|
||||||
|
* @library ../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main DisjunctiveTypeWellFormednessTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
import com.sun.source.util.JavacTask;
|
||||||
import javax.tools.ToolProvider;
|
|
||||||
|
|
||||||
public class DisjunctiveTypeWellFormednessTest {
|
public class DisjunctiveTypeWellFormednessTest
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
|
implements Runnable {
|
||||||
|
|
||||||
enum Alternative {
|
enum Alternative {
|
||||||
EXCEPTION("Exception"),
|
EXCEPTION("Exception"),
|
||||||
@ -92,40 +94,37 @@ public class DisjunctiveTypeWellFormednessTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
|
|
||||||
//create default shared JavaCompiler - reused across multiple compilations
|
|
||||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
|
||||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
for (Arity arity : Arity.values()) {
|
for (Arity arity : Arity.values()) {
|
||||||
for (Alternative a1 : Alternative.values()) {
|
for (Alternative a1 : Alternative.values()) {
|
||||||
if (arity == Arity.ONE) {
|
if (arity == Arity.ONE) {
|
||||||
new DisjunctiveTypeWellFormednessTest(a1).run(comp, fm);
|
pool.execute(new DisjunctiveTypeWellFormednessTest(a1));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (Alternative a2 : Alternative.values()) {
|
for (Alternative a2 : Alternative.values()) {
|
||||||
if (arity == Arity.TWO) {
|
if (arity == Arity.TWO) {
|
||||||
new DisjunctiveTypeWellFormednessTest(a1, a2).run(comp, fm);
|
pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (Alternative a3 : Alternative.values()) {
|
for (Alternative a3 : Alternative.values()) {
|
||||||
if (arity == Arity.THREE) {
|
if (arity == Arity.THREE) {
|
||||||
new DisjunctiveTypeWellFormednessTest(a1, a2, a3).run(comp, fm);
|
pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2, a3));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (Alternative a4 : Alternative.values()) {
|
for (Alternative a4 : Alternative.values()) {
|
||||||
if (arity == Arity.FOUR) {
|
if (arity == Arity.FOUR) {
|
||||||
new DisjunctiveTypeWellFormednessTest(a1, a2, a3, a4).run(comp, fm);
|
pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2, a3, a4));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (Alternative a5 : Alternative.values()) {
|
for (Alternative a5 : Alternative.values()) {
|
||||||
new DisjunctiveTypeWellFormednessTest(a1, a2, a3, a4, a5).run(comp, fm);
|
pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2, a3, a4, a5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkAfterExec(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Alternative[] alternatives;
|
Alternative[] alternatives;
|
||||||
@ -159,10 +158,16 @@ public class DisjunctiveTypeWellFormednessTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
|
@Override
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
|
public void run() {
|
||||||
|
JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
|
||||||
null, null, Arrays.asList(source));
|
null, null, Arrays.asList(source));
|
||||||
ct.analyze();
|
try {
|
||||||
|
ct.analyze();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
processException(t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,4 +207,5 @@ public class DisjunctiveTypeWellFormednessTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,8 +25,22 @@
|
|||||||
* @test
|
* @test
|
||||||
* @bug 7042566
|
* @bug 7042566
|
||||||
* @summary Unambiguous varargs method calls flagged as ambiguous
|
* @summary Unambiguous varargs method calls flagged as ambiguous
|
||||||
|
* @library ../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
|
* @run main T7042566
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
import javax.tools.SimpleJavaFileObject;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
import com.sun.source.util.JavacTask;
|
||||||
import com.sun.tools.classfile.Instruction;
|
import com.sun.tools.classfile.Instruction;
|
||||||
import com.sun.tools.classfile.Attribute;
|
import com.sun.tools.classfile.Attribute;
|
||||||
@ -34,44 +48,36 @@ import com.sun.tools.classfile.ClassFile;
|
|||||||
import com.sun.tools.classfile.Code_attribute;
|
import com.sun.tools.classfile.Code_attribute;
|
||||||
import com.sun.tools.classfile.ConstantPool.*;
|
import com.sun.tools.classfile.ConstantPool.*;
|
||||||
import com.sun.tools.classfile.Method;
|
import com.sun.tools.classfile.Method;
|
||||||
import com.sun.tools.javac.api.JavacTool;
|
|
||||||
import com.sun.tools.javac.util.List;
|
import com.sun.tools.javac.util.List;
|
||||||
|
|
||||||
import java.io.File;
|
public class T7042566
|
||||||
import java.net.URI;
|
extends JavacTestingAbstractThreadedTest
|
||||||
import java.util.Arrays;
|
implements Runnable {
|
||||||
import java.util.Locale;
|
|
||||||
import javax.tools.Diagnostic;
|
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.JavaFileObject;
|
|
||||||
import javax.tools.SimpleJavaFileObject;
|
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
import javax.tools.ToolProvider;
|
|
||||||
|
|
||||||
public class T7042566 {
|
|
||||||
|
|
||||||
VarargsMethod m1;
|
VarargsMethod m1;
|
||||||
VarargsMethod m2;
|
VarargsMethod m2;
|
||||||
TypeConfiguration actuals;
|
TypeConfiguration actuals;
|
||||||
|
|
||||||
T7042566(TypeConfiguration m1_conf, TypeConfiguration m2_conf, TypeConfiguration actuals) {
|
T7042566(TypeConfiguration m1_conf, TypeConfiguration m2_conf,
|
||||||
|
TypeConfiguration actuals) {
|
||||||
this.m1 = new VarargsMethod(m1_conf);
|
this.m1 = new VarargsMethod(m1_conf);
|
||||||
this.m2 = new VarargsMethod(m2_conf);
|
this.m2 = new VarargsMethod(m2_conf);
|
||||||
this.actuals = actuals;
|
this.actuals = actuals;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compileAndCheck() throws Exception {
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int id = checkCount.incrementAndGet();
|
||||||
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
||||||
JavaSource source = new JavaSource();
|
JavaSource source = new JavaSource(id);
|
||||||
ErrorChecker ec = new ErrorChecker();
|
ErrorChecker ec = new ErrorChecker();
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, ec,
|
JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), ec,
|
||||||
null, null, Arrays.asList(source));
|
null, null, Arrays.asList(source));
|
||||||
ct.call();
|
ct.call();
|
||||||
check(source, ec);
|
check(source, ec, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check(JavaSource source, ErrorChecker ec) {
|
void check(JavaSource source, ErrorChecker ec, int id) {
|
||||||
checkCount++;
|
|
||||||
boolean resolutionError = false;
|
boolean resolutionError = false;
|
||||||
VarargsMethod selectedMethod = null;
|
VarargsMethod selectedMethod = null;
|
||||||
|
|
||||||
@ -99,13 +105,13 @@ public class T7042566 {
|
|||||||
"\nFound error: " + ec.errorFound +
|
"\nFound error: " + ec.errorFound +
|
||||||
"\nCompiler diagnostics:\n" + ec.printDiags());
|
"\nCompiler diagnostics:\n" + ec.printDiags());
|
||||||
} else if (!resolutionError) {
|
} else if (!resolutionError) {
|
||||||
verifyBytecode(selectedMethod, source);
|
verifyBytecode(selectedMethod, source, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void verifyBytecode(VarargsMethod selected, JavaSource source) {
|
void verifyBytecode(VarargsMethod selected, JavaSource source, int id) {
|
||||||
bytecodeCheckCount++;
|
bytecodeCheckCount.incrementAndGet();
|
||||||
File compiledTest = new File("Test.class");
|
File compiledTest = new File(String.format("Test%d.class", id));
|
||||||
try {
|
try {
|
||||||
ClassFile cf = ClassFile.read(compiledTest);
|
ClassFile cf = ClassFile.read(compiledTest);
|
||||||
Method testMethod = null;
|
Method testMethod = null;
|
||||||
@ -118,7 +124,8 @@ public class T7042566 {
|
|||||||
if (testMethod == null) {
|
if (testMethod == null) {
|
||||||
throw new Error("Test method not found");
|
throw new Error("Test method not found");
|
||||||
}
|
}
|
||||||
Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code);
|
Code_attribute ea =
|
||||||
|
(Code_attribute)testMethod.attributes.get(Attribute.Code);
|
||||||
if (testMethod == null) {
|
if (testMethod == null) {
|
||||||
throw new Error("Code attribute for test() method not found");
|
throw new Error("Code attribute for test() method not found");
|
||||||
}
|
}
|
||||||
@ -127,11 +134,12 @@ public class T7042566 {
|
|||||||
if (i.getMnemonic().equals("invokevirtual")) {
|
if (i.getMnemonic().equals("invokevirtual")) {
|
||||||
int cp_entry = i.getUnsignedShort(1);
|
int cp_entry = i.getUnsignedShort(1);
|
||||||
CONSTANT_Methodref_info methRef =
|
CONSTANT_Methodref_info methRef =
|
||||||
(CONSTANT_Methodref_info)cf.constant_pool.get(cp_entry);
|
(CONSTANT_Methodref_info)cf.constant_pool.get(cp_entry);
|
||||||
String type = methRef.getNameAndTypeInfo().getType();
|
String type = methRef.getNameAndTypeInfo().getType();
|
||||||
String sig = selected.parameterTypes.bytecodeSigStr;
|
String sig = selected.parameterTypes.bytecodeSigStr;
|
||||||
if (!type.contains(sig)) {
|
if (!type.contains(sig)) {
|
||||||
throw new Error("Unexpected type method call: " + type + "" +
|
throw new Error("Unexpected type method call: " +
|
||||||
|
type + "" +
|
||||||
"\nfound: " + sig +
|
"\nfound: " + sig +
|
||||||
"\n" + source.getCharContent(true));
|
"\n" + source.getCharContent(true));
|
||||||
}
|
}
|
||||||
@ -146,7 +154,7 @@ public class T7042566 {
|
|||||||
|
|
||||||
class JavaSource extends SimpleJavaFileObject {
|
class JavaSource extends SimpleJavaFileObject {
|
||||||
|
|
||||||
static final String source_template = "class Test {\n" +
|
static final String source_template = "class Test#ID {\n" +
|
||||||
" #V1\n" +
|
" #V1\n" +
|
||||||
" #V2\n" +
|
" #V2\n" +
|
||||||
" void test() { m(#E); }\n" +
|
" void test() { m(#E); }\n" +
|
||||||
@ -154,11 +162,13 @@ public class T7042566 {
|
|||||||
|
|
||||||
String source;
|
String source;
|
||||||
|
|
||||||
public JavaSource() {
|
public JavaSource(int id) {
|
||||||
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
super(URI.create(String.format("myfo:/Test%d.java", id)),
|
||||||
source = source_template.replaceAll("#V1", m1.toString()).
|
JavaFileObject.Kind.SOURCE);
|
||||||
replaceAll("#V2", m2.toString()).
|
source = source_template.replaceAll("#V1", m1.toString())
|
||||||
replaceAll("#E", actuals.expressionListStr);
|
.replaceAll("#V2", m2.toString())
|
||||||
|
.replaceAll("#E", actuals.expressionListStr)
|
||||||
|
.replaceAll("#ID", String.valueOf(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -167,26 +177,17 @@ public class T7042566 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** global decls ***/
|
|
||||||
|
|
||||||
// Create a single file manager and reuse it for each compile to save time.
|
|
||||||
static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
//statistics
|
|
||||||
static int checkCount = 0;
|
|
||||||
static int bytecodeCheckCount = 0;
|
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
for (TypeConfiguration tconf1 : TypeConfiguration.values()) {
|
for (TypeConfiguration tconf1 : TypeConfiguration.values()) {
|
||||||
for (TypeConfiguration tconf2 : TypeConfiguration.values()) {
|
for (TypeConfiguration tconf2 : TypeConfiguration.values()) {
|
||||||
for (TypeConfiguration tconf3 : TypeConfiguration.values()) {
|
for (TypeConfiguration tconf3 : TypeConfiguration.values()) {
|
||||||
new T7042566(tconf1, tconf2, tconf3).compileAndCheck();
|
pool.execute(new T7042566(tconf1, tconf2, tconf3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Total checks made: " + checkCount);
|
outWriter.println("Bytecode checks made: " + bytecodeCheckCount.get());
|
||||||
System.out.println("Bytecode checks made: " + bytecodeCheckCount);
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TypeKind {
|
enum TypeKind {
|
||||||
@ -326,14 +327,16 @@ public class T7042566 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ErrorChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class ErrorChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
boolean errorFound;
|
boolean errorFound;
|
||||||
List<String> errDiags = List.nil();
|
List<String> errDiags = List.nil();
|
||||||
|
|
||||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
||||||
errDiags = errDiags.append(diagnostic.getMessage(Locale.getDefault()));
|
errDiags = errDiags
|
||||||
|
.append(diagnostic.getMessage(Locale.getDefault()));
|
||||||
errorFound = true;
|
errorFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -347,4 +350,8 @@ public class T7042566 {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//number of bytecode checks made while running combo tests
|
||||||
|
static AtomicInteger bytecodeCheckCount = new AtomicInteger();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,10 +26,11 @@
|
|||||||
* @bug 6945418 6993978
|
* @bug 6945418 6993978
|
||||||
* @summary Project Coin: Simplified Varargs Method Invocation
|
* @summary Project Coin: Simplified Varargs Method Invocation
|
||||||
* @author mcimadamore
|
* @author mcimadamore
|
||||||
|
* @library ../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
* @run main Warn4
|
* @run main Warn4
|
||||||
*/
|
*/
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import com.sun.tools.javac.api.JavacTool;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -38,16 +39,19 @@ import javax.tools.Diagnostic;
|
|||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
import javax.tools.ToolProvider;
|
import javax.tools.ToolProvider;
|
||||||
|
import com.sun.source.util.JavacTask;
|
||||||
|
|
||||||
public class Warn4 {
|
public class Warn4
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
|
implements Runnable {
|
||||||
|
|
||||||
final static Warning[] error = null;
|
final static Warning[] error = null;
|
||||||
final static Warning[] none = new Warning[] {};
|
final static Warning[] none = new Warning[] {};
|
||||||
final static Warning[] vararg = new Warning[] { Warning.VARARGS };
|
final static Warning[] vararg = new Warning[] { Warning.VARARGS };
|
||||||
final static Warning[] unchecked = new Warning[] { Warning.UNCHECKED };
|
final static Warning[] unchecked = new Warning[] { Warning.UNCHECKED };
|
||||||
final static Warning[] both = new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
|
final static Warning[] both =
|
||||||
|
new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
|
||||||
|
|
||||||
enum Warning {
|
enum Warning {
|
||||||
UNCHECKED("generic.array.creation"),
|
UNCHECKED("generic.array.creation"),
|
||||||
@ -59,8 +63,10 @@ public class Warn4 {
|
|||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isSuppressed(TrustMe trustMe, SourceLevel source, SuppressLevel suppressLevelClient,
|
boolean isSuppressed(TrustMe trustMe, SourceLevel source,
|
||||||
SuppressLevel suppressLevelDecl, ModifierKind modKind) {
|
SuppressLevel suppressLevelClient,
|
||||||
|
SuppressLevel suppressLevelDecl,
|
||||||
|
ModifierKind modKind) {
|
||||||
switch(this) {
|
switch(this) {
|
||||||
case VARARGS:
|
case VARARGS:
|
||||||
return source == SourceLevel.JDK_6 ||
|
return source == SourceLevel.JDK_6 ||
|
||||||
@ -68,7 +74,8 @@ public class Warn4 {
|
|||||||
trustMe == TrustMe.TRUST;
|
trustMe == TrustMe.TRUST;
|
||||||
case UNCHECKED:
|
case UNCHECKED:
|
||||||
return suppressLevelClient == SuppressLevel.UNCHECKED ||
|
return suppressLevelClient == SuppressLevel.UNCHECKED ||
|
||||||
(trustMe == TrustMe.TRUST && modKind != ModifierKind.NONE && source == SourceLevel.JDK_7);
|
(trustMe == TrustMe.TRUST && modKind !=
|
||||||
|
ModifierKind.NONE && source == SourceLevel.JDK_7);
|
||||||
}
|
}
|
||||||
|
|
||||||
SuppressLevel supLev = this == VARARGS ?
|
SuppressLevel supLev = this == VARARGS ?
|
||||||
@ -172,13 +179,13 @@ public class Warn4 {
|
|||||||
for (Signature vararg_meth : Signature.values()) {
|
for (Signature vararg_meth : Signature.values()) {
|
||||||
for (Signature client_meth : Signature.values()) {
|
for (Signature client_meth : Signature.values()) {
|
||||||
if (vararg_meth.isApplicableTo(client_meth)) {
|
if (vararg_meth.isApplicableTo(client_meth)) {
|
||||||
test(sourceLevel,
|
pool.execute(new Warn4(sourceLevel,
|
||||||
trustMe,
|
trustMe,
|
||||||
suppressLevelClient,
|
suppressLevelClient,
|
||||||
suppressLevelDecl,
|
suppressLevelDecl,
|
||||||
modKind,
|
modKind,
|
||||||
vararg_meth,
|
vararg_meth,
|
||||||
client_meth);
|
client_meth));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,63 +194,82 @@ public class Warn4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkAfterExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a single file manager and reuse it for each compile to save time.
|
SourceLevel sourceLevel;
|
||||||
static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
|
TrustMe trustMe;
|
||||||
|
SuppressLevel suppressLevelClient;
|
||||||
|
SuppressLevel suppressLevelDecl;
|
||||||
|
ModifierKind modKind;
|
||||||
|
Signature vararg_meth;
|
||||||
|
Signature client_meth;
|
||||||
|
DiagnosticChecker diagChecker;
|
||||||
|
|
||||||
static void test(SourceLevel sourceLevel, TrustMe trustMe, SuppressLevel suppressLevelClient,
|
public Warn4(SourceLevel sourceLevel, TrustMe trustMe,
|
||||||
SuppressLevel suppressLevelDecl, ModifierKind modKind, Signature vararg_meth, Signature client_meth) throws Exception {
|
SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl,
|
||||||
|
ModifierKind modKind, Signature vararg_meth, Signature client_meth) {
|
||||||
|
this.sourceLevel = sourceLevel;
|
||||||
|
this.trustMe = trustMe;
|
||||||
|
this.suppressLevelClient = suppressLevelClient;
|
||||||
|
this.suppressLevelDecl = suppressLevelDecl;
|
||||||
|
this.modKind = modKind;
|
||||||
|
this.vararg_meth = vararg_meth;
|
||||||
|
this.client_meth = client_meth;
|
||||||
|
this.diagChecker = new DiagnosticChecker();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int id = checkCount.incrementAndGet();
|
||||||
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
||||||
JavaSource source = new JavaSource(trustMe, suppressLevelClient, suppressLevelDecl, modKind, vararg_meth, client_meth);
|
JavaSource source = new JavaSource(id);
|
||||||
DiagnosticChecker dc = new DiagnosticChecker();
|
JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), diagChecker,
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, dc,
|
|
||||||
Arrays.asList("-Xlint:unchecked", "-source", sourceLevel.sourceKey),
|
Arrays.asList("-Xlint:unchecked", "-source", sourceLevel.sourceKey),
|
||||||
null, Arrays.asList(source));
|
null, Arrays.asList(source));
|
||||||
ct.generate(); //to get mandatory notes
|
ct.call(); //to get mandatory notes
|
||||||
check(dc.warnings, sourceLevel,
|
check(source, new boolean[] {vararg_meth.giveUnchecked(client_meth),
|
||||||
new boolean[] {vararg_meth.giveUnchecked(client_meth),
|
vararg_meth.giveVarargs(client_meth)});
|
||||||
vararg_meth.giveVarargs(client_meth)},
|
|
||||||
source, trustMe, suppressLevelClient, suppressLevelDecl, modKind);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check(Set<Warning> warnings, SourceLevel sourceLevel, boolean[] warnArr, JavaSource source,
|
void check(JavaSource source, boolean[] warnArr) {
|
||||||
TrustMe trustMe, SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl, ModifierKind modKind) {
|
|
||||||
boolean badOutput = false;
|
boolean badOutput = false;
|
||||||
for (Warning wkind : Warning.values()) {
|
for (Warning wkind : Warning.values()) {
|
||||||
boolean isSuppressed = wkind.isSuppressed(trustMe, sourceLevel,
|
boolean isSuppressed = wkind.isSuppressed(trustMe, sourceLevel,
|
||||||
suppressLevelClient, suppressLevelDecl, modKind);
|
suppressLevelClient, suppressLevelDecl, modKind);
|
||||||
System.out.println("SUPPRESSED = " + isSuppressed);
|
System.out.println("SUPPRESSED = " + isSuppressed);
|
||||||
badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) != warnings.contains(wkind);
|
badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) !=
|
||||||
|
diagChecker.warnings.contains(wkind);
|
||||||
}
|
}
|
||||||
if (badOutput) {
|
if (badOutput) {
|
||||||
throw new Error("invalid diagnostics for source:\n" +
|
throw new Error("invalid diagnostics for source:\n" +
|
||||||
source.getCharContent(true) +
|
source.getCharContent(true) +
|
||||||
"\nExpected unchecked warning: " + warnArr[0] +
|
"\nExpected unchecked warning: " + warnArr[0] +
|
||||||
"\nExpected unsafe vararg warning: " + warnArr[1] +
|
"\nExpected unsafe vararg warning: " + warnArr[1] +
|
||||||
"\nWarnings: " + warnings +
|
"\nWarnings: " + diagChecker.warnings +
|
||||||
"\nSource level: " + sourceLevel);
|
"\nSource level: " + sourceLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class JavaSource extends SimpleJavaFileObject {
|
class JavaSource extends SimpleJavaFileObject {
|
||||||
|
|
||||||
String source;
|
String source;
|
||||||
|
|
||||||
public JavaSource(TrustMe trustMe, SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl,
|
public JavaSource(int id) {
|
||||||
ModifierKind modKind, Signature vararg_meth, Signature client_meth) {
|
super(URI.create(String.format("myfo:/Test%d.java", id)),
|
||||||
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
JavaFileObject.Kind.SOURCE);
|
||||||
String meth1 = vararg_meth.template.replace("#arity", "...");
|
String meth1 = vararg_meth.template.replace("#arity", "...");
|
||||||
meth1 = meth1.replace("#name", "m");
|
meth1 = meth1.replace("#name", "m");
|
||||||
meth1 = meth1.replace("#body", "");
|
meth1 = meth1.replace("#body", "");
|
||||||
meth1 = trustMe.anno + "\n" + suppressLevelDecl.getSuppressAnno() + modKind.mod + meth1;
|
meth1 = trustMe.anno + "\n" + suppressLevelDecl.getSuppressAnno() +
|
||||||
|
modKind.mod + meth1;
|
||||||
String meth2 = client_meth.template.replace("#arity", "");
|
String meth2 = client_meth.template.replace("#arity", "");
|
||||||
meth2 = meth2.replace("#name", "test");
|
meth2 = meth2.replace("#name", "test");
|
||||||
meth2 = meth2.replace("#body", "m(arg);");
|
meth2 = meth2.replace("#body", "m(arg);");
|
||||||
meth2 = suppressLevelClient.getSuppressAnno() + meth2;
|
meth2 = suppressLevelClient.getSuppressAnno() + meth2;
|
||||||
source = "import java.util.List;\n" +
|
source = String.format("import java.util.List;\n" +
|
||||||
"class Test {\n" + meth1 +
|
"class Test%s {\n %s \n %s \n } \n", id, meth1, meth2);
|
||||||
"\n" + meth2 + "\n}\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -252,7 +278,8 @@ public class Warn4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
static class DiagnosticChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
Set<Warning> warnings = new HashSet<>();
|
Set<Warning> warnings = new HashSet<>();
|
||||||
|
|
||||||
@ -267,4 +294,5 @@ public class Warn4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,10 +26,10 @@
|
|||||||
* @bug 6993978 7097436
|
* @bug 6993978 7097436
|
||||||
* @summary Project Coin: Annotation to reduce varargs warnings
|
* @summary Project Coin: Annotation to reduce varargs warnings
|
||||||
* @author mcimadamore
|
* @author mcimadamore
|
||||||
|
* @library ../../lib
|
||||||
|
* @build JavacTestingAbstractThreadedTest
|
||||||
* @run main Warn5
|
* @run main Warn5
|
||||||
*/
|
*/
|
||||||
import com.sun.source.util.JavacTask;
|
|
||||||
import com.sun.tools.javac.api.JavacTool;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
@ -37,10 +37,12 @@ import javax.tools.Diagnostic;
|
|||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
import javax.tools.ToolProvider;
|
import javax.tools.ToolProvider;
|
||||||
|
import com.sun.source.util.JavacTask;
|
||||||
|
|
||||||
public class Warn5 {
|
public class Warn5
|
||||||
|
extends JavacTestingAbstractThreadedTest
|
||||||
|
implements Runnable {
|
||||||
|
|
||||||
enum XlintOption {
|
enum XlintOption {
|
||||||
NONE("none"),
|
NONE("none"),
|
||||||
@ -161,9 +163,6 @@ public class Warn5 {
|
|||||||
REDUNDANT_SAFEVARARGS;
|
REDUNDANT_SAFEVARARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a single file manager and reuse it for each compile to save time.
|
|
||||||
static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
for (SourceLevel sourceLevel : SourceLevel.values()) {
|
for (SourceLevel sourceLevel : SourceLevel.values()) {
|
||||||
for (XlintOption xlint : XlintOption.values()) {
|
for (XlintOption xlint : XlintOption.values()) {
|
||||||
@ -173,14 +172,9 @@ public class Warn5 {
|
|||||||
for (MethodKind methKind : MethodKind.values()) {
|
for (MethodKind methKind : MethodKind.values()) {
|
||||||
for (SignatureKind sig : SignatureKind.values()) {
|
for (SignatureKind sig : SignatureKind.values()) {
|
||||||
for (BodyKind body : BodyKind.values()) {
|
for (BodyKind body : BodyKind.values()) {
|
||||||
new Warn5(sourceLevel,
|
pool.execute(new Warn5(sourceLevel,
|
||||||
xlint,
|
xlint, trustMe, suppressLevel,
|
||||||
trustMe,
|
modKind, methKind, sig, body));
|
||||||
suppressLevel,
|
|
||||||
modKind,
|
|
||||||
methKind,
|
|
||||||
sig,
|
|
||||||
body).test();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,6 +183,8 @@ public class Warn5 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkAfterExec(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final SourceLevel sourceLevel;
|
final SourceLevel sourceLevel;
|
||||||
@ -202,7 +198,9 @@ public class Warn5 {
|
|||||||
final JavaSource source;
|
final JavaSource source;
|
||||||
final DiagnosticChecker dc;
|
final DiagnosticChecker dc;
|
||||||
|
|
||||||
public Warn5(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind, MethodKind methKind, SignatureKind sig, BodyKind body) {
|
public Warn5(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe,
|
||||||
|
SuppressLevel suppressLevel, ModifierKind modKind,
|
||||||
|
MethodKind methKind, SignatureKind sig, BodyKind body) {
|
||||||
this.sourceLevel = sourceLevel;
|
this.sourceLevel = sourceLevel;
|
||||||
this.xlint = xlint;
|
this.xlint = xlint;
|
||||||
this.trustMe = trustMe;
|
this.trustMe = trustMe;
|
||||||
@ -215,24 +213,36 @@ public class Warn5 {
|
|||||||
this.dc = new DiagnosticChecker();
|
this.dc = new DiagnosticChecker();
|
||||||
}
|
}
|
||||||
|
|
||||||
void test() throws Exception {
|
@Override
|
||||||
|
public void run() {
|
||||||
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
||||||
JavacTask ct = (JavacTask)tool.getTask(null, fm, dc,
|
JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), dc,
|
||||||
Arrays.asList(xlint.getXlintOption(), "-source", sourceLevel.sourceKey), null, Arrays.asList(source));
|
Arrays.asList(xlint.getXlintOption(),
|
||||||
ct.analyze();
|
"-source", sourceLevel.sourceKey),
|
||||||
|
null, Arrays.asList(source));
|
||||||
|
try {
|
||||||
|
ct.analyze();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
processException(t);
|
||||||
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void check() {
|
void check() {
|
||||||
|
|
||||||
EnumSet<WarningKind> expectedWarnings = EnumSet.noneOf(WarningKind.class);
|
EnumSet<WarningKind> expectedWarnings =
|
||||||
|
EnumSet.noneOf(WarningKind.class);
|
||||||
|
|
||||||
if (sourceLevel == SourceLevel.JDK_7 &&
|
if (sourceLevel == SourceLevel.JDK_7 &&
|
||||||
trustMe == TrustMe.TRUST &&
|
trustMe == TrustMe.TRUST &&
|
||||||
suppressLevel != SuppressLevel.VARARGS &&
|
suppressLevel != SuppressLevel.VARARGS &&
|
||||||
xlint != XlintOption.NONE &&
|
xlint != XlintOption.NONE &&
|
||||||
sig.isVarargs && !sig.isReifiableArg && body.hasAliasing &&
|
sig.isVarargs &&
|
||||||
(methKind == MethodKind.CONSTRUCTOR || (methKind == MethodKind.METHOD && modKind != ModifierKind.NONE))) {
|
!sig.isReifiableArg &&
|
||||||
|
body.hasAliasing &&
|
||||||
|
(methKind == MethodKind.CONSTRUCTOR ||
|
||||||
|
(methKind == MethodKind.METHOD &&
|
||||||
|
modKind != ModifierKind.NONE))) {
|
||||||
expectedWarnings.add(WarningKind.UNSAFE_BODY);
|
expectedWarnings.add(WarningKind.UNSAFE_BODY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +257,8 @@ public class Warn5 {
|
|||||||
if (sourceLevel == SourceLevel.JDK_7 &&
|
if (sourceLevel == SourceLevel.JDK_7 &&
|
||||||
trustMe == TrustMe.TRUST &&
|
trustMe == TrustMe.TRUST &&
|
||||||
(!sig.isVarargs ||
|
(!sig.isVarargs ||
|
||||||
(modKind == ModifierKind.NONE && methKind == MethodKind.METHOD))) {
|
(modKind == ModifierKind.NONE &&
|
||||||
|
methKind == MethodKind.METHOD))) {
|
||||||
expectedWarnings.add(WarningKind.MALFORMED_SAFEVARARGS);
|
expectedWarnings.add(WarningKind.MALFORMED_SAFEVARARGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,7 +266,8 @@ public class Warn5 {
|
|||||||
trustMe == TrustMe.TRUST &&
|
trustMe == TrustMe.TRUST &&
|
||||||
xlint != XlintOption.NONE &&
|
xlint != XlintOption.NONE &&
|
||||||
suppressLevel != SuppressLevel.VARARGS &&
|
suppressLevel != SuppressLevel.VARARGS &&
|
||||||
(modKind != ModifierKind.NONE || methKind == MethodKind.CONSTRUCTOR) &&
|
(modKind != ModifierKind.NONE ||
|
||||||
|
methKind == MethodKind.CONSTRUCTOR) &&
|
||||||
sig.isVarargs &&
|
sig.isVarargs &&
|
||||||
sig.isReifiableArg) {
|
sig.isReifiableArg) {
|
||||||
expectedWarnings.add(WarningKind.REDUNDANT_SAFEVARARGS);
|
expectedWarnings.add(WarningKind.REDUNDANT_SAFEVARARGS);
|
||||||
@ -297,19 +309,23 @@ public class Warn5 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
class DiagnosticChecker
|
||||||
|
implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
EnumSet<WarningKind> warnings = EnumSet.noneOf(WarningKind.class);
|
EnumSet<WarningKind> warnings = EnumSet.noneOf(WarningKind.class);
|
||||||
|
|
||||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
if (diagnostic.getKind() == Diagnostic.Kind.WARNING) {
|
if (diagnostic.getKind() == Diagnostic.Kind.WARNING) {
|
||||||
if (diagnostic.getCode().contains("unsafe.use.varargs.param")) {
|
if (diagnostic.getCode().
|
||||||
|
contains("unsafe.use.varargs.param")) {
|
||||||
setWarning(WarningKind.UNSAFE_BODY);
|
setWarning(WarningKind.UNSAFE_BODY);
|
||||||
} else if (diagnostic.getCode().contains("redundant.trustme")) {
|
} else if (diagnostic.getCode().
|
||||||
|
contains("redundant.trustme")) {
|
||||||
setWarning(WarningKind.REDUNDANT_SAFEVARARGS);
|
setWarning(WarningKind.REDUNDANT_SAFEVARARGS);
|
||||||
}
|
}
|
||||||
} else if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING &&
|
} else if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING &&
|
||||||
diagnostic.getCode().contains("varargs.non.reifiable.type")) {
|
diagnostic.getCode().
|
||||||
|
contains("varargs.non.reifiable.type")) {
|
||||||
setWarning(WarningKind.UNSAFE_DECL);
|
setWarning(WarningKind.UNSAFE_DECL);
|
||||||
} else if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
|
} else if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
|
||||||
diagnostic.getCode().contains("invalid.trustme")) {
|
diagnostic.getCode().contains("invalid.trustme")) {
|
||||||
@ -319,7 +335,8 @@ public class Warn5 {
|
|||||||
|
|
||||||
void setWarning(WarningKind wk) {
|
void setWarning(WarningKind wk) {
|
||||||
if (!warnings.add(wk)) {
|
if (!warnings.add(wk)) {
|
||||||
throw new AssertionError("Duplicate warning of kind " + wk + " in source:\n" + source);
|
throw new AssertionError("Duplicate warning of kind " +
|
||||||
|
wk + " in source:\n" + source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,4 +344,5 @@ public class Warn5 {
|
|||||||
return warnings.contains(wk);
|
return warnings.contains(wk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user