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

/**
 * Stratego class support for functions
 */
signature
  constructors
    PHP5Function : ClassName

strategies
    
  /**
   * Succeeds if the current term is an instance of PHP function
   */
  instanceof-PHPFunction =
    instanceof-PHP5Function

  instanceof-PHP5Function =
    classes_instanceof(|PHP5Function())

strategies

  /**
   * Constructs a new function.
   *
   * @type  _ -> Function Object
   */
  new-php5-function(|ast) =
      <classes_get-class> PHP5Function()
    ; classes_new-instance
    ; classes_set-instance-field(|"reference-ast", ast)

/**
 * Properties
 */
strategies

  /**
   * Returns the name of the function
   *
   * @type Function Object -> String
   */
  get-name = instanceof-PHP5Function;
    get-name(get-php5-function-name)
    
  get-php5-function-name =
       get-function-name
    <+ ?FunctionDecl(_,<id>,_,_)
    <+ ?FunctionDeclRef(_,<id>,_,_)
  
  /**
   * Returns the body of the function
   *
   * @type Function Object -> AST 
   */
  get-body = instanceof-PHP5Function;
    get-body(get-php5-function-body)
    
  get-php5-function-body =
       get-function-body
    <+ ?FunctionDecl(_,_,_,MethodBody(<id>))
    <+ ?FunctionDeclRef(_,_,_,MethodBody(<id>))
    
  /**
   * Returns the number of parameters of the function
   *
   * @type Function object -> Int
   */
  get-param-count = instanceof-PHP5Function;
    get-param-count(get-params)

  /**
   * Returns the parameters of the function
   *
   * @type Function object -> List(Param)
   */
  get-params = instanceof-PHP5Function; 
    get-params(php5-param-match)

  php5-param-match =
       param-match
    <+ ?FunctionDecl(_,_,<id>,_)
    <+ ?FunctionDeclRef(_,_,<id>,_)

  /** 
   * Returns the acces level of the function
   * Only usefull if the function is within a class because
   * otherwise the strategy will always return Public.
   *
   * @type Function5 Objects -> List(Type)
   */
  get-acces-level = instanceof-PHP5Function;
       oncetd(?Modifiers(_))
    <+ !Public()