26 //todo: one might eliminate uninits.andSets when monotonic |
26 //todo: one might eliminate uninits.andSets when monotonic |
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 import java.util.Map; |
|
32 import java.util.LinkedHashMap; |
31 |
33 |
32 import com.sun.tools.javac.code.*; |
34 import com.sun.tools.javac.code.*; |
33 import com.sun.tools.javac.tree.*; |
35 import com.sun.tools.javac.tree.*; |
34 import com.sun.tools.javac.util.*; |
36 import com.sun.tools.javac.util.*; |
35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
961 } |
967 } |
962 |
968 |
963 public void visitTry(JCTry tree) { |
969 public void visitTry(JCTry tree) { |
964 List<Type> caughtPrev = caught; |
970 List<Type> caughtPrev = caught; |
965 List<Type> thrownPrev = thrown; |
971 List<Type> thrownPrev = thrown; |
|
972 Map<VarSymbol, JCVariableDecl> unrefdResourcesPrev = unrefdResources; |
966 thrown = List.nil(); |
973 thrown = List.nil(); |
967 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { |
974 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { |
968 List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ? |
975 List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ? |
969 ((JCTypeDisjoint)l.head.param.vartype).components : |
976 ((JCTypeDisjoint)l.head.param.vartype).components : |
970 List.of(l.head.param.vartype); |
977 List.of(l.head.param.vartype); |
975 Bits uninitsTryPrev = uninitsTry; |
982 Bits uninitsTryPrev = uninitsTry; |
976 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
983 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
977 pendingExits = new ListBuffer<PendingExit>(); |
984 pendingExits = new ListBuffer<PendingExit>(); |
978 Bits initsTry = inits.dup(); |
985 Bits initsTry = inits.dup(); |
979 uninitsTry = uninits.dup(); |
986 uninitsTry = uninits.dup(); |
|
987 unrefdResources = new LinkedHashMap<VarSymbol, JCVariableDecl>(); |
|
988 for (JCTree resource : tree.resources) { |
|
989 if (resource instanceof JCVariableDecl) { |
|
990 JCVariableDecl vdecl = (JCVariableDecl) resource; |
|
991 visitVarDef(vdecl); |
|
992 unrefdResources.put(vdecl.sym, vdecl); |
|
993 } else if (resource instanceof JCExpression) { |
|
994 scanExpr((JCExpression) resource); |
|
995 } else { |
|
996 throw new AssertionError(tree); // parser error |
|
997 } |
|
998 } |
|
999 for (JCTree resource : tree.resources) { |
|
1000 MethodSymbol topCloseMethod = (MethodSymbol)syms.autoCloseableType.tsym.members().lookup(names.close).sym; |
|
1001 List<Type> closeableSupertypes = resource.type.isCompound() ? |
|
1002 types.interfaces(resource.type).prepend(types.supertype(resource.type)) : |
|
1003 List.of(resource.type); |
|
1004 for (Type sup : closeableSupertypes) { |
|
1005 if (types.asSuper(sup, syms.autoCloseableType.tsym) != null) { |
|
1006 MethodSymbol closeMethod = types.implementation(topCloseMethod, sup.tsym, types, true); |
|
1007 for (Type t : closeMethod.getThrownTypes()) { |
|
1008 markThrown(tree.body, t); |
|
1009 } |
|
1010 } |
|
1011 } |
|
1012 } |
980 scanStat(tree.body); |
1013 scanStat(tree.body); |
981 List<Type> thrownInTry = thrown; |
1014 List<Type> thrownInTry = thrown; |
982 thrown = thrownPrev; |
1015 thrown = thrownPrev; |
983 caught = caughtPrev; |
1016 caught = caughtPrev; |
984 boolean aliveEnd = alive; |
1017 boolean aliveEnd = alive; |
985 uninitsTry.andSet(uninits); |
1018 uninitsTry.andSet(uninits); |
986 Bits initsEnd = inits; |
1019 Bits initsEnd = inits; |
987 Bits uninitsEnd = uninits; |
1020 Bits uninitsEnd = uninits; |
988 int nextadrCatch = nextadr; |
1021 int nextadrCatch = nextadr; |
|
1022 |
|
1023 if (!unrefdResources.isEmpty() && |
|
1024 lint.isEnabled(Lint.LintCategory.ARM)) { |
|
1025 for (Map.Entry<VarSymbol, JCVariableDecl> e : unrefdResources.entrySet()) { |
|
1026 log.warning(e.getValue().pos(), |
|
1027 "automatic.resource.not.referenced", e.getKey()); |
|
1028 } |
|
1029 } |
989 |
1030 |
990 List<Type> caughtInTry = List.nil(); |
1031 List<Type> caughtInTry = List.nil(); |
991 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { |
1032 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { |
992 alive = true; |
1033 alive = true; |
993 JCVariableDecl param = l.head.param; |
1034 JCVariableDecl param = l.head.param; |
1068 ListBuffer<PendingExit> exits = pendingExits; |
1109 ListBuffer<PendingExit> exits = pendingExits; |
1069 pendingExits = prevPendingExits; |
1110 pendingExits = prevPendingExits; |
1070 while (exits.nonEmpty()) pendingExits.append(exits.next()); |
1111 while (exits.nonEmpty()) pendingExits.append(exits.next()); |
1071 } |
1112 } |
1072 uninitsTry.andSet(uninitsTryPrev).andSet(uninits); |
1113 uninitsTry.andSet(uninitsTryPrev).andSet(uninits); |
|
1114 unrefdResources = unrefdResourcesPrev; |
1073 } |
1115 } |
1074 |
1116 |
1075 public void visitConditional(JCConditional tree) { |
1117 public void visitConditional(JCConditional tree) { |
1076 scanCond(tree.cond); |
1118 scanCond(tree.cond); |
1077 Bits initsBeforeElse = initsWhenFalse; |
1119 Bits initsBeforeElse = initsWhenFalse; |
1291 // annotations don't get scanned |
1333 // annotations don't get scanned |
1292 tree.underlyingType.accept(this); |
1334 tree.underlyingType.accept(this); |
1293 } |
1335 } |
1294 |
1336 |
1295 public void visitIdent(JCIdent tree) { |
1337 public void visitIdent(JCIdent tree) { |
1296 if (tree.sym.kind == VAR) |
1338 if (tree.sym.kind == VAR) { |
1297 checkInit(tree.pos(), (VarSymbol)tree.sym); |
1339 checkInit(tree.pos(), (VarSymbol)tree.sym); |
|
1340 referenced(tree.sym); |
|
1341 } |
|
1342 } |
|
1343 |
|
1344 void referenced(Symbol sym) { |
|
1345 if (unrefdResources != null && unrefdResources.containsKey(sym)) { |
|
1346 unrefdResources.remove(sym); |
|
1347 } |
1298 } |
1348 } |
1299 |
1349 |
1300 public void visitTypeCast(JCTypeCast tree) { |
1350 public void visitTypeCast(JCTypeCast tree) { |
1301 super.visitTypeCast(tree); |
1351 super.visitTypeCast(tree); |
1302 if (!tree.type.isErroneous() |
1352 if (!tree.type.isErroneous() |