public void visitClosureExpression(ClosureExpression expression) { pushState(); expression.setVariableScope(currentScope); if (expression.isParameterSpecified()) { Parameter[] parameters = expression.getParameters(); for (Parameter parameter : parameters) { parameter.setInStaticContext(currentScope.isInStaticContext()); if (parameter.hasInitialExpression()) { parameter.getInitialExpression().visit(this); } declare(parameter, expression); } } else if (expression.getParameters() != null) { Parameter var = new Parameter(ClassHelper.OBJECT_TYPE, "it"); var.setInStaticContext(currentScope.isInStaticContext()); currentScope.putDeclaredVariable(var); } super.visitClosureExpression(expression); markClosureSharedVariables(); popState(); }
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 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); }
public void visitCatchStatement(CatchStatement statement) { pushState(); Parameter p = statement.getVariable(); p.setInStaticContext(currentScope.isInStaticContext()); declare(p, statement); super.visitCatchStatement(statement); popState(); }
public void visitForLoop(ForStatement forLoop) { pushState(); forLoop.setVariableScope(currentScope); Parameter p = forLoop.getVariable(); p.setInStaticContext(currentScope.isInStaticContext()); if (p != ForStatement.FOR_LOOP_DUMMY) declare(p, forLoop); super.visitForLoop(forLoop); popState(); }
/** * a property on "this", like this.x is transformed to a direct field access, so we need to check * the static context here * * @param pe the property expression to check */ private void checkPropertyOnExplicitThis(PropertyExpression pe) { if (!currentScope.isInStaticContext()) return; Expression object = pe.getObjectExpression(); if (!(object instanceof VariableExpression)) return; VariableExpression ve = (VariableExpression) object; if (!ve.getName().equals("this")) return; String name = pe.getPropertyAsString(); if (name == null || name.equals("class")) return; Variable member = findClassMember(currentClass, name); if (member == null) return; checkVariableContextAccess(member, pe); }
private void declare(VariableExpression vex) { vex.setInStaticContext(currentScope.isInStaticContext()); declare(vex, vex); vex.setAccessedVariable(vex); }
private void pushState() { pushState(currentScope.isInStaticContext()); }