private Map<Variable, VariableState> pushState() { Map<Variable, VariableState> state = new StateMap(); state.putAll(getState()); assignmentTracker.add(state); return state; }
public boolean isEffectivelyFinal(Variable v) { VariableState state = getState().get(v); return (v instanceof Parameter && state == null) || (state != null && state.isFinal()); }
@Override public void visitClosureExpression(final ClosureExpression expression) { boolean old = inAssignmentRHS; inAssignmentRHS = false; Map<Variable, VariableState> origState = new StateMap(); origState.putAll(getState()); super.visitClosureExpression(expression); cleanLocalVars(origState, getState()); inAssignmentRHS = old; }
private void visitCatchFinally(Map<Variable, VariableState> initialVarState, List<Map<Variable, VariableState>> afterTryCatchStates, CatchStatement catchStatement, Statement finallyStatement) { pushState(); // getState().clear(); getState().putAll(initialVarState); Statement code = catchStatement.getCode(); catchStatement.visit(this); visitPossiblyEmptyStatement(finallyStatement); if (code == null || !returningBlock(code)) { afterTryCatchStates.add(new HashMap<Variable, VariableState>(getState())); } popState(); }
getState().put(var, VariableState.is_var); VariableState variableState = getState().get(var); if (variableState == null) { variableState = uninitialized ? VariableState.is_uninitialized : VariableState.is_final; variableState = VariableState.is_var; getState().put(var, variableState); if ((variableState == VariableState.is_var || variableState == VariableState.is_ambiguous) && callback != null) { callback.variableNotFinal(var, expression);
@Override public void visitTryCatchFinally(final TryCatchStatement statement) { visitStatement(statement); Map<Variable, VariableState> beforeTryState = new HashMap<Variable, VariableState>(getState()); pushState(); Statement tryStatement = statement.getTryStatement(); tryStatement.visit(this); Map<Variable, VariableState> afterTryState = new HashMap<Variable, VariableState>(getState()); Statement finallyStatement = statement.getFinallyStatement(); List<Map<Variable, VariableState>> afterStates = new ArrayList<>(); afterStates.add(new HashMap<Variable, VariableState>(getState())); visitPossiblyEmptyStatement(finallyStatement); if (!returningBlock(tryStatement)) { afterStates.add(new HashMap<Variable, VariableState>(getState())); getState().putAll(corrected);
@Override public void visitIfElse(final IfStatement ifElse) { visitStatement(ifElse); ifElse.getBooleanExpression().visit(this); Map<Variable, VariableState> ifState = pushState(); ifElse.getIfBlock().visit(this); popState(); Statement elseBlock = ifElse.getElseBlock(); Map<Variable, VariableState> elseState = pushState(); visitPossiblyEmptyStatement(elseBlock); popState(); // merge if/else branches Map<Variable, VariableState> curState = getState(); Set<Variable> allVars = new HashSet<Variable>(); allVars.addAll(curState.keySet()); allVars.addAll(ifState.keySet()); allVars.addAll(elseState.keySet()); for (Variable var : allVars) { VariableState beforeValue = curState.get(var); VariableState ifValue = ifState.get(var); VariableState elseValue = elseState.get(var); // merge if and else values VariableState mergedIfElse; mergedIfElse = isFinal(ifValue) && isFinal(elseValue) ? VariableState.is_final : VariableState.is_var; if (beforeValue != null) { curState.put(var, mergedIfElse); } } }
@Override public void visitVariableExpression(final VariableExpression expression) { super.visitVariableExpression(expression); Map<Variable, VariableState> state = getState(); Variable key = expression.getAccessedVariable(); if (key == null) { fixVar(expression); key = expression.getAccessedVariable(); } if (key != null && !key.isClosureSharedVariable() && callback != null) { VariableState variableState = state.get(key); if ((inAssignmentRHS || inArgumentList) && (variableState == VariableState.is_uninitialized || variableState == VariableState.is_ambiguous)) { callback.variableNotAlwaysInitialized(expression); } } }