mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
6993963: Project Coin: Use precise exception analysis for effectively final catch parameters
More precise rethrow analysis should be extended to effectively-final exception parameters. Multicatch parameters should be made implicitly final. Reviewed-by: jjg, darcy
This commit is contained in:
parent
9b7bc21bb0
commit
d4d5f60edc
@ -247,6 +247,11 @@ public class Flags {
|
||||
*/
|
||||
public static final long OVERRIDE_BRIDGE = 1L<<41;
|
||||
|
||||
/**
|
||||
* Flag that marks an 'effectively final' local variable
|
||||
*/
|
||||
public static final long EFFECTIVELY_FINAL = 1L<<42;
|
||||
|
||||
/** Modifier masks.
|
||||
*/
|
||||
public static final int
|
||||
|
||||
@ -256,6 +256,8 @@ public class Attr extends JCTree.Visitor {
|
||||
} else {
|
||||
log.error(pos, "cant.assign.val.to.final.var", v);
|
||||
}
|
||||
} else if ((v.flags() & EFFECTIVELY_FINAL) != 0) {
|
||||
v.flags_field &= ~EFFECTIVELY_FINAL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -799,6 +801,7 @@ public class Attr extends JCTree.Visitor {
|
||||
memberEnter.memberEnter(tree, env);
|
||||
annotate.flush();
|
||||
}
|
||||
tree.sym.flags_field |= EFFECTIVELY_FINAL;
|
||||
}
|
||||
|
||||
VarSymbol v = tree.sym;
|
||||
@ -1061,11 +1064,8 @@ public class Attr extends JCTree.Visitor {
|
||||
localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
|
||||
Type ctype = attribStat(c.param, catchEnv);
|
||||
if (TreeInfo.isMultiCatch(c)) {
|
||||
//check that multi-catch parameter is marked as final
|
||||
if ((c.param.sym.flags() & FINAL) == 0) {
|
||||
log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym);
|
||||
}
|
||||
c.param.sym.flags_field = c.param.sym.flags() | DISJUNCTION;
|
||||
//multi-catch parameter is implicitly marked as final
|
||||
c.param.sym.flags_field |= FINAL | DISJUNCTION;
|
||||
}
|
||||
if (c.param.sym.kind == Kinds.VAR) {
|
||||
c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
|
||||
|
||||
@ -226,7 +226,7 @@ public class Flow extends TreeScanner {
|
||||
*/
|
||||
Bits uninits;
|
||||
|
||||
HashMap<Symbol, List<Type>> multicatchTypes;
|
||||
HashMap<Symbol, List<Type>> preciseRethrowTypes;
|
||||
|
||||
/** The set of variables that are definitely unassigned everywhere
|
||||
* in current try block. This variable is maintained lazily; it is
|
||||
@ -332,7 +332,7 @@ public class Flow extends TreeScanner {
|
||||
if (!chk.isUnchecked(tree.pos(), exc)) {
|
||||
if (!chk.isHandled(exc, caught))
|
||||
pendingExits.append(new PendingExit(tree, exc));
|
||||
thrown = chk.incl(exc, thrown);
|
||||
thrown = chk.incl(exc, thrown);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1077,12 +1077,12 @@ public class Flow extends TreeScanner {
|
||||
scan(param);
|
||||
inits.incl(param.sym.adr);
|
||||
uninits.excl(param.sym.adr);
|
||||
multicatchTypes.put(param.sym, chk.intersect(ctypes, rethrownTypes));
|
||||
preciseRethrowTypes.put(param.sym, chk.intersect(ctypes, rethrownTypes));
|
||||
scanStat(l.head.body);
|
||||
initsEnd.andSet(inits);
|
||||
uninitsEnd.andSet(uninits);
|
||||
nextadr = nextadrCatch;
|
||||
multicatchTypes.remove(param.sym);
|
||||
preciseRethrowTypes.remove(param.sym);
|
||||
aliveEnd |= alive;
|
||||
}
|
||||
if (tree.finalizer != null) {
|
||||
@ -1215,10 +1215,10 @@ public class Flow extends TreeScanner {
|
||||
Symbol sym = TreeInfo.symbol(tree.expr);
|
||||
if (sym != null &&
|
||||
sym.kind == VAR &&
|
||||
(sym.flags() & FINAL) != 0 &&
|
||||
multicatchTypes.get(sym) != null &&
|
||||
(sym.flags() & (FINAL | EFFECTIVELY_FINAL)) != 0 &&
|
||||
preciseRethrowTypes.get(sym) != null &&
|
||||
allowRethrowAnalysis) {
|
||||
for (Type t : multicatchTypes.get(sym)) {
|
||||
for (Type t : preciseRethrowTypes.get(sym)) {
|
||||
markThrown(tree, t);
|
||||
}
|
||||
}
|
||||
@ -1422,7 +1422,7 @@ public class Flow extends TreeScanner {
|
||||
firstadr = 0;
|
||||
nextadr = 0;
|
||||
pendingExits = new ListBuffer<PendingExit>();
|
||||
multicatchTypes = new HashMap<Symbol, List<Type>>();
|
||||
preciseRethrowTypes = new HashMap<Symbol, List<Type>>();
|
||||
alive = true;
|
||||
this.thrown = this.caught = null;
|
||||
this.classDef = null;
|
||||
|
||||
@ -187,8 +187,6 @@ compiler.err.twr.resource.may.not.be.assigned=\
|
||||
automatic resource {0} may not be assigned
|
||||
compiler.err.multicatch.parameter.may.not.be.assigned=\
|
||||
multi-catch parameter {0} may not be assigned
|
||||
compiler.err.multicatch.param.must.be.final=\
|
||||
multi-catch parameter {0} must be final
|
||||
compiler.err.finally.without.try=\
|
||||
''finally'' without ''try''
|
||||
compiler.err.foreach.not.applicable.to.type=\
|
||||
|
||||
28
langtools/test/tools/javac/multicatch/Neg01eff_final.java
Normal file
28
langtools/test/tools/javac/multicatch/Neg01eff_final.java
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6943289
|
||||
*
|
||||
* @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch')
|
||||
* @author darcy
|
||||
* @compile/fail/ref=Neg01eff_final.out -XDrawDiagnostics Neg01eff_final.java
|
||||
* @compile -source 6 -XDrawDiagnostics Neg01eff_final.java
|
||||
*
|
||||
*/
|
||||
|
||||
class Neg01eff_final {
|
||||
static class A extends Exception {}
|
||||
static class B1 extends A {}
|
||||
static class B2 extends A {}
|
||||
|
||||
class Test {
|
||||
void m() throws A {
|
||||
try {
|
||||
throw new B1();
|
||||
} catch (A ex1) {
|
||||
try {
|
||||
throw ex1; // used to throw A, now throws B1!
|
||||
} catch (B2 ex2) { }//unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
langtools/test/tools/javac/multicatch/Neg01eff_final.out
Normal file
2
langtools/test/tools/javac/multicatch/Neg01eff_final.out
Normal file
@ -0,0 +1,2 @@
|
||||
Neg01eff_final.java:24:19: compiler.err.except.never.thrown.in.try: Neg01eff_final.B2
|
||||
1 error
|
||||
@ -20,6 +20,8 @@ class Neg02 {
|
||||
else {
|
||||
throw new B();
|
||||
}
|
||||
} catch (A | B ex) { }
|
||||
} catch (final A | B ex) {
|
||||
ex = new B();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
Neg02.java:23:24: compiler.err.multicatch.param.must.be.final: ex
|
||||
Neg02.java:24:13: compiler.err.multicatch.parameter.may.not.be.assigned: ex
|
||||
1 error
|
||||
|
||||
27
langtools/test/tools/javac/multicatch/Neg02eff_final.java
Normal file
27
langtools/test/tools/javac/multicatch/Neg02eff_final.java
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6943289 6993963
|
||||
*
|
||||
* @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch')
|
||||
* @author mcimadamore
|
||||
* @compile/fail/ref=Neg02eff_final.out -XDrawDiagnostics Neg02eff_final.java
|
||||
*
|
||||
*/
|
||||
|
||||
class Neg02eff_final {
|
||||
static class A extends Exception {}
|
||||
static class B extends Exception {}
|
||||
|
||||
void m() {
|
||||
try {
|
||||
if (true) {
|
||||
throw new A();
|
||||
}
|
||||
else {
|
||||
throw new B();
|
||||
}
|
||||
} catch (A | B ex) {
|
||||
ex = new B();
|
||||
}
|
||||
}
|
||||
}
|
||||
2
langtools/test/tools/javac/multicatch/Neg02eff_final.out
Normal file
2
langtools/test/tools/javac/multicatch/Neg02eff_final.out
Normal file
@ -0,0 +1,2 @@
|
||||
Neg02eff_final.java:24:13: compiler.err.multicatch.parameter.may.not.be.assigned: ex
|
||||
1 error
|
||||
@ -9,19 +9,22 @@
|
||||
*/
|
||||
|
||||
class Neg03 {
|
||||
static class A extends Exception {}
|
||||
static class B extends Exception {}
|
||||
|
||||
void m() {
|
||||
static class A extends Exception { public void m() {}; public Object f;}
|
||||
static class B1 extends A {}
|
||||
static class B2 extends A {}
|
||||
|
||||
void m() throws B1, B2 {
|
||||
try {
|
||||
if (true) {
|
||||
throw new A();
|
||||
throw new B1();
|
||||
}
|
||||
else {
|
||||
throw new B();
|
||||
throw new B2();
|
||||
}
|
||||
} catch (final A | B ex) {
|
||||
ex = new B();
|
||||
} catch (Exception ex) {
|
||||
ex = new B2(); //effectively final analysis disabled!
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
Neg03.java:24:13: compiler.err.multicatch.parameter.may.not.be.assigned: ex
|
||||
Neg03.java:27:13: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
1 error
|
||||
|
||||
31
langtools/test/tools/javac/multicatch/Neg04eff_final.java
Normal file
31
langtools/test/tools/javac/multicatch/Neg04eff_final.java
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6943289
|
||||
*
|
||||
* @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch')
|
||||
* @author mcimadamore
|
||||
* @compile/fail/ref=Neg04eff_final.out -XDrawDiagnostics Neg04eff_final.java
|
||||
*
|
||||
*/
|
||||
|
||||
class Neg04eff_final {
|
||||
static class A extends Exception {}
|
||||
static class B extends Exception {}
|
||||
|
||||
void test() throws B {
|
||||
try {
|
||||
if (true) {
|
||||
throw new A();
|
||||
} else if (false) {
|
||||
throw new B();
|
||||
} else {
|
||||
throw (Throwable)new Exception();
|
||||
}
|
||||
}
|
||||
catch (A e) {}
|
||||
catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable t) {}
|
||||
}
|
||||
}
|
||||
2
langtools/test/tools/javac/multicatch/Neg04eff_final.out
Normal file
2
langtools/test/tools/javac/multicatch/Neg04eff_final.out
Normal file
@ -0,0 +1,2 @@
|
||||
Neg04eff_final.java:27:13: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
1 error
|
||||
33
langtools/test/tools/javac/multicatch/Neg05.java
Normal file
33
langtools/test/tools/javac/multicatch/Neg05.java
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6943289
|
||||
*
|
||||
* @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch')
|
||||
* @author mcimadamore
|
||||
* @compile/fail/ref=Neg05.out -XDrawDiagnostics Neg05.java
|
||||
*
|
||||
*/
|
||||
|
||||
class Neg02 {
|
||||
|
||||
static class Foo<X> {
|
||||
Foo(X x) {}
|
||||
}
|
||||
|
||||
static interface Base<X> {}
|
||||
static class A extends Exception implements Base<String> {}
|
||||
static class B extends Exception implements Base<Integer> {}
|
||||
|
||||
void m() {
|
||||
try {
|
||||
if (true) {
|
||||
throw new A();
|
||||
}
|
||||
else {
|
||||
throw new B();
|
||||
}
|
||||
} catch (A | B ex) {
|
||||
Foo<?> f = new Foo<>(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
langtools/test/tools/javac/multicatch/Neg05.out
Normal file
2
langtools/test/tools/javac/multicatch/Neg05.out
Normal file
@ -0,0 +1,2 @@
|
||||
Neg05.java:30:31: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg02.Foo), (compiler.misc.diamond.invalid.arg: java.lang.Exception&Neg02.Base<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, (compiler.misc.diamond: Neg02.Foo))
|
||||
1 error
|
||||
27
langtools/test/tools/javac/multicatch/Pos06.java
Normal file
27
langtools/test/tools/javac/multicatch/Pos06.java
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6993963
|
||||
*
|
||||
* @summary Project Coin: Use precise exception analysis for effectively final catch parameters
|
||||
* @author mcimadamore
|
||||
* @compile Pos06.java
|
||||
*
|
||||
*/
|
||||
|
||||
class Pos06 {
|
||||
static class A extends Exception {}
|
||||
static class B extends Exception {}
|
||||
|
||||
void m() {
|
||||
try {
|
||||
if (true) {
|
||||
throw new A();
|
||||
}
|
||||
else {
|
||||
throw new B();
|
||||
}
|
||||
} catch (A | B ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
langtools/test/tools/javac/multicatch/Pos07.java
Normal file
49
langtools/test/tools/javac/multicatch/Pos07.java
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 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 6993963
|
||||
* @summary Project Coin: Use precise exception analysis for effectively final catch parameters
|
||||
* @compile Pos07.java
|
||||
*/
|
||||
|
||||
class Pos07 {
|
||||
|
||||
static class A extends Exception { public void m() {}; public Object f;}
|
||||
static class B1 extends A {}
|
||||
static class B2 extends A {}
|
||||
|
||||
void m() throws B1, B2 {
|
||||
try {
|
||||
if (true) {
|
||||
throw new B1();
|
||||
}
|
||||
else {
|
||||
throw new B2();
|
||||
}
|
||||
} catch (Exception ex) { //effectively final analysis
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
27
langtools/test/tools/javac/multicatch/model/Check.java
Normal file
27
langtools/test/tools/javac/multicatch/model/Check.java
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Annotation used by ModelChecker to mark the class whose model is to be checked
|
||||
*/
|
||||
@interface Check {}
|
||||
@ -21,18 +21,11 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// key: compiler.err.multicatch.param.must.be.final
|
||||
import javax.lang.model.element.ElementKind;
|
||||
|
||||
class MulticatchMustBeFinal {
|
||||
void e1() throws NullPointerException { }
|
||||
void e2() throws IllegalArgumentException { }
|
||||
|
||||
void m() {
|
||||
try {
|
||||
e1();
|
||||
e2();
|
||||
} catch (NullPointerException | IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Annotation used by ModelChecker to mark a member that is to be checked
|
||||
*/
|
||||
@interface Member {
|
||||
ElementKind value();
|
||||
}
|
||||
48
langtools/test/tools/javac/multicatch/model/Model01.java
Normal file
48
langtools/test/tools/javac/multicatch/model/Model01.java
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 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 javax.lang.model.element.ElementKind;
|
||||
|
||||
@Check
|
||||
class Test {
|
||||
|
||||
class A extends Exception {
|
||||
@Member(ElementKind.METHOD)
|
||||
public void m() {};
|
||||
@Member(ElementKind.FIELD)
|
||||
public Object f;
|
||||
}
|
||||
|
||||
class B1 extends A {}
|
||||
class B2 extends A {}
|
||||
|
||||
void test(){
|
||||
try {
|
||||
if (true)
|
||||
throw new B1();
|
||||
else
|
||||
throw new B2();
|
||||
}
|
||||
catch(B1 | B2 ex) { }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 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 6993963
|
||||
* @summary Project Coin: Use precise exception analysis for effectively final catch parameters
|
||||
* @library ../../lib
|
||||
* @build JavacTestingAbstractProcessor ModelChecker
|
||||
* @compile -processor ModelChecker Model01.java
|
||||
*/
|
||||
|
||||
import com.sun.source.tree.VariableTree;
|
||||
import com.sun.source.util.TreePathScanner;
|
||||
import com.sun.source.util.Trees;
|
||||
import com.sun.source.util.TreePath;
|
||||
|
||||
import java.util.Set;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
@SupportedAnnotationTypes("Check")
|
||||
public class ModelChecker extends JavacTestingAbstractProcessor {
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
if (roundEnv.processingOver())
|
||||
return true;
|
||||
|
||||
Trees trees = Trees.instance(processingEnv);
|
||||
|
||||
TypeElement testAnno = elements.getTypeElement("Check");
|
||||
for (Element elem: roundEnv.getElementsAnnotatedWith(testAnno)) {
|
||||
TreePath p = trees.getPath(elem);
|
||||
new MulticatchParamTester(trees).scan(p, null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class MulticatchParamTester extends TreePathScanner<Void, Void> {
|
||||
Trees trees;
|
||||
|
||||
public MulticatchParamTester(Trees trees) {
|
||||
super();
|
||||
this.trees = trees;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitVariable(VariableTree node, Void p) {
|
||||
Element ex = trees.getElement(getCurrentPath());
|
||||
if (ex.getSimpleName().contentEquals("ex")) {
|
||||
assertTrue(ex.getKind() == ElementKind.EXCEPTION_PARAMETER, "Expected EXCEPTION_PARAMETER - found " + ex.getKind());
|
||||
for (Element e : types.asElement(ex.asType()).getEnclosedElements()) {
|
||||
Member m = e.getAnnotation(Member.class);
|
||||
if (m != null) {
|
||||
assertTrue(e.getKind() == m.value(), "Expected " + m.value() + " - found " + e.getKind());
|
||||
}
|
||||
}
|
||||
assertTrue(assertionCount == 3, "Expected 3 assertions - found " + assertionCount);
|
||||
}
|
||||
return super.visitVariable(node, p);
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertTrue(boolean cond, String msg) {
|
||||
assertionCount++;
|
||||
if (!cond)
|
||||
throw new AssertionError(msg);
|
||||
}
|
||||
|
||||
static int assertionCount = 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user