From 1133e9dadec074e41ae4e08fc6c97cf74b7539fe Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Wed, 1 Aug 2012 08:34:26 +0000 Subject: Les tests ne sont pas des tests (au sens de tests unitaires) de l'outil (non encore existant) . Ce sont des essais des idées germantes, des Proof-of-Concept (PoC). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///var/svn/2012-php-weave/trunk@3 d972a294-176a-4cf9-8ea1-fcd5b0c30f5c --- poc/poc01-parsing-includes/src/composer.json | 6 ++ poc/poc01-parsing-includes/src/get_deps.sh | 2 + poc/poc01-parsing-includes/src/php-weave/main.php | 64 +++++++++++++++ .../src/php-weave/to_parse.php | 5 ++ .../src/php-weave/visitors.inc.php | 91 ++++++++++++++++++++++ 5 files changed, 168 insertions(+) create mode 100644 poc/poc01-parsing-includes/src/composer.json create mode 100755 poc/poc01-parsing-includes/src/get_deps.sh create mode 100644 poc/poc01-parsing-includes/src/php-weave/main.php create mode 100644 poc/poc01-parsing-includes/src/php-weave/to_parse.php create mode 100644 poc/poc01-parsing-includes/src/php-weave/visitors.inc.php (limited to 'poc/poc01-parsing-includes') diff --git a/poc/poc01-parsing-includes/src/composer.json b/poc/poc01-parsing-includes/src/composer.json new file mode 100644 index 0000000..a366739 --- /dev/null +++ b/poc/poc01-parsing-includes/src/composer.json @@ -0,0 +1,6 @@ +{ + "require": { + "nikic/php-parser": "0.9.2" + } +} + diff --git a/poc/poc01-parsing-includes/src/get_deps.sh b/poc/poc01-parsing-includes/src/get_deps.sh new file mode 100755 index 0000000..67c84c3 --- /dev/null +++ b/poc/poc01-parsing-includes/src/get_deps.sh @@ -0,0 +1,2 @@ +#!/bin/sh +php ../../../composer.phar install diff --git a/poc/poc01-parsing-includes/src/php-weave/main.php b/poc/poc01-parsing-includes/src/php-weave/main.php new file mode 100644 index 0000000..2a4df55 --- /dev/null +++ b/poc/poc01-parsing-includes/src/php-weave/main.php @@ -0,0 +1,64 @@ +parse(file_get_contents($src_filepath)); + + if (strlen($stmts1_filepath) > 0 ) { + dbg($level,"Dumping1 '$src_filepath' AST to '$stmts1_filepath'"); + file_put_contents($stmts1_filepath, $nodeDumper->dump($stmts)); + } + + dbg($level,"Transforming '$src_filepath'"); + $traverser = new PHPParser_NodeTraverser; +/* + $traverser->addVisitor(new PHPParser_NodeVisitor_NameResolver); + $traverser->addVisitor(new NodeVisitor_NamespaceConverter); +*/ + // FIXME : getcwd is quick and dirty here + $traverser->addVisitor(new NodeVisitor_PreprocessInclude($level, getcwd(), $src_filepath)); + $stmts = $traverser->traverse($stmts); + $traverser=null; //Destroy + + if (strlen($stmts2_filepath) > 0) { + dbg($level,"Dumping2 '$src_filepath' AST to '$stmts2_filepath'"); + file_put_contents($stmts2_filepath, $nodeDumper->dump($stmts)); + } + + } catch (PHPParser_Error $e) { + echo 'Parse Error: ', $e->getMessage(); + } + return $stmts; +} + + +// Main +$src_filepath = "./main.php"; +#$src_filepath = "./to_parse.php"; +$stmts1_filepath = "out/stmts1.ast"; +$stmts2_filepath = "out/stmts2.ast"; +$dest_filepath = "out/result.php"; + +$parser = new PHPParser_Parser(new PHPParser_Lexer); +$nodeDumper = new PHPParser_NodeDumper; + +$level=0; +$stmts=recursive_parse($src_filepath, $stmts1_filepath, $stmts2_filepath); + +dbg(0,"Outputing '$dest_filepath'"); +$prettyPrinter = new PHPParser_PrettyPrinter_Zend; +file_put_contents($dest_filepath, "prettyPrint($stmts) . "\n?>"); + +?> diff --git a/poc/poc01-parsing-includes/src/php-weave/to_parse.php b/poc/poc01-parsing-includes/src/php-weave/to_parse.php new file mode 100644 index 0000000..7b953d5 --- /dev/null +++ b/poc/poc01-parsing-includes/src/php-weave/to_parse.php @@ -0,0 +1,5 @@ + diff --git a/poc/poc01-parsing-includes/src/php-weave/visitors.inc.php b/poc/poc01-parsing-includes/src/php-weave/visitors.inc.php new file mode 100644 index 0000000..3f997ad --- /dev/null +++ b/poc/poc01-parsing-includes/src/php-weave/visitors.inc.php @@ -0,0 +1,91 @@ +toString('_')); + } elseif ($node instanceof PHPParser_Node_Stmt_Class + || $node instanceof PHPParser_Node_Stmt_Interface + || $node instanceof PHPParser_Node_Stmt_Function) { + $node->name = $node->namespacedName->toString('_'); + } elseif ($node instanceof PHPParser_Node_Stmt_Const) { + foreach ($node->consts as $const) { + $const->name = $const->namespacedName->toString('_'); + } + } elseif ($node instanceof PHPParser_Node_Stmt_Namespace) { + // returning an array merges is into the parent array + return $node->stmts; + } elseif ($node instanceof PHPParser_Node_Stmt_Use) { + // returning false removed the node altogether + return false; + } + } +} +*/ + +class NodeVisitor_PreprocessInclude extends PHPParser_NodeVisitorAbstract { + protected $level; + protected $cwd; + protected $filepath; + protected $prettyPrinter; + + public function __construct($level, $cwd, $filepath) { + $this->level=$level; + $this->cwd=$cwd; + $this->filepath=$filepath; + $this->prettyPrinter = new PHPParser_PrettyPrinter_Zend; + } + + protected function resolveIncludePath($node) { + //FIXME : Quick and dirty + // no classpath checks... + // no check if compound value like "dirname(__FILE__) . '/PHPParser/Autoloader.php'" + return $node->expr->value; + } + + public function enterNode(PHPParser_Node $node) { + if ($node instanceof PHPParser_Node_Expr_Include) { + // Already processed, go out (occurs if an unresolved include has left as is in the previous recursion level) + if (is_array($node->attributes) && array_key_exists('NodeVisitor_PreprocessInclude', $node->attributes)) return $node; + + switch($node->type) { + case PHPParser_Node_Expr_Include::TYPE_INCLUDE: + case PHPParser_Node_Expr_Include::TYPE_REQUIRE: + $once=0; + break; + case PHPParser_Node_Expr_Include::TYPE_INCLUDE_ONCE: + case PHPParser_Node_Expr_Include::TYPE_REQUIRE_ONCE: + $once=1; + echo "TODO : include_once or require_once\n"; + break; + default: + echo "FIXME : BUG NodeVisitor_PreprocessInclude::enterNode !!\n"; + return $node; + } + + $path=$this->resolveIncludePath($node); + + //FIXME : No infinite recursion check like test.php contains include('./test.php'); + // Preprocess include if readable + $comment_suffix=" */"; + if ( ($this->level < 3) && is_readable($path)) { + $comment_prefix="/* "; + //FIXME : use a closure or sort of here (dependancy injection) + //$stmts=recursive_parse($path, "out/rec.out1", "out/rec.out2", $this->level+1); + $stmts=recursive_parse($path, "", "", $this->level+1); + } else { + $comment_prefix="/* UNRESOLVED : "; + $node->attributes['NodeVisitor_PreprocessInclude']='unresolved'; + $stmts=array($node); // Caution : can cause infinite loop (will be tried at the next step) + } + + $comment= new PHPParser_Comment($comment_prefix . $this->prettyPrinter->prettyPrint(array($node)) . $comment_suffix); + + // FIXME : Get out this if() that is a trick for not returning here an array instead of a node + return new PHPParser_Node_Stmt_If(new PHPParser_Node_Scalar_LNumber(1),array('stmts'=>$stmts),array('comments'=>array($comment))); + } + + } +} + -- cgit v1.2.3