summaryrefslogtreecommitdiff
path: root/poc/poc02-compiling-cake/src/php-weave/abstract_weaver.class.php
diff options
context:
space:
mode:
Diffstat (limited to 'poc/poc02-compiling-cake/src/php-weave/abstract_weaver.class.php')
-rw-r--r--poc/poc02-compiling-cake/src/php-weave/abstract_weaver.class.php119
1 files changed, 119 insertions, 0 deletions
diff --git a/poc/poc02-compiling-cake/src/php-weave/abstract_weaver.class.php b/poc/poc02-compiling-cake/src/php-weave/abstract_weaver.class.php
new file mode 100644
index 0000000..86a07b1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/php-weave/abstract_weaver.class.php
@@ -0,0 +1,119 @@
+<?php
+require '../vendor/nikic/php-parser/lib/bootstrap.php';
+
+function dbg($indent, $text) {
+ for($i=0;$i<$indent;$i++) echo ".";
+ echo "$text\n";
+}
+
+abstract class AbstractWeaver {
+ protected $parser;
+ protected $nodeDumper;
+ protected $prettyPrinter;
+ protected $ast_dump_before_walk;
+ protected $ast_dump_after_walk;
+
+ public function __construct() {
+ $this->parser = new PHPParser_Parser(new PHPParser_Lexer);
+ $this->nodeDumper = new PHPParser_NodeDumper;
+ $this->prettyPrinter = new PHPParser_PrettyPrinter_Zend;
+ $this->ast_dump_before_walk="";
+ $this->ast_dump_after_walk="";
+ }
+
+ public function setASTDumpFiles($ast_dump_before_walk, $ast_dump_after_walk) {
+ // Set file to "" to prevent AST dumping
+ $this->$ast_dump_before_walk=$ast_dump_before_walk;
+ $this->$ast_dump_after_walk=$ast_dump_after_walk;
+ }
+
+ public function runAllSteps($sourcetree_rootpath, $cache_path, $result_path) {
+ try {
+ $step='detectFramework';
+ $fw_props=$this->detectFramework($sourcetree_rootpath);
+ $step='parseFrameworkConfig';
+ $fw_conf=$this->parseFrameworkConfig($fw_props);
+ $step='parseFrameworkCode';
+ $fw_extra=$this->parseFrameworkCode($fw_props, $fw_conf, $cache_path);
+ $step='parseApplicationCode';
+ $app_extra=$this->parseApplicationCode($fw_props, $fw_conf, $fw_extra, $cache_path);
+ $step='computePageList';
+ $app_pages=$this->computePageList($fw_props, $fw_conf, $fw_extra, $app_extra);
+ $step='outputMappingFile';
+ $this->outputMappingFile($app_pages, $result_path);
+ foreach ($app_pages as $page=>$page_props) {
+ $step="makePageFullAST of '$page'";
+ $page_full_ast=$this->makePageFullAST($page, $page_props, $fw_props, $fw_conf, $fw_extra, $app_extra, $cache_path);
+ $step="analysePageAST of '$page'";
+ $page_annotated_ast=$this->analysePageAST($page_full_ast, $page, $page_props, $fw_props, $fw_conf, $fw_extra, $app_extra, $cache_path);
+ $step="throwDeadCode of '$page'";
+ $this->throwDeadCode($page_annotated_ast);
+ $step="weaveCode of '$page'";
+ $out_ast=$this->weaveCode($page_annotated_ast);
+
+ $page_dest_path=$this->makeDestPath($page, $result_path);
+ $step="prettyPrint to '$page_dest_path'";
+ $this->prettyPrint($out_ast, $page_dest_path);
+ }
+
+ } catch (Exception $e) {
+ echo "Step '$step' failure : ", $e->getMessage();
+ }
+ }
+
+ public function makeDestPath($page, $result_path) {
+ return $result_path . '/' . str_replace('/', '_', $page) . ".php";
+ }
+ public function parseAndWalk($src_filepath, $traverser, $env=array(), $level=0) {
+ /* Parse a file et traverse the AST.
+ * Could be recursive if a traverser call again parseAndWalk for example when finding a include() directive
+ * The main call should be in this case :
+ * $w=new XXXWeaver;
+ * $nv=new NodeVisitor_XXX($w); // The node visitor
+ * $t=new PHPParser_NodeTraverser; $t->addVisitor($nv);
+ * w->parseAndWalk($src_mainfile, $t, array('cwd'=>dirname($src_mainfile));
+ */
+ try {
+ dbg($level,"Parsing '$src_filepath'");
+ $stmts = $this->parser->parse(file_get_contents($src_filepath));
+
+ $this->dumpAST($stmts, $src_filepath, $this->ast_dump_before_walk);
+
+ if ($traverser) {
+ dbg($level,"Transforming '$src_filepath'");
+ $stmts = $traverser->traverse($stmts);
+ $traverser=null; //Destroy
+ }
+
+ $this->dumpAST($stmts, $src_filepath, $this->ast_dump_after_walk);
+
+ } catch (PHPParser_Error $e) {
+ echo 'Parse Error: ', $e->getMessage();
+ }
+ return $stmts;
+ }
+
+ public function prettyPrint($ast, $dest_filepath) {
+ dbg(0,"Outputing '$dest_filepath'");
+ file_put_contents($dest_filepath, "<?php\n" . $this->prettyPrinter->prettyPrint($ast) . "\n?>");
+ }
+
+ public function dumpAST($ast, $ast_title, $dest_filepath) {
+ if (is_array($ast) && strlen($dest_filepath) > 0 ) {
+ dbg($level,"Dumping '$ast_title,' AST to '$dest_filepath'");
+ file_put_contents($dest_filepath, $this->nodeDumper->dump($ast));
+ }
+ }
+
+ // Framework specific code
+ abstract public function detectFramework($sourcetree_rootpath);
+ abstract public function parseFrameworkConfig($fw_props);
+ abstract public function parseFrameworkCode($fw_props, $fw_conf, $cache_path);
+ abstract public function parseApplicationCode($fw_props, $fw_conf, $fw_extra, $cache_path);
+ abstract public function computePageList($fw_props, $fw_conf, $fw_extra, $app_extra);
+ abstract public function outputMappingFile($app_pages, $result_path);
+ abstract public function makePageFullAST($page, $page_props, $fw_props, $fw_conf, $fw_extra, $app_extra, $cache_path);
+ abstract public function analysePageAST($page_full_ast, $page, $page_props, $fw_props, $fw_conf, $fw_extra, $app_extra, $cache_path);
+ abstract public function throwDeadCode(&$page_annotated_ast);
+ abstract public function weaveCode($page_annotated_ast);
+}