Esempio n. 1
0
  /**
   * Fills in all used scopes of the given one.
   *
   * @param curr current scope
   * @return IDs of all directly reachable scopes
   * @throws QueryException if a variable directly calls itself
   */
  private int[] neighbors(final Scope curr) throws QueryException {
    final IntList adj = new IntList(0);
    final boolean ok =
        curr.visit(
            new ASTVisitor() {
              @Override
              public boolean staticVar(final StaticVar var) {
                return var != curr && neighbor(var);
              }

              @Override
              public boolean staticFuncCall(final StaticFuncCall call) {
                return neighbor(call.func());
              }

              @Override
              public boolean inlineFunc(final Scope sub) {
                return sub.visit(this);
              }

              @Override
              public boolean funcItem(final FuncItem func) {
                return neighbor(func);
              }

              /**
               * Adds a neighbor of the currently inspected scope.
               *
               * @param scp the neighbor
               * @return {@code true} for convenience
               */
              private boolean neighbor(final Scope scp) {
                final int old = id(scp), id = old == -1 ? add(scp) : old;
                if (old == -1 || !adj.contains(id)) adj.add(id);
                return true;
              }
            });

    if (!ok) {
      final StaticVar var = (StaticVar) curr;
      throw CIRCREF_X.get(var.info, "$" + var.name);
    }
    return adj.finish();
  }