langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
changeset 41640 0c5bdda9ac56
parent 41156 251471aec877
child 41854 12089a7805af
equal deleted inserted replaced
41639:90220025bd6c 41640:0c5bdda9ac56
    27 
    27 
    28 package com.sun.tools.javac.comp;
    28 package com.sun.tools.javac.comp;
    29 
    29 
    30 import java.util.HashMap;
    30 import java.util.HashMap;
    31 
    31 
       
    32 import com.sun.source.tree.LambdaExpressionTree.BodyKind;
    32 import com.sun.tools.javac.code.*;
    33 import com.sun.tools.javac.code.*;
    33 import com.sun.tools.javac.code.Scope.WriteableScope;
    34 import com.sun.tools.javac.code.Scope.WriteableScope;
    34 import com.sun.tools.javac.tree.*;
    35 import com.sun.tools.javac.tree.*;
    35 import com.sun.tools.javac.util.*;
    36 import com.sun.tools.javac.util.*;
    36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
   222         //related errors, which will allow for more errors to be detected
   223         //related errors, which will allow for more errors to be detected
   223         if (!speculative) {
   224         if (!speculative) {
   224             diagHandler = new Log.DiscardDiagnosticHandler(log);
   225             diagHandler = new Log.DiscardDiagnosticHandler(log);
   225         }
   226         }
   226         try {
   227         try {
   227             new AliveAnalyzer().analyzeTree(env, that, make);
   228             new LambdaAliveAnalyzer().analyzeTree(env, that, make);
   228         } finally {
   229         } finally {
   229             if (!speculative) {
   230             if (!speculative) {
   230                 log.popDiagnosticHandler(diagHandler);
   231                 log.popDiagnosticHandler(diagHandler);
   231             }
   232             }
   232         }
   233         }
   239         //message will be reported and will cause compilation to skip the flow analyis
   240         //message will be reported and will cause compilation to skip the flow analyis
   240         //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
   241         //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
   241         //related errors, which will allow for more errors to be detected
   242         //related errors, which will allow for more errors to be detected
   242         Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
   243         Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
   243         try {
   244         try {
   244             new AssignAnalyzer() {
   245             new LambdaAssignAnalyzer(env).analyzeTree(env, that);
   245                 WriteableScope enclosedSymbols = WriteableScope.create(env.enclClass.sym);
       
   246                 @Override
       
   247                 public void visitVarDef(JCVariableDecl tree) {
       
   248                     enclosedSymbols.enter(tree.sym);
       
   249                     super.visitVarDef(tree);
       
   250                 }
       
   251                 @Override
       
   252                 protected boolean trackable(VarSymbol sym) {
       
   253                     return enclosedSymbols.includes(sym) &&
       
   254                            sym.owner.kind == MTH;
       
   255                 }
       
   256             }.analyzeTree(env, that);
       
   257             LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
   246             LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
   258             flowAnalyzer.analyzeTree(env, that, make);
   247             flowAnalyzer.analyzeTree(env, that, make);
   259             return flowAnalyzer.inferredThrownTypes;
   248             return flowAnalyzer.inferredThrownTypes;
   260         } finally {
   249         } finally {
   261             log.popDiagnosticHandler(diagHandler);
   250             log.popDiagnosticHandler(diagHandler);
  1335                 pendingExits = null;
  1324                 pendingExits = null;
  1336                 Flow.this.make = null;
  1325                 Flow.this.make = null;
  1337                 this.thrown = this.caught = null;
  1326                 this.thrown = this.caught = null;
  1338                 this.classDef = null;
  1327                 this.classDef = null;
  1339             }
  1328             }
       
  1329         }
       
  1330     }
       
  1331 
       
  1332     /**
       
  1333      * Specialized pass that performs reachability analysis on a lambda
       
  1334      */
       
  1335     class LambdaAliveAnalyzer extends AliveAnalyzer {
       
  1336 
       
  1337         boolean inLambda;
       
  1338 
       
  1339         @Override
       
  1340         public void visitReturn(JCReturn tree) {
       
  1341             //ignore lambda return expression (which might not even be attributed)
       
  1342             recordExit(new PendingExit(tree));
       
  1343         }
       
  1344 
       
  1345         @Override
       
  1346         public void visitLambda(JCLambda tree) {
       
  1347             if (inLambda || tree.getBodyKind() == BodyKind.EXPRESSION) {
       
  1348                 return;
       
  1349             }
       
  1350             inLambda = true;
       
  1351             try {
       
  1352                 super.visitLambda(tree);
       
  1353             } finally {
       
  1354                 inLambda = false;
       
  1355             }
       
  1356         }
       
  1357 
       
  1358         @Override
       
  1359         public void visitClassDef(JCClassDecl tree) {
       
  1360             //skip
       
  1361         }
       
  1362     }
       
  1363 
       
  1364     /**
       
  1365      * Specialized pass that performs DA/DU on a lambda
       
  1366      */
       
  1367     class LambdaAssignAnalyzer extends AssignAnalyzer {
       
  1368         WriteableScope enclosedSymbols;
       
  1369         boolean inLambda;
       
  1370 
       
  1371         LambdaAssignAnalyzer(Env<AttrContext> env) {
       
  1372             enclosedSymbols = WriteableScope.create(env.enclClass.sym);
       
  1373         }
       
  1374 
       
  1375         @Override
       
  1376         public void visitLambda(JCLambda tree) {
       
  1377             if (inLambda) {
       
  1378                 return;
       
  1379             }
       
  1380             inLambda = true;
       
  1381             try {
       
  1382                 super.visitLambda(tree);
       
  1383             } finally {
       
  1384                 inLambda = false;
       
  1385             }
       
  1386         }
       
  1387 
       
  1388         @Override
       
  1389         public void visitVarDef(JCVariableDecl tree) {
       
  1390             enclosedSymbols.enter(tree.sym);
       
  1391             super.visitVarDef(tree);
       
  1392         }
       
  1393         @Override
       
  1394         protected boolean trackable(VarSymbol sym) {
       
  1395             return enclosedSymbols.includes(sym) &&
       
  1396                    sym.owner.kind == MTH;
       
  1397         }
       
  1398 
       
  1399         @Override
       
  1400         public void visitClassDef(JCClassDecl tree) {
       
  1401             //skip
  1340         }
  1402         }
  1341     }
  1403     }
  1342 
  1404 
  1343     /**
  1405     /**
  1344      * Specialized pass that performs inference of thrown types for lambdas.
  1406      * Specialized pass that performs inference of thrown types for lambdas.