/** * 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(_))