/**
* Simple common strategies for PHP
*
* @author Eric Bouwers
*/
module php/strategy/simple
strategies
/**
* Topdown without going into
* class- or function-declerations.
*
* @param s The strategy to be applied to each term
*/
procedural-topdown(s) =
generic-procedural-topdown(s,procedural-topdown(s))
/**
* Generic version of prodecural topdown
*
* @param s1 The strategy to be applied to each term
* @param s2 The strategy to be called when going into children
*/
generic-procedural-topdown(s1,s2) =
?t; where(<not(isClassDecl)> t)
; where(<not(isFunctionDecl)> t)
; where(<not(isOldFunctionDecl)> t)
; where(<not(isInterfaceDecl)> t)
; s1
; all(s2)
generic-procedural-topdown(s1,s2) =
?t; ( <isClassDecl> t
<+ <isFunctionDecl> t
<+ <isOldFunctionDecl> t
<+ <isInterfaceDecl> t
)
;!t
strategies
/**
* Counting occurences of everything Const that is in the given strategy,
* without going into function- or class- or interface-definitions
*/
procedural-occurrences(s) =
?t; <not(isRequireOrInclude)> t
; procedural-occurrences-worker(s)
procedural-occurrences(s) =
?t{a*}; <isRequireOrInclude> t{a*}
;((env := <get-php-environment>
; inclusionId := <get-inclusion-id> t{a*}
; ast := <get-inclusion-file(|inclusionId)> env
; num := <procedural-occurrences(s)> ast
)
<+
num := 0
)
; <add> (num,<procedural-occurrences-worker(s)> t)
procedural-occurrences-worker(s) =
?t ; where(<not(isClassDecl)> t)
; where(<not(isFunctionDecl)> t)
; where(<not(isOldFunctionDecl)> t)
; where(<not(isInterfaceDecl)> t)
; <add> ( <if s then !1 else !0 end>
, <crush(!0, add, procedural-occurrences(s))>
)
procedural-occurrences-worker(s) =
?t; ( <isClassDecl> t
<+ <isFunctionDecl> t
<+ <isOldFunctionDecl> t
<+ <isInterfaceDecl> t
)
;!0
strategies
/**
* Topdown with going into inclusion. This will try to extract
* the AST from the enivironment and apply the strategy to it.
* Stores the new AST in the environment.
* Note that is tries to extract the AST. If there are no inclusions made this
* strategy will behave like topdown.
*
* Note: This strategy does _NOT_ take the '_once' into account.
*/
topdown-with-inclusion(s) =
?t; <not(isRequireOrInclude)> t
; s
; all(topdown-with-inclusion(s))
topdown-with-inclusion(s) =
?t{a*}; <isRequireOrInclude> t{a*}
;where(try( env := <get-php-environment>
; inclusionId := <get-inclusion-id> t{a*}
; ast := <get-inclusion-file(|inclusionId)> env
; log(|Debug(), "Start topdown with inclusion into id: ", inclusionId)
; ast':= <topdown-with-inclusion(s)> ast
; <add-inclusion-file(|ast',inclusionId)> env
; set-php-environment(|<id>)
; log(|Debug(), "Finish topdown with inclusion into id: ", inclusionId)
)
)
; s
; all(topdown-with-inclusion(s))
strategies
/**
* Topdown with going into inclusion. This will try to extract
* the AST from the enivironment and apply the strategy to it.
* Stores the new AST in the environment.
* This strategy will not go into class- of function-declerations.
*
* Note: This strategy does _NOT_ take the '_once' into account.
*/
procedural-topdown-with-inclusion(s) =
?t; <not(isRequireOrInclude)> t
; procedural-topdown-with-inclusion-worker(s)
procedural-topdown-with-inclusion(s) =
?t{a*}; <isRequireOrInclude> t{a*}
;where(try( env := <get-php-environment>
; inclusionId := <get-inclusion-id> t{a*}
; ast := <get-inclusion-file(|inclusionId)> env
; log(|Debug(), "Start procedural topdown with inclusion into id: ", inclusionId)
; ast':= <procedural-topdown-with-inclusion(s)> ast
; <add-inclusion-file(|ast',inclusionId)> env
; set-php-environment(|<id>)
; log(|Debug(), "Finish procedural topdown with inclusion into id: ", inclusionId)
)
)
; procedural-topdown-with-inclusion-worker(s)
procedural-topdown-with-inclusion-worker(s) =
generic-procedural-topdown(s,procedural-topdown-with-inclusion(s))
strategies
/**
* Collects all the terms that succeed a given strategy. Is compareable
* with the normal collect, but this strategy goes into included files when
* they are found.
*
* @param s The strategy to try on the terms
* @type a -> List(b)
*/
php-collect-inclusion(s) =
?t; <not(isRequireOrInclude)> t
;( ![<s> | <crush(![],union,php-collect-inclusion(s))>]
<+ crush(![],union,php-collect-inclusion(s))
)
php-collect-inclusion(s) =
?t{a*}; <isRequireOrInclude> t{a*}
; if ( env := <get-php-environment>
; inclusionId := <get-inclusion-id> t{a*}
; ast := <get-inclusion-file(|inclusionId)> env
)
then extra := <php-collect-inclusion(s)> ast //only if a file is actually included
else extra := []
end
; !t{a*} //Needs to be build to preserve current term
; ( ( ![<s> | <crush(![],union,php-collect-inclusion(s))>] ; ?normal)
<+ ( crush(![],union,php-collect-inclusion(s)) ; ?normal)
)
; <union> (extra,normal)
strategies
/**
* Different match functions for different constructors
*/
isClassDecl =
?Class(_,_,_,_)
<+ ?Class(_,_,_,_,_)
isFunctionDecl =
?FunctionDecl(_,_,_,_)
<+ ?FunctionDecl(_,_,_)
isOldFunctionDecl =
?OldFunctionDecl(_,_,_)
isInterfaceDecl =
?InterfaceDecl(_,_,_)
isRequireOrInclude=
?InternalFunction(Require(_))
<+ ?InternalFunction(RequireOnce(_))
<+ ?InternalFunction(Include(_))
<+ ?InternalFunction(IncludeOnce(_))