Exemple #1
0
 /**
  * provides and registers a fresh variable in the current scope. It takes parent scopes into
  * account and only reuses names of synthetic variables from parent scopes. Pseudo scopes are
  * treated as if they were part of their parent scope.
  */
 @NonNull
 public String declareVariable(
     @NonNull Object key, @NonNull String proposedName, boolean synthetic) {
   if (scopes.isEmpty()) throw new IllegalArgumentException("No scope has been opened yet.");
   Scope currentScope = scopes.peek();
   if (get(proposedName) == null) {
     currentScope.addVariable(proposedName, synthetic, key);
     return proposedName;
   }
   final Set<String> names = newHashSet();
   boolean scopeClosed = false;
   // add only the non-synthetic variables, since they could be referenced from nested scopes.
   for (Scope scope : reverse(newArrayList(scopes))) {
     for (Variable variable : scope.variables()) {
       if (!scopeClosed || !variable.synthetic) names.add(variable.name);
     }
     scopeClosed = scopeClosed || !scope.pseudoScope;
     // if we left the current scope (incl. pseudo scopes) and the variable is not synthetic, we
     // can stop collecting names.
     // Overriding names from outside is ok in that case.
     if (scopeClosed && !synthetic) break;
   }
   String newName = findNewName(names, proposedName);
   currentScope.addVariable(newName, synthetic, key);
   return newName;
 }
Exemple #2
0
  @Nullable
  public String getName(Object referenced) {
    if (referenced == null) throw new NullPointerException("referenced");
    if (scopes.isEmpty()) return null;

    int size = scopes.size();
    int i = size - 1;
    while (i >= 0) {
      Scope currentScope = scopes.get(i--);
      for (Variable v : currentScope.variables()) {
        if (v.referenced.equals(referenced)) return v.name;
      }
    }
    return null;
  }