// Return false if the inference is illegal. Currently this only happens if the var is reassigned // to incompatible // type inside the loop. public boolean add(VariableExpression ve, ClassNode type) { if (defVars == null) defVars = FHashMap.emptyMap; if (ve.getAccessedVariable() != null) { defVars = defVars.put(ve.getAccessedVariable(), type); // dumpMap(ve); } else { boolean done = false; for (Map.Entry<Variable, ClassNode> variable : defVars.entrySet()) { if (variable.getKey().getName().equals(ve.getName())) { defVars = defVars.put(variable.getKey(), type); // dumpMap(ve); done = true; break; } } if (!done) { defVars = defVars.put(ve, type); // dumpMap(ve); } } if (parentScopeInference != null && parentScopeInference.defVars != null) { final ClassNode oldType = parentScopeInference.defVars.get(ve.getAccessedVariable()); if (oldType != null) { if (!TypeUtil.isDirectlyAssignableFrom(oldType, type)) { return false; } } } return true; }
// TODO handle local variables private void checkForFinal(final Expression expression, VariableExpression ve) { Variable v = ve.getAccessedVariable(); boolean isFinal = isFinal(v.getModifiers()); boolean isParameter = v instanceof Parameter; if (isFinal && isParameter) { addError("Cannot assign a value to final variable '" + v.getName() + "'", expression); } }
@Override public void visitVariableExpression(final VariableExpression expression) { super.visitVariableExpression(expression); if (inAssignment) { Map<Variable, VariableState> state = getState(); Variable key = expression.getAccessedVariable(); VariableState variableState = state.get(key); if (variableState == VariableState.is_uninitialized) { variableState = VariableState.is_var; state.put(key, variableState); } } }
protected Expression transformVariableExpression(VariableExpression ve) { Variable v = ve.getAccessedVariable(); if (v != null && v instanceof DynamicVariable) { Expression result = findStaticFieldOrPropAccessorImportFromModule(v.getName()); if (result != null) { setSourcePosition(result, ve); if (inAnnotation) { result = transformInlineConstants(result); } return result; } } return ve; }
@Override public void visitBlockStatement(final BlockStatement block) { Set<VariableExpression> old = declaredFinalVariables; declaredFinalVariables = new HashSet<VariableExpression>(); super.visitBlockStatement(block); if (callback != null) { Map<Variable, VariableState> state = getState(); for (VariableExpression declaredFinalVariable : declaredFinalVariables) { VariableState variableState = state.get(declaredFinalVariable.getAccessedVariable()); if (variableState == null || variableState != VariableState.is_final) { callback.variableNotAlwaysInitialized(declaredFinalVariable); } } } declaredFinalVariables = old; }
public ClassNode get(VariableExpression ve) { if (defVars == null) return ClassHelper.OBJECT_TYPE; else { final Variable accessed = ve.getAccessedVariable(); if (accessed != null) return defVars.get(accessed); else { for (Map.Entry<Variable, ClassNode> variable : defVars.entrySet()) { if (variable.getKey().getName().equals(ve.getName())) { return variable.getValue(); } } return null; } } }
private boolean doAssignmentToLocalVariable(String method, BinaryExpression binExp) { Expression left = binExp.getLeftExpression(); if (left instanceof VariableExpression) { VariableExpression ve = (VariableExpression) left; Variable v = ve.getAccessedVariable(); if (v instanceof DynamicVariable) return false; if (v instanceof PropertyExpression) return false; /* field and declaration we don't return false */ } else { return false; } evaluateBinaryExpression(method, binExp); getController().getOperandStack().dup(); getController().getCompileStack().pushLHS(true); binExp.getLeftExpression().visit(getController().getAcg()); getController().getCompileStack().popLHS(); return true; }
private void checkFinalFieldAccess(Expression expression) { if (!(expression instanceof VariableExpression) && !(expression instanceof PropertyExpression)) return; Variable v = null; if (expression instanceof VariableExpression) { VariableExpression ve = (VariableExpression) expression; v = ve.getAccessedVariable(); } else { PropertyExpression propExp = ((PropertyExpression) expression); Expression objectExpression = propExp.getObjectExpression(); if (objectExpression instanceof VariableExpression) { VariableExpression varExp = (VariableExpression) objectExpression; if (varExp.isThisExpression()) { v = currentClass.getDeclaredField(propExp.getPropertyAsString()); } } } if (v instanceof FieldNode) { FieldNode fn = (FieldNode) v; /* * if it is static final but not accessed inside a static constructor, or, * if it is an instance final but not accessed inside a instance constructor, it is an error */ boolean isFinal = fn.isFinal(); boolean isStatic = fn.isStatic(); boolean error = isFinal && ((isStatic && !inStaticConstructor) || (!isStatic && !inConstructor)); if (error) addError( "cannot modify" + (isStatic ? " static" : "") + " final field '" + fn.getName() + "' outside of " + (isStatic ? "static initialization block." : "constructor."), expression); } }