src/share/classes/com/sun/tools/javac/comp/Flow.java

changeset 2019
77d395862700
parent 1955
ec77c7b46c37
child 2027
4932bb04c4b8
equal deleted inserted replaced
2018:7439356a7dc5 2019:77d395862700
222 if (!speculative) { 222 if (!speculative) {
223 diagHandler = new Log.DiscardDiagnosticHandler(log); 223 diagHandler = new Log.DiscardDiagnosticHandler(log);
224 } 224 }
225 try { 225 try {
226 new AliveAnalyzer().analyzeTree(env, that, make); 226 new AliveAnalyzer().analyzeTree(env, that, make);
227 new LambdaFlowAnalyzer().analyzeTree(env, that, make);
228 } finally { 227 } finally {
229 if (!speculative) { 228 if (!speculative) {
230 log.popDiagnosticHandler(diagHandler); 229 log.popDiagnosticHandler(diagHandler);
231 } 230 }
231 }
232 }
233
234 public List<Type> analyzeLambdaThrownTypes(Env<AttrContext> env, JCLambda that, TreeMaker make) {
235 //we need to disable diagnostics temporarily; the problem is that if
236 //a lambda expression contains e.g. an unreachable statement, an error
237 //message will be reported and will cause compilation to skip the flow analyis
238 //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
239 //related errors, which will allow for more errors to be detected
240 Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
241 try {
242 new AssignAnalyzer().analyzeTree(env, that, make);
243 LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
244 flowAnalyzer.analyzeTree(env, that, make);
245 return flowAnalyzer.inferredThrownTypes;
246 } finally {
247 log.popDiagnosticHandler(diagHandler);
232 } 248 }
233 } 249 }
234 250
235 /** 251 /**
236 * Definite assignment scan mode 252 * Definite assignment scan mode
1316 1332
1317 /** 1333 /**
1318 * Specialized pass that performs inference of thrown types for lambdas. 1334 * Specialized pass that performs inference of thrown types for lambdas.
1319 */ 1335 */
1320 class LambdaFlowAnalyzer extends FlowAnalyzer { 1336 class LambdaFlowAnalyzer extends FlowAnalyzer {
1337 List<Type> inferredThrownTypes;
1338 boolean inLambda;
1321 @Override 1339 @Override
1322 public void visitLambda(JCLambda tree) { 1340 public void visitLambda(JCLambda tree) {
1323 if (tree.type != null && 1341 if ((tree.type != null &&
1324 tree.type.isErroneous()) { 1342 tree.type.isErroneous()) || inLambda) {
1325 return; 1343 return;
1326 } 1344 }
1327 List<Type> prevCaught = caught; 1345 List<Type> prevCaught = caught;
1328 List<Type> prevThrown = thrown; 1346 List<Type> prevThrown = thrown;
1329 ListBuffer<FlowPendingExit> prevPending = pendingExits; 1347 ListBuffer<FlowPendingExit> prevPending = pendingExits;
1348 inLambda = true;
1330 try { 1349 try {
1331 pendingExits = ListBuffer.lb(); 1350 pendingExits = ListBuffer.lb();
1332 caught = List.of(syms.throwableType); 1351 caught = List.of(syms.throwableType);
1333 thrown = List.nil(); 1352 thrown = List.nil();
1334 scan(tree.body); 1353 scan(tree.body);
1335 tree.inferredThrownTypes = thrown; 1354 inferredThrownTypes = thrown;
1336 } finally { 1355 } finally {
1337 pendingExits = prevPending; 1356 pendingExits = prevPending;
1338 caught = prevCaught; 1357 caught = prevCaught;
1339 thrown = prevThrown; 1358 thrown = prevThrown;
1340 } 1359 inLambda = false;
1360 }
1361 }
1362 @Override
1363 public void visitClassDef(JCClassDecl tree) {
1364 //skip
1341 } 1365 }
1342 } 1366 }
1343 1367
1344 /** 1368 /**
1345 * This pass implements (i) definite assignment analysis, which ensures that 1369 * This pass implements (i) definite assignment analysis, which ensures that

mercurial