module php/reflect/version5/class
imports
  php/reflect/oo/classes

/**
 * Stratego class support for class
 */
signature
  constructors
    PHP5Class : ClassName

strategies
    
  /**
   * Succeeds if the current term is an instance of PHP Class
   */
  instanceof-PHPClass =
    instanceof-PHP5Class

  instanceof-PHP5Class =
    classes_instanceof(|PHP5Class())

strategies

  /**
   * Constructs a new Class.
   *
   * @type  _ -> Class Object
   */
  new-php5-class(|ast) =
   { this :
      <classes_get-class> PHP5Class()
    ; classes_new-instance
    ; ?this
    ; classes_set-instance-field(|"reference-ast", ast)
    ; classes_set-instance-field(|"classes-table" , <new-hashtable>) 
    ; classes_set-instance-field(|"function-table", <new-hashtable>)
    ; <add-php5-function-objects(|this)> ast
    ;!this
    }
    
  add-php5-function-objects(|this) = 
     collect-all(match-php5-function-decl)
    ; map({ast, fun:
        ?ast
        ; fun := <new-php5-function(|ast)>
        ; <add-function(|fun)> this
      })

/**
 * Properties
 */
strategies
  /**
   * Returns the name of the class
   *
   * @type Class Object -> String
   */
  get-name = instanceof-PHP5Class;
    get-name(get-php5-class-name)

  get-php5-class-name =
       get-class-name
   <+ ?Class(_, <id> , _, _, _)

  /**
   * Returns the name of the class
   * it extends (if any)
   *
   * @type Class Object -> String
   */
  get-extends = instanceof-PHP5Class;
    get-extends(get-php5-extends-name)

  get-php5-extends-name =
       get-extends-name
   <+ ?Class(_, _, Some(Extends(<id>)), _, _)


  /**
   * Returns the instance-variables of this class
   *
   * @type Class Object -> List(InstanceVariable)
   */
  get-instance-variables = instanceof-PHP5Class;
    get-instance-variables(match-php5-instance-variable)

  match-php5-instance-variable =
       match-instance-variable
    <+ ?InstanceVariable(_,_)

  /**
   * Returns the class constants of this class
   *
   * @type Class Object -> List(ClassConstant)
   */
  get-class-constants = instanceof-PHP5Class;
      get-reference-ast
    ; collect-all(?ClassConstantDecl(_,_))
    
  /**
   * Returns the list of abstract functions in this class
   *
   * @type PHP5Class Object -> List(AST)
   */
   get-abstract-functions = instanceof-PHP5Class;
       get-reference-ast
     ; collect-all(match-abstract-function-decls)
     
   match-abstract-function-decls = 
        ?FunctionDecl(_,_,_,AbstractMethodBody())
     <+ ?FunctionDeclRef(_,_,_,AbstractMethodBody())
     
strategies
   /**
    * Returns the list of names of the interfaces this class implements
    */
    get-implemented-interfaces = (instanceof-PHP5Class;
      get-reference-ast
    ; ?Class(_, _ , _, Some(Implements(<id>)), _)
    )
   <+ ![]
      
  
    /**
     * Checks whether this class implements interfaces
     */
    implements-interfaces = instanceof-PHP5Class;
      get-implemented-interfaces
    ; not(?[])  


strategies
   /**
    * Returns the function object of the constructor of 
    * this class.
    *
    * @type PHP5Class Object -> Function Object
    */
    get-class-constructor = instanceof-PHP5Class;
     ((get-function(|"__construct"))
     <+
     ( ?class
     ; name := <get-name>    class
     ; <get-function(|name)> class
     )
     <+
     ( get-class-parent
     ; get-class-constructor
     ))