diff --git a/reusablecfg/src/main/jastadd/AlreadyClosedAnalysis.jrag b/reusablecfg/src/main/jastadd/AlreadyClosedAnalysis.jrag index 5767ebbada61e979ee123e9a4800074609177cb2..7bee66a47f999ad74349ee8014c35ddbc071891c 100644 --- a/reusablecfg/src/main/jastadd/AlreadyClosedAnalysis.jrag +++ b/reusablecfg/src/main/jastadd/AlreadyClosedAnalysis.jrag @@ -40,16 +40,8 @@ aspect AlreadyClosedAnalysis { /** Check if the reciever of this method access was already closed. */ syn boolean MethodAccess.alreadyClosedStream() { - // The receiver must be an effectively final local variable (or parameter). - if (name().equals("close") // Don't check for repeated close() calls. - || name().equals("toString") || name().equals("toByteArray") - || !hasPrevExpr() // Does not have a variable or parameter receiver. - || prevExpr().varDecl() == null // Receiver is not a variable/parameter. - || !(prevExpr().varDecl().isFinal() - || prevExpr().varDecl().isEffectivelyFinal()) // Receiver might have changed. - || !prevExpr().type().isCloseable()) { // Receiver is not instance of java.io.Closeable. - return false; - } + if (!isCloseableAccess()) return false; + final Variable receiver = prevExpr().varDecl(); return null != call().reverseBfs(new CfgVisitor() { @Override @@ -75,6 +67,18 @@ aspect AlreadyClosedAnalysis { }); } + /** + * Determines if a MethodAccess is an access of a Closable and its expression is an effectively final local variable (or parameter). + */ + syn boolean MethodAccess.isCloseableAccess() = !( + name().equals("close") // Don't check for repeated close() calls. + || name().equals("toString") || name().equals("toByteArray") + || !hasPrevExpr() // Does not have a variable or parameter receiver. + || prevExpr().varDecl() == null // Receiver is not a variable/parameter. + || !(prevExpr().varDecl().isFinal() + || prevExpr().varDecl().isEffectivelyFinal()) // Receiver might have changed. + || !prevExpr().type().isCloseable()); + /** Test if the CFG node is a call node with the given variable as receiver. */ syn boolean CfgNode.isCall(Variable receiver) = false; eq CfgMethodCall.isCall(Variable receiver) = methodAccess().hasReceiver(receiver);