diff -r f5b5112ee1cc -r de1c65ecfec2 test/tools/javac/TryWithResources/InterruptedExceptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/TryWithResources/InterruptedExceptionTest.java Tue Mar 29 16:41:18 2011 +0100 @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7027157 + * @summary Project Coin: javac warnings for AutoCloseable.close throwing InterruptedException + */ + +import com.sun.source.util.JavacTask; +import java.net.URI; +import java.util.Arrays; +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 InterruptedExceptionTest { + + enum XlintOption { + NONE("none"), + TRY("try"); + + String opt; + + XlintOption(String opt) { + this.opt = opt; + } + + String getXlintOption() { + return "-Xlint:" + opt; + } + } + + enum SuppressLevel { + NONE, + SUPPRESS; + + String getSuppressAnno() { + return this == SUPPRESS ? + "@SuppressWarnings(\"try\")" : + ""; + } + } + + enum ClassKind { + ABSTRACT_CLASS("abstract class", "implements", false), + CLASS("class", "implements", true), + INTERFACE("interface", "extends", false); + + String kindName; + String extendsClause; + boolean hasBody; + + private ClassKind(String kindName, String extendsClause, boolean hasBody) { + this.kindName = kindName; + this.extendsClause = extendsClause; + this.hasBody = hasBody; + } + + String getBody() { + return hasBody ? "{}" : ";"; + } + } + + enum ExceptionKind { + NONE("", false), + EXCEPTION("Exception", true), + INTERRUPTED_EXCEPTION("InterruptedException", true), + ILLEGAL_ARGUMENT_EXCEPTION("IllegalArgumentException", false), + X("X", false); + + String exName; + boolean shouldWarn; + + private ExceptionKind(String exName, boolean shouldWarn) { + this.exName = exName; + this.shouldWarn = shouldWarn; + } + + String getThrowsClause() { + return this == NONE ? "" : "throws " + exName; + } + + String getTypeArguments(ExceptionKind decl) { + return (decl != X || this == NONE) ? "" : "<" + exName + ">"; + } + + String getTypeParameter() { + return this == X ? "" : ""; + } + } + + 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 (XlintOption xlint : XlintOption.values()) { + for (SuppressLevel suppress_decl : SuppressLevel.values()) { + for (SuppressLevel suppress_use : SuppressLevel.values()) { + for (ClassKind ck : ClassKind.values()) { + for (ExceptionKind ek_decl : ExceptionKind.values()) { + for (ExceptionKind ek_use : ExceptionKind.values()) { + new InterruptedExceptionTest(xlint, suppress_decl, + suppress_use, ck, ek_decl, ek_use).run(comp, fm); + } + } + } + } + } + } + } + + XlintOption xlint; + SuppressLevel suppress_decl; + SuppressLevel suppress_use; + ClassKind ck; + ExceptionKind ek_decl; + ExceptionKind ek_use; + JavaSource source; + DiagnosticChecker diagChecker; + + InterruptedExceptionTest(XlintOption xlint, SuppressLevel suppress_decl, SuppressLevel suppress_use, + ClassKind ck, ExceptionKind ek_decl, ExceptionKind ek_use) { + this.xlint = xlint; + this.suppress_decl = suppress_decl; + this.suppress_use = suppress_use; + this.ck = ck; + this.ek_decl = ek_decl; + this.ek_use = ek_use; + this.source = new JavaSource(); + this.diagChecker = new DiagnosticChecker(); + } + + class JavaSource extends SimpleJavaFileObject { + + String template = "#S1 #CK Resource#G #EC AutoCloseable {\n" + + "public void close() #TK #BK\n" + + "}\n" + + "class Test {\n" + + "#S2 void test() {\n" + + "try (Resource#PK r = null) { }\n" + + "}\n" + + "}\n"; + + String source; + + public JavaSource() { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + source = template.replace("#S1", suppress_decl.getSuppressAnno()) + .replace("#S2", suppress_use.getSuppressAnno()) + .replace("#CK", ck.kindName) + .replace("#EC", ck.extendsClause) + .replace("#G", ek_decl.getTypeParameter()) + .replace("#TK", ek_decl.getThrowsClause()) + .replace("#BK", ck.getBody()) + .replace("#PK", ek_use.getTypeArguments(ek_decl)); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return source; + } + } + + void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception { + JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker, + Arrays.asList(xlint.getXlintOption()), null, Arrays.asList(source)); + ct.analyze(); + check(); + } + + void check() { + + boolean shouldWarnDecl = ek_decl.shouldWarn && + xlint == XlintOption.TRY && + suppress_decl != SuppressLevel.SUPPRESS; + + boolean shouldWarnUse = (ek_decl.shouldWarn || + ((ek_use.shouldWarn || ek_use == ExceptionKind.NONE) && ek_decl == ExceptionKind.X)) && + xlint == XlintOption.TRY && + suppress_use != SuppressLevel.SUPPRESS; + + int foundWarnings = 0; + + if (shouldWarnDecl) foundWarnings++; + if (shouldWarnUse) foundWarnings++; + + if (foundWarnings != diagChecker.tryWarnFound) { + throw new Error("invalid diagnostics for source:\n" + + source.getCharContent(true) + + "\nOptions: " + xlint.getXlintOption() + + "\nFound warnings: " + diagChecker.tryWarnFound + + "\nExpected decl warning: " + shouldWarnDecl + + "\nExpected use warning: " + shouldWarnUse); + } + } + + static class DiagnosticChecker implements javax.tools.DiagnosticListener { + + int tryWarnFound; + + public void report(Diagnostic diagnostic) { + if (diagnostic.getKind() == Diagnostic.Kind.WARNING && + diagnostic.getCode().contains("try.resource.throws.interrupted.exc")) { + tryWarnFound++; + } + } + } +}