--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Mon Sep 09 17:36:23 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Mon Sep 09 23:13:45 2013 +0200
@@ -224,7 +224,6 @@
}
try {
new AliveAnalyzer().analyzeTree(env, that, make);
- new LambdaFlowAnalyzer().analyzeTree(env, that, make);
} finally {
if (!speculative) {
log.popDiagnosticHandler(diagHandler);
@@ -232,6 +231,23 @@
}
}
+ public List<Type> analyzeLambdaThrownTypes(Env<AttrContext> env, JCLambda that, TreeMaker make) {
+ //we need to disable diagnostics temporarily; the problem is that if
+ //a lambda expression contains e.g. an unreachable statement, an error
+ //message will be reported and will cause compilation to skip the flow analyis
+ //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
+ //related errors, which will allow for more errors to be detected
+ Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
+ try {
+ new AssignAnalyzer().analyzeTree(env, that, make);
+ LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
+ flowAnalyzer.analyzeTree(env, that, make);
+ return flowAnalyzer.inferredThrownTypes;
+ } finally {
+ log.popDiagnosticHandler(diagHandler);
+ }
+ }
+
/**
* Definite assignment scan mode
*/
@@ -1318,27 +1334,35 @@
* Specialized pass that performs inference of thrown types for lambdas.
*/
class LambdaFlowAnalyzer extends FlowAnalyzer {
+ List<Type> inferredThrownTypes;
+ boolean inLambda;
@Override
public void visitLambda(JCLambda tree) {
- if (tree.type != null &&
- tree.type.isErroneous()) {
+ if ((tree.type != null &&
+ tree.type.isErroneous()) || inLambda) {
return;
}
List<Type> prevCaught = caught;
List<Type> prevThrown = thrown;
ListBuffer<FlowPendingExit> prevPending = pendingExits;
+ inLambda = true;
try {
pendingExits = ListBuffer.lb();
caught = List.of(syms.throwableType);
thrown = List.nil();
scan(tree.body);
- tree.inferredThrownTypes = thrown;
+ inferredThrownTypes = thrown;
} finally {
pendingExits = prevPending;
caught = prevCaught;
thrown = prevThrown;
+ inLambda = false;
}
}
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ //skip
+ }
}
/**