Standard Libraries

/** --- Variable ***

   Classes used to represent variables and their declarations.
*/

import Element

/** A variable is a field, a local variable or a parameter. */
class Variable extends @variable, Element {
  /** get this variable's type */
  /*abstract*/ Type getType() { exists(Type t | t = result) and not(0 = 0) }

  /** get an access to this variable */
  VarAccess getAnAccess() { variableBinding(result,this,_) }

  string pp() {
    result = this.getType().getName() + " " + this.getName() 
  }
}

/** A local variable declaration */
class LocalVariableDecl extends @localvar, Annotatable, Variable {
  /** get the type of the variable declared */
  Type getType() { localvars(this,_,result,_,_) }

  /** get this declaration's parent */
  Expr getParent() { localvars(this,_,_,result,_) }

  /** get the callable enclosing this declaration */
  Callable getCallable() { result = this.getParent().getEnclosingCallable() }

  /** printable representation */
  string toString() { result = this.getType().getName() + " " + this.getName() }

  /** does this local variable declaration have modifier modifier? */
  predicate hasModifier(string modifier) { hasStrModifier(this,modifier) }

  /** does this local variable declaration have no modifier at all? */
  predicate hasNoModifier() { not hasModifier(this,_,_) }

  /** get a modifier of this declaration */
  Modifier getAModifier() { this = result.getElement() }

  /** get the source location of this declaration */
  Location getLocation() { locations(result,this,_,_,_,_,_,_,_) }
}

/** A formal parameter of a callable */
class Parameter extends Element, @param, Variable {
  /** return the type of this formal parameter */
  Type getType() { params(this,_,result,_,_,_,_) }

  /** get the position of this formal parameter */
  int getPosition() { params(this,_,_,result,_,_,_) }

  /** get the callable in which this formal parameter is declared */
  Callable getCallable() { params(this,_,_,_,result,_,_) }

  /** printable representation */
  string toString() { result = Element.super.toString() }

  /** get the source declaration of this parameter */
  Parameter getSourceDeclaration() { params(this,_,_,_,_,result,_) }

  /** is this parameter the same as its source declaration? */
  predicate isSourceDeclaration() { this.getSourceDeclaration() = this }
}