コード例 #1
0
  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;
  }
コード例 #2
0
  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);
  }