// 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); } }
private void checkVariableContextAccess(Variable v, Expression expr) { if (inPropertyExpression || v.isInStaticContext() || !currentScope.isInStaticContext()) return; String msg = v.getName() + " is declared in a dynamic context, but you tried to" + " access it from a static context."; addError(msg, expr); // declare a static variable to be able to continue the check DynamicVariable v2 = new DynamicVariable(v.getName(), currentScope.isInStaticContext()); currentScope.putDeclaredVariable(v2); }
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; }
private Variable checkVariableNameForDeclaration(String name, Expression expression) { if ("super".equals(name) || "this".equals(name)) return null; VariableScope scope = currentScope; Variable var = new DynamicVariable(name, currentScope.isInStaticContext()); // try to find a declaration of a variable while (true) { Variable var1; var1 = scope.getDeclaredVariable(var.getName()); if (var1 != null) { var = var1; break; } var1 = scope.getReferencedLocalVariable(var.getName()); if (var1 != null) { var = var1; break; } var1 = scope.getReferencedClassVariable(var.getName()); if (var1 != null) { var = var1; break; } ClassNode classScope = scope.getClassScope(); if (classScope != null) { Variable member = findClassMember(classScope, var.getName()); if (member != null) { boolean staticScope = currentScope.isInStaticContext() || isSpecialConstructorCall; boolean staticMember = member.isInStaticContext(); // We don't allow a static context (e.g. a static method) to access // a non-static variable (e.g. a non-static field). if (!(staticScope && !staticMember)) var = member; } break; } scope = scope.getParent(); } VariableScope end = scope; scope = currentScope; while (scope != end) { if (end.isClassScope() || (end.isReferencedClassVariable(name) && end.getDeclaredVariable(name) == null)) { scope.putReferencedClassVariable(var); } else { // var.setClosureSharedVariable(var.isClosureSharedVariable() || inClosure); scope.putReferencedLocalVariable(var); } scope = scope.getParent(); } return var; }
private void declare(Variable var, ASTNode expr) { String scopeType = "scope"; String variableType = "variable"; if (expr.getClass() == FieldNode.class) { scopeType = "class"; variableType = "field"; } else if (expr.getClass() == PropertyNode.class) { scopeType = "class"; variableType = "property"; } StringBuilder msg = new StringBuilder(); msg.append("The current ").append(scopeType); msg.append(" already contains a ").append(variableType); msg.append(" of the name ").append(var.getName()); if (currentScope.getDeclaredVariable(var.getName()) != null) { addError(msg.toString(), expr); return; } for (VariableScope scope = currentScope.getParent(); scope != null; scope = scope.getParent()) { // if we are in a class and no variable is declared until // now, then we can break the loop, because we are allowed // to declare a variable of the same name as a class member if (scope.getClassScope() != null) break; if (scope.getDeclaredVariable(var.getName()) != null) { // variable already declared addError(msg.toString(), expr); break; } } // declare the variable even if there was an error to allow more checks currentScope.putDeclaredVariable(var); }