summaryrefslogtreecommitdiff
path: root/poc/poc01-parsing-includes/src/php-weave/visitors.inc.php
blob: 3f997adf13bfd341ecf2469cf055119e2d157869 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?php
/*
class NodeVisitor_NamespaceConverter extends PHPParser_NodeVisitorAbstract
{
	public function leaveNode(PHPParser_Node $node) {
		if ($node instanceof PHPParser_Node_Name) {
			return new PHPParser_Node_Name($node->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)));
		}

	}
}