module php/reflect/common/environment
imports
  php/reflect/common/function
  php/reflect/oo/classes

strategies
  /**
   * Succeeds if the current term is an instance of PHP Environment.
   * This class is iself a abstract class. So it has no instance.
   * subclasses have to implement this.
   */
  instanceof-PHPEnvironment =
    fail

strategies

  /**
   * Returns all functions.
   *
   * @type Environment Object -> List(Function Object)
   */
  get-functions = instanceof-PHPEnvironment;
    classes_get-instance-field(|"function-table")
    ; hashtable-values

  /**
   * @param Name of the function (String)
   * @type  Environment Object -> Environment Object
   */
  get-function(|name) = instanceof-PHPEnvironment;
    classes_get-instance-field(|"function-table")
    ; hashtable-get(|name)

  /**
   * @param Function Object
   * @type Environment Object -> Environment Object
   */
  add-function(|function) = instanceof-PHPEnvironment;
    where(
      classes_get-instance-field(|"function-table")
      ; where(name := <get-name> function)
      ; hashtable-put(|<strip-annos> name, function)
    )

strategies
  /**
   * Returns all classes.
   *
   * @type Environment Object -> List(Class Object)
   */
  get-classes = instanceof-PHPEnvironment;
    classes_get-instance-field(|"classes-table")
    ; hashtable-values

  /**
   * @param Name of the class (String)
   * @type  Environment Object -> Environment Object
   */
  get-class(|name) = instanceof-PHPEnvironment;
    classes_get-instance-field(|"classes-table")
    ; hashtable-get(|name)

  /**
   * @param Class Object
   * @type Environment Object -> Environment Object
   */
  add-class(|class) = instanceof-PHPEnvironment;
    where(
       classes_get-instance-field(|"classes-table")
      ; where(name := <get-name> class)
      ; hashtable-put(|<strip-annos> name, class)
    )

strategies
  /**
   * Returns the main AST. This is the initial
   * file the environment is created on.
   *
   * @type _ -> Environment Object
   */
   get-main-ast = instanceof-PHPEnvironment;
    classes_get-instance-field(|"files-table")
    ; hashtable-get(|"main-file")

  /**
   * Sets the main AST-file. This should be the initial
   * file the environment is created on.
   *
   * @param AST
   * @type Environment Object -> Environment Object
   */
   set-main-ast(|ast) = instanceof-PHPEnvironment;
    where(
       classes_get-instance-field(|"files-table")
      ; hashtable-put(|"main-file", ast)
      ; get-input-path ; add-inclusion-status //set status of main input
    )

  /**
   * Adds a AST of an included file to the environment.
   * The file is stored with the inclusionid. This id should be 
   * used to get the AST.
   *
   * @param AST
   * @param iid The id of the inclusion
   * @type Environment Object -> Environment Object
   */
    add-inclusion-file(|ast,iid) = instanceof-PHPEnvironment; ?env;
      where(
          classes_get-instance-field(|"files-table")
        ; hashtable-put(|iid, ast)
        ; <?Inclusionid(path,_)> iid
        ; <add-inclusion-filename(|path,iid)> env
     )

   /**
    * Adds a file-name to the files that are included. This can be used 
    * to question the environment which files are already included.
    *
    * @param path String The pathname to add
    * @param iid  InclusionId The ID to store
    * @type Environment Object -> Environment Object
    */
   add-inclusion-filename(|path,iid) = instanceof-PHPEnvironment; ?env;
     where(
          !env
        ; classes_get-instance-field(|"filenames-table")
        ; hashtable-put(|path, iid)
        ; <add-inclusion-status> path
      )

   /**
    * Checks wheter or not the given path is already included by this environment.
    *
    * @param String
    * @type Environment Object -> Inclusionid
    */
    is-file-included(|path) = instanceof-PHPEnvironment;
        where(<get-inclusion-status> path ; ?DefIncluded())
      ; classes_get-instance-field(|"filenames-table")
      ; hashtable-get(|path)

   /**
    * Checks wheter or not the given path is maybe included by this environment.
    * 
    * @param String
    * @type Environment Object -> Inclusionid
    */
    is-file-maybe-included(|path) = instanceof-PHPEnvironment;
        where(<get-inclusion-status> path ; ?MaybeIncluded())
      ; classes_get-instance-field(|"filenames-table")
      ; hashtable-get(|path)

  /**
   * Gets a AST of an included file from the environment.
   *
   * @param iid The id of the inclusion
   * @type Environment Object -> AST
   */
    get-inclusion-file(|iid) = instanceof-PHPEnvironment;
          classes_get-instance-field(|"files-table")
        ; hashtable-get(|iid)
        
  /**
   * Get all Id's of the included AST's.
   *
   * @type Environment Object -> List((path,desc))
   */
    get-all-inclusion-ids = instanceof-PHPEnvironment;
          classes_get-instance-field(|"files-table")
        ; hashtable-keys