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());
 }