test/tools/javac/TryWithResources/InterruptedExceptionTest.java

Tue, 29 Mar 2011 16:41:18 +0100

author
mcimadamore
date
Tue, 29 Mar 2011 16:41:18 +0100
changeset 951
de1c65ecfec2
parent 0
959103a6100f
permissions
-rw-r--r--

7027157: Project Coin: javac warnings for AutoCloseable.close throwing InterruptedException
Summary: javac should warn about use/declaration of AutoCloseable subclasses that can throw InterruptedException
Reviewed-by: jjg

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 */
aoqi@0 23
aoqi@0 24 /*
aoqi@0 25 * @test
aoqi@0 26 * @bug 7027157
aoqi@0 27 * @summary Project Coin: javac warnings for AutoCloseable.close throwing InterruptedException
aoqi@0 28 */
aoqi@0 29
aoqi@0 30 import com.sun.source.util.JavacTask;
aoqi@0 31 import java.net.URI;
aoqi@0 32 import java.util.Arrays;
aoqi@0 33 import javax.tools.Diagnostic;
aoqi@0 34 import javax.tools.JavaCompiler;
aoqi@0 35 import javax.tools.JavaFileObject;
aoqi@0 36 import javax.tools.SimpleJavaFileObject;
aoqi@0 37 import javax.tools.StandardJavaFileManager;
aoqi@0 38 import javax.tools.ToolProvider;
aoqi@0 39
aoqi@0 40 public class InterruptedExceptionTest {
aoqi@0 41
aoqi@0 42 enum XlintOption {
aoqi@0 43 NONE("none"),
aoqi@0 44 TRY("try");
aoqi@0 45
aoqi@0 46 String opt;
aoqi@0 47
aoqi@0 48 XlintOption(String opt) {
aoqi@0 49 this.opt = opt;
aoqi@0 50 }
aoqi@0 51
aoqi@0 52 String getXlintOption() {
aoqi@0 53 return "-Xlint:" + opt;
aoqi@0 54 }
aoqi@0 55 }
aoqi@0 56
aoqi@0 57 enum SuppressLevel {
aoqi@0 58 NONE,
aoqi@0 59 SUPPRESS;
aoqi@0 60
aoqi@0 61 String getSuppressAnno() {
aoqi@0 62 return this == SUPPRESS ?
aoqi@0 63 "@SuppressWarnings(\"try\")" :
aoqi@0 64 "";
aoqi@0 65 }
aoqi@0 66 }
aoqi@0 67
aoqi@0 68 enum ClassKind {
aoqi@0 69 ABSTRACT_CLASS("abstract class", "implements", false),
aoqi@0 70 CLASS("class", "implements", true),
aoqi@0 71 INTERFACE("interface", "extends", false);
aoqi@0 72
aoqi@0 73 String kindName;
aoqi@0 74 String extendsClause;
aoqi@0 75 boolean hasBody;
aoqi@0 76
aoqi@0 77 private ClassKind(String kindName, String extendsClause, boolean hasBody) {
aoqi@0 78 this.kindName = kindName;
aoqi@0 79 this.extendsClause = extendsClause;
aoqi@0 80 this.hasBody = hasBody;
aoqi@0 81 }
aoqi@0 82
aoqi@0 83 String getBody() {
aoqi@0 84 return hasBody ? "{}" : ";";
aoqi@0 85 }
aoqi@0 86 }
aoqi@0 87
aoqi@0 88 enum ExceptionKind {
aoqi@0 89 NONE("", false),
aoqi@0 90 EXCEPTION("Exception", true),
aoqi@0 91 INTERRUPTED_EXCEPTION("InterruptedException", true),
aoqi@0 92 ILLEGAL_ARGUMENT_EXCEPTION("IllegalArgumentException", false),
aoqi@0 93 X("X", false);
aoqi@0 94
aoqi@0 95 String exName;
aoqi@0 96 boolean shouldWarn;
aoqi@0 97
aoqi@0 98 private ExceptionKind(String exName, boolean shouldWarn) {
aoqi@0 99 this.exName = exName;
aoqi@0 100 this.shouldWarn = shouldWarn;
aoqi@0 101 }
aoqi@0 102
aoqi@0 103 String getThrowsClause() {
aoqi@0 104 return this == NONE ? "" : "throws " + exName;
aoqi@0 105 }
aoqi@0 106
aoqi@0 107 String getTypeArguments(ExceptionKind decl) {
aoqi@0 108 return (decl != X || this == NONE) ? "" : "<" + exName + ">";
aoqi@0 109 }
aoqi@0 110
aoqi@0 111 String getTypeParameter() {
aoqi@0 112 return this == X ? "<X extends Exception>" : "";
aoqi@0 113 }
aoqi@0 114 }
aoqi@0 115
aoqi@0 116 public static void main(String... args) throws Exception {
aoqi@0 117
aoqi@0 118 //create default shared JavaCompiler - reused across multiple compilations
aoqi@0 119 JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
aoqi@0 120 StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
aoqi@0 121
aoqi@0 122 for (XlintOption xlint : XlintOption.values()) {
aoqi@0 123 for (SuppressLevel suppress_decl : SuppressLevel.values()) {
aoqi@0 124 for (SuppressLevel suppress_use : SuppressLevel.values()) {
aoqi@0 125 for (ClassKind ck : ClassKind.values()) {
aoqi@0 126 for (ExceptionKind ek_decl : ExceptionKind.values()) {
aoqi@0 127 for (ExceptionKind ek_use : ExceptionKind.values()) {
aoqi@0 128 new InterruptedExceptionTest(xlint, suppress_decl,
aoqi@0 129 suppress_use, ck, ek_decl, ek_use).run(comp, fm);
aoqi@0 130 }
aoqi@0 131 }
aoqi@0 132 }
aoqi@0 133 }
aoqi@0 134 }
aoqi@0 135 }
aoqi@0 136 }
aoqi@0 137
aoqi@0 138 XlintOption xlint;
aoqi@0 139 SuppressLevel suppress_decl;
aoqi@0 140 SuppressLevel suppress_use;
aoqi@0 141 ClassKind ck;
aoqi@0 142 ExceptionKind ek_decl;
aoqi@0 143 ExceptionKind ek_use;
aoqi@0 144 JavaSource source;
aoqi@0 145 DiagnosticChecker diagChecker;
aoqi@0 146
aoqi@0 147 InterruptedExceptionTest(XlintOption xlint, SuppressLevel suppress_decl, SuppressLevel suppress_use,
aoqi@0 148 ClassKind ck, ExceptionKind ek_decl, ExceptionKind ek_use) {
aoqi@0 149 this.xlint = xlint;
aoqi@0 150 this.suppress_decl = suppress_decl;
aoqi@0 151 this.suppress_use = suppress_use;
aoqi@0 152 this.ck = ck;
aoqi@0 153 this.ek_decl = ek_decl;
aoqi@0 154 this.ek_use = ek_use;
aoqi@0 155 this.source = new JavaSource();
aoqi@0 156 this.diagChecker = new DiagnosticChecker();
aoqi@0 157 }
aoqi@0 158
aoqi@0 159 class JavaSource extends SimpleJavaFileObject {
aoqi@0 160
aoqi@0 161 String template = "#S1 #CK Resource#G #EC AutoCloseable {\n" +
aoqi@0 162 "public void close() #TK #BK\n" +
aoqi@0 163 "}\n" +
aoqi@0 164 "class Test {\n" +
aoqi@0 165 "#S2 <X> void test() {\n" +
aoqi@0 166 "try (Resource#PK r = null) { }\n" +
aoqi@0 167 "}\n" +
aoqi@0 168 "}\n";
aoqi@0 169
aoqi@0 170 String source;
aoqi@0 171
aoqi@0 172 public JavaSource() {
aoqi@0 173 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
aoqi@0 174 source = template.replace("#S1", suppress_decl.getSuppressAnno())
aoqi@0 175 .replace("#S2", suppress_use.getSuppressAnno())
aoqi@0 176 .replace("#CK", ck.kindName)
aoqi@0 177 .replace("#EC", ck.extendsClause)
aoqi@0 178 .replace("#G", ek_decl.getTypeParameter())
aoqi@0 179 .replace("#TK", ek_decl.getThrowsClause())
aoqi@0 180 .replace("#BK", ck.getBody())
aoqi@0 181 .replace("#PK", ek_use.getTypeArguments(ek_decl));
aoqi@0 182 }
aoqi@0 183
aoqi@0 184 @Override
aoqi@0 185 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
aoqi@0 186 return source;
aoqi@0 187 }
aoqi@0 188 }
aoqi@0 189
aoqi@0 190 void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
aoqi@0 191 JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
aoqi@0 192 Arrays.asList(xlint.getXlintOption()), null, Arrays.asList(source));
aoqi@0 193 ct.analyze();
aoqi@0 194 check();
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 void check() {
aoqi@0 198
aoqi@0 199 boolean shouldWarnDecl = ek_decl.shouldWarn &&
aoqi@0 200 xlint == XlintOption.TRY &&
aoqi@0 201 suppress_decl != SuppressLevel.SUPPRESS;
aoqi@0 202
aoqi@0 203 boolean shouldWarnUse = (ek_decl.shouldWarn ||
aoqi@0 204 ((ek_use.shouldWarn || ek_use == ExceptionKind.NONE) && ek_decl == ExceptionKind.X)) &&
aoqi@0 205 xlint == XlintOption.TRY &&
aoqi@0 206 suppress_use != SuppressLevel.SUPPRESS;
aoqi@0 207
aoqi@0 208 int foundWarnings = 0;
aoqi@0 209
aoqi@0 210 if (shouldWarnDecl) foundWarnings++;
aoqi@0 211 if (shouldWarnUse) foundWarnings++;
aoqi@0 212
aoqi@0 213 if (foundWarnings != diagChecker.tryWarnFound) {
aoqi@0 214 throw new Error("invalid diagnostics for source:\n" +
aoqi@0 215 source.getCharContent(true) +
aoqi@0 216 "\nOptions: " + xlint.getXlintOption() +
aoqi@0 217 "\nFound warnings: " + diagChecker.tryWarnFound +
aoqi@0 218 "\nExpected decl warning: " + shouldWarnDecl +
aoqi@0 219 "\nExpected use warning: " + shouldWarnUse);
aoqi@0 220 }
aoqi@0 221 }
aoqi@0 222
aoqi@0 223 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
aoqi@0 224
aoqi@0 225 int tryWarnFound;
aoqi@0 226
aoqi@0 227 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
aoqi@0 228 if (diagnostic.getKind() == Diagnostic.Kind.WARNING &&
aoqi@0 229 diagnostic.getCode().contains("try.resource.throws.interrupted.exc")) {
aoqi@0 230 tryWarnFound++;
aoqi@0 231 }
aoqi@0 232 }
aoqi@0 233 }
aoqi@0 234 }

mercurial