blob: 5171d5a447f848663a2e4a8281aafe82b657250b [file] [log] [blame]
package edu.uci.ics.asterix.aql.parser;
import java.util.Stack;
import edu.uci.ics.asterix.aql.context.Scope;
import edu.uci.ics.asterix.aql.expression.Identifier;
import edu.uci.ics.asterix.om.functions.AsterixFunction;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.Counter;
public abstract class ScopeChecker {
protected Counter varCounter = new Counter(-1);
protected Stack<Scope> scopeStack = new Stack<Scope>();
protected Stack<Scope> forbiddenScopeStack = new Stack<Scope>();
// Forbidden scopes are used to disallow, in a limit clause, variables
// having the same name as a variable defined by the FLWOR in which that
// limit clause appears.
/**
* Create a new scope, using the top scope in scopeStack as parent scope
*
* @param scopeStack
* @return new scope
*/
public final Scope createNewScope() {
Scope scope = new Scope(this, scopeStack.peek());// top one as parent
scopeStack.push(scope);
return scope;
}
/**
* Extend the current scope
*
* @param scopeStack
* @return
*/
public final Scope extendCurrentScope() {
return extendCurrentScope(false);
}
public final Scope extendCurrentScope(boolean maskParentScope) {
Scope scope = extendCurrentScopeNoPush(maskParentScope);
scopeStack.pop();
scopeStack.push(scope);
return scope;
}
public final Scope extendCurrentScopeNoPush(boolean maskParentScope) {
Scope scope = scopeStack.peek();
scope = new Scope(this, scope, maskParentScope);
return scope;
}
public final void replaceCurrentScope(Scope scope) {
scopeStack.pop();
scopeStack.push(scope);
}
/**
* Remove current scope
*
* @return
*/
public final Scope removeCurrentScope() {
return scopeStack.pop();
}
/**
* get current scope
*
* @return
*/
public final Scope getCurrentScope() {
return scopeStack.peek();
}
/**
* find symbol in the scope
*
* @return identifier
*/
public final Identifier lookupSymbol(String name) {
if (name != null) {
return getCurrentScope().findSymbol(name);
} else {
return null;
}
}
/**
* find FunctionSignature in the scope
*
* @return functionDescriptor
*/
public final AsterixFunction lookupFunctionSignature(String name, int arity) {
if (name != null) {
return getCurrentScope().findFunctionSignature(name, arity);
} else {
return null;
}
}
public final int getVarCounter() {
return varCounter.get();
}
public final void setVarCounter(Counter varCounter) {
this.varCounter = varCounter;
}
public final void incVarCounter() {
varCounter.inc();
}
public final void pushForbiddenScope(Scope s) {
forbiddenScopeStack.push(s);
}
public final void popForbiddenScope() {
forbiddenScopeStack.pop();
}
public final boolean isInForbiddenScopes(String ident) {
for (Scope s : forbiddenScopeStack) {
if (s.findLocalSymbol(ident) != null) {
return true;
}
}
return false;
}
public static final String removeQuotesAndEscapes(String s) {
char q = s.charAt(0); // simple or double quote
String stripped = s.substring(1, s.length() - 1);
return stripped.replaceAll("\\\\" + q, "\\" + q);
}
}