PageRenderTime 58ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/ezcomponents/Template/src/parsers/ast_to_ast/implementations/ast_walker.php

http://hppg.googlecode.com/
PHP | 733 lines | 314 code | 91 blank | 328 comment | 9 complexity | 4df82fe809b6e90c508f2dedce4c8244 MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause
  1. <?php
  2. /**
  3. * File containing the ezcTemplateAstWalker
  4. *
  5. * @package Template
  6. * @version 1.4.2
  7. * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
  8. * @license http://ez.no/licenses/new_bsd New BSD License
  9. * @access private
  10. */
  11. /**
  12. * The entire AST tree, doing nothing.
  13. *
  14. * @package Template
  15. * @version 1.4.2
  16. * @access private
  17. */
  18. class ezcTemplateAstWalker implements ezcTemplateAstNodeVisitor
  19. {
  20. /**
  21. * A stack that keeps the path of nodes to the current position. The first element (0) contains the last
  22. * executed node. The second element, the second last node, etc.
  23. *
  24. * @var array(ezcTemplateAstNode)
  25. */
  26. public $nodePath = array();
  27. /**
  28. * The amount of statements in the last, second last, etc. position / level.
  29. *
  30. * @var array(int)
  31. */
  32. public $statements = array();
  33. /**
  34. * The offset of the statements. Default it's 0. When a statement is inserted, the offset should also increase.
  35. *
  36. * @var array(int)
  37. */
  38. public $offset = array();
  39. /**
  40. * Constructs a new ezcTemplateAstWalker
  41. */
  42. public function __construct( )
  43. {
  44. }
  45. /**
  46. * Destructor
  47. */
  48. public function __destruct()
  49. {
  50. }
  51. /**
  52. * visitLiteralAstNode
  53. *
  54. * @param ezcTemplateLiteralAstNode $type
  55. * @return void
  56. */
  57. public function visitLiteralAstNode( ezcTemplateLiteralAstNode $type )
  58. {
  59. }
  60. /**
  61. * visitLiteralArrayAstNode
  62. *
  63. * @param ezcTemplateLiteralArrayAstNode $type
  64. * @return void
  65. */
  66. public function visitLiteralArrayAstNode( ezcTemplateLiteralArrayAstNode $type )
  67. {
  68. }
  69. /**
  70. * visitOutputAstNode
  71. *
  72. * @param ezcTemplateOutputAstNode $type
  73. * @return void
  74. */
  75. public function visitOutputAstNode( ezcTemplateOutputAstNode $type )
  76. {
  77. array_unshift( $this->nodePath, $type );
  78. $this->acceptAndUpdate( $type->expression );
  79. array_shift( $this->nodePath );
  80. }
  81. /**
  82. * visitTypeCastAstNode
  83. *
  84. * @param ezcTemplateTypeCastAstNode $node
  85. * @return void
  86. */
  87. public function visitTypeCastAstNode( ezcTemplateTypeCastAstNode $node )
  88. {
  89. array_unshift( $this->nodePath, $node );
  90. $this->acceptAndUpdate( $node->value );
  91. array_shift( $this->nodePath );
  92. }
  93. /**
  94. * visitConstantAstNode
  95. *
  96. * @param ezcTemplateConstantAstNode $type
  97. * @return void
  98. */
  99. public function visitConstantAstNode( ezcTemplateConstantAstNode $type )
  100. {
  101. }
  102. /**
  103. * visitEolCommentAstNode
  104. *
  105. * @param ezcTemplateEolCommentAstNode $comment
  106. * @return void
  107. */
  108. public function visitEolCommentAstNode( ezcTemplateEolCommentAstNode $comment )
  109. {
  110. }
  111. /**
  112. * visitBlockCommentAstNode
  113. *
  114. * @param ezcTemplateBlockCommentAstNode $comment
  115. * @return void
  116. */
  117. public function visitBlockCommentAstNode( ezcTemplateBlockCommentAstNode $comment )
  118. {
  119. }
  120. /**
  121. * visitVariableAstNode
  122. *
  123. * @param ezcTemplateVariableAstNode $var
  124. * @return void
  125. */
  126. public function visitVariableAstNode( ezcTemplateVariableAstNode $var )
  127. {
  128. }
  129. /**
  130. * visitDynamicVariableAstNode
  131. *
  132. * @param ezcTemplateDynamicVariableAstNode $var
  133. * @return void
  134. */
  135. public function visitDynamicVariableAstNode( ezcTemplateDynamicVariableAstNode $var )
  136. {
  137. array_unshift( $this->nodePath, $var );
  138. $this->acceptAndUpdate( $var->nameExpression );
  139. array_shift( $this->nodePath );
  140. }
  141. /**
  142. * visitDynamicStringAstNode
  143. *
  144. * @param ezcTemplateDynamicStringAstNode $dynamic
  145. * @return void
  146. */
  147. public function visitDynamicStringAstNode( ezcTemplateDynamicStringAstNode $dynamic )
  148. {
  149. throw new ezcTemplateInternalException( "TODO: dynamicstring Ast node , tree walker" );
  150. array_unshift( $this->nodePath, $dynamic );
  151. foreach ( $parameters as $parameter )
  152. {
  153. if ( !$parameter instanceof ezcTemplateLiteralAstNode )
  154. {
  155. $this->acceptAndUpdate( $parameter );
  156. }
  157. }
  158. array_shift( $this->nodePath );
  159. }
  160. /**
  161. * visitArrayFetchOperatorAstNode
  162. *
  163. * @param ezcTemplateArrayFetchOperatorAstNode $operator
  164. * @return void
  165. */
  166. public function visitArrayFetchOperatorAstNode( ezcTemplateArrayFetchOperatorAstNode $operator )
  167. {
  168. array_unshift( $this->nodePath, $operator );
  169. $parameters = $operator->getParameters();
  170. $count = count( $parameters );
  171. for ( $i = 0; $i < $count; ++$i )
  172. {
  173. $this->acceptAndUpdate( $operator->parameters[$i] );
  174. }
  175. array_shift( $this->nodePath );
  176. }
  177. /**
  178. * visitUnaryOperatorAstNode
  179. *
  180. * @param ezcTemplateOperatorAstNode $operator
  181. * @return void
  182. */
  183. public function visitUnaryOperatorAstNode( ezcTemplateOperatorAstNode $operator )
  184. {
  185. $parameters = $operator->getParameters();
  186. if ( count( $parameters ) < $operator->minParameterCount )
  187. {
  188. throw new ezcTemplateInternalException( "The operator <" . get_class( $operator ) . " contains only " . count( $parameters ) . " parameters but should at least have {$operator->minParameterCount} parameters." );
  189. }
  190. array_unshift( $this->nodePath, $operator );
  191. $this->acceptAndUpdate( $operator->parameters[0] );
  192. array_shift( $this->nodePath );
  193. }
  194. /**
  195. * visitBinaryOperatorAstNode
  196. *
  197. * @param ezcTemplateOperatorAstNode $operator
  198. * @return void
  199. */
  200. public function visitBinaryOperatorAstNode( ezcTemplateOperatorAstNode $operator )
  201. {
  202. $parameters = $operator->getParameters();
  203. if ( count( $parameters ) < $operator->minParameterCount )
  204. {
  205. throw new ezcTemplateInternalException( "The operator <" . get_class( $operator ) . " contains only " . count( $parameters ) . " parameters but should at least have {$operator->minParameterCount} parameters." );
  206. }
  207. array_unshift( $this->nodePath, $operator );
  208. $this->acceptAndUpdate( $operator->parameters[0] );
  209. $this->acceptAndUpdate( $operator->parameters[1] );
  210. array_shift( $this->nodePath );
  211. }
  212. /**
  213. * visitFunctionCallAstNode
  214. *
  215. * @param ezcTemplateFunctionCallAstNode $fcall
  216. * @return void
  217. */
  218. public function visitFunctionCallAstNode( ezcTemplateFunctionCallAstNode $fcall )
  219. {
  220. array_unshift( $this->nodePath, $fcall );
  221. foreach ( $fcall->getParameters() as $i => $parameter )
  222. {
  223. $this->acceptAndUpdate( $fcall->parameters[$i] );
  224. }
  225. array_shift( $this->nodePath );
  226. }
  227. /**
  228. * visitBodyAstNode
  229. *
  230. * @param ezcTemplateBodyAstNode $body
  231. * @return void
  232. */
  233. public function visitBodyAstNode( ezcTemplateBodyAstNode $body )
  234. {
  235. array_unshift( $this->nodePath, $body );
  236. array_unshift( $this->statements, 0);
  237. array_unshift( $this->offset, 0);
  238. $b = clone( $body );
  239. for( $i = 0; $i < sizeof( $b->statements ); $i++)
  240. {
  241. $this->statements[0] = $i;
  242. $this->acceptAndUpdate( $b->statements[$i] );
  243. }
  244. $body = $b;
  245. array_shift( $this->offset );
  246. array_shift( $this->statements );
  247. array_shift( $this->nodePath );
  248. }
  249. /**
  250. * visitRootAstNode
  251. *
  252. * @param ezcTemplateRootAstNode $body
  253. * @return void
  254. */
  255. public function visitRootAstNode( ezcTemplateRootAstNode &$body )
  256. {
  257. array_unshift( $this->nodePath, $body );
  258. array_unshift( $this->statements, 0);
  259. array_unshift( $this->offset, 0);
  260. $b = clone( $body );
  261. for( $i = 0; $i < sizeof( $b->statements ); $i++)
  262. {
  263. $this->statements[0] = $i;
  264. $this->acceptAndUpdate( $b->statements[$i] );
  265. }
  266. // XXX Test this, this may be wrong.
  267. // $body = $b;
  268. array_shift( $this->offset );
  269. array_shift( $this->statements );
  270. array_shift( $this->nodePath );
  271. }
  272. /**
  273. * visitGenericStatementAstNode
  274. *
  275. * @param ezcTemplateGenericStatementAstNode $statement
  276. * @return void
  277. */
  278. public function visitGenericStatementAstNode( ezcTemplateGenericStatementAstNode $statement )
  279. {
  280. array_unshift( $this->nodePath, $statement );
  281. $this->acceptAndUpdate( $statement->expression );
  282. array_shift( $this->nodePath );
  283. }
  284. /**
  285. * visitIfAstNode
  286. *
  287. * @param ezcTemplateIfAstNode $if
  288. * @return void
  289. */
  290. public function visitIfAstNode( ezcTemplateIfAstNode $if )
  291. {
  292. array_unshift( $this->nodePath, $if );
  293. foreach ( $if->conditions as $i => $conditionBody )
  294. {
  295. $condition = $conditionBody->condition;
  296. if ( $condition !== null )
  297. {
  298. $this->acceptAndUpdate( $if->conditions[$i]->condition );
  299. }
  300. $this->acceptAndUpdate( $conditionBody->body );
  301. }
  302. array_shift( $this->nodePath );
  303. }
  304. /**
  305. * visitDynamicBlockAstNode
  306. *
  307. * @param ezcTemplateDynamicBlockAstNode $statement
  308. * @return void
  309. */
  310. public function visitDynamicBlockAstNode( ezcTemplateDynamicBlockAstNode $statement )
  311. {
  312. array_unshift( $this->nodePath, $statement );
  313. $this->acceptAndUpdate( $statement->body );
  314. array_shift( $this->nodePath );
  315. }
  316. /**
  317. * Visits a code element containing while control structures.
  318. *
  319. * @param ezcTemplateWhileAstNode $while The code element containing the while control structure.
  320. * @return void
  321. */
  322. public function visitWhileAstNode( ezcTemplateWhileAstNode $while )
  323. {
  324. array_unshift( $this->nodePath, $while );
  325. $conditionBody = $while->conditionBody;
  326. $this->acceptAndUpdate( $conditionBody->condition );
  327. $this->acceptAndUpdate( $conditionBody->body );
  328. array_shift( $this->nodePath );
  329. }
  330. /**
  331. * visitForeachAstNode
  332. *
  333. * @param ezcTemplateForeachAstNode $foreach
  334. * @return void
  335. */
  336. public function visitForeachAstNode( ezcTemplateForeachAstNode $foreach )
  337. {
  338. array_unshift( $this->nodePath, $foreach );
  339. $this->acceptAndUpdate( $foreach->arrayExpression );
  340. if ( $foreach->keyVariable !== null )
  341. {
  342. $this->acceptAndUpdate( $foreach->keyVariable );
  343. }
  344. $this->acceptAndUpdate( $foreach->valueVariable );
  345. $this->acceptAndUpdate( $foreach->body );
  346. array_shift( $this->nodePath );
  347. }
  348. /**
  349. * visitBreakAstNode
  350. *
  351. * @param ezcTemplateBreakAstNode $break
  352. * @return void
  353. */
  354. public function visitBreakAstNode( ezcTemplateBreakAstNode $break )
  355. {
  356. }
  357. /**
  358. * visitContinueAstNode
  359. *
  360. * @param ezcTemplateContinueAstNode $continue
  361. * @return void
  362. */
  363. public function visitContinueAstNode( ezcTemplateContinueAstNode $continue )
  364. {
  365. }
  366. /**
  367. * visitReturnAstNode
  368. *
  369. * @param ezcTemplateReturnAstNode $return
  370. * @return void
  371. */
  372. public function visitReturnAstNode( ezcTemplateReturnAstNode $return )
  373. {
  374. }
  375. /**
  376. * visitRequireAstNode
  377. *
  378. * @param ezcTemplateRequireAstNode $require
  379. * @return void
  380. */
  381. public function visitRequireAstNode( ezcTemplateRequireAstNode $require )
  382. {
  383. }
  384. /**
  385. * visitRequireOnceAstNode
  386. *
  387. * @param ezcTemplateRequireOnceAstNode $require
  388. * @return void
  389. */
  390. public function visitRequireOnceAstNode( ezcTemplateRequireOnceAstNode $require )
  391. {
  392. }
  393. /**
  394. * visitIncludeAstNode
  395. *
  396. * @param ezcTemplateIncludeAstNode $include
  397. * @return void
  398. */
  399. public function visitIncludeAstNode( ezcTemplateIncludeAstNode $include )
  400. {
  401. }
  402. /**
  403. * visitIncludeOnceAstNode
  404. *
  405. * @param ezcTemplateIncludeOnceAstNode $include
  406. * @return void
  407. */
  408. public function visitIncludeOnceAstNode( ezcTemplateIncludeOnceAstNode $include )
  409. {
  410. }
  411. /**
  412. * visitSwitchAstNode
  413. *
  414. * @param ezcTemplateSwitchAstNode $switch
  415. * @return void
  416. */
  417. public function visitSwitchAstNode( ezcTemplateSwitchAstNode $switch )
  418. {
  419. array_unshift( $this->nodePath, $switch );
  420. $this->acceptAndUpdate( $switch->expression );
  421. foreach ( $switch->cases as $key => $case )
  422. {
  423. $this->acceptAndUpdate( $case );
  424. }
  425. array_shift( $this->nodePath );
  426. }
  427. /**
  428. * visitCaseAstNode
  429. *
  430. * @param ezcTemplateCaseAstNode $case
  431. * @return void
  432. */
  433. public function visitCaseAstNode( ezcTemplateCaseAstNode $case )
  434. {
  435. array_unshift( $this->nodePath, $case );
  436. $this->acceptAndUpdate( $case->match );
  437. $this->acceptAndUpdate( $case->body );
  438. array_shift( $this->nodePath );
  439. }
  440. /**
  441. * visitDefaultAstNode
  442. *
  443. * @param ezcTemplateDefaultAstNode $default
  444. * @return void
  445. */
  446. public function visitDefaultAstNode( ezcTemplateDefaultAstNode $default )
  447. {
  448. array_unshift( $this->nodePath, $default );
  449. $this->acceptAndUpdate( $default->body );
  450. array_shift( $this->nodePath );
  451. }
  452. /**
  453. * visitConditionBodyAstNode
  454. *
  455. * @param ezcTemplateConditionBodyAstNode $cond
  456. * @return void
  457. */
  458. public function visitConditionBodyAstNode( ezcTemplateConditionBodyAstNode $cond )
  459. {
  460. }
  461. /**
  462. * visitTryAstNode
  463. *
  464. * @param ezcTemplateTryAstNode $try
  465. * @return void
  466. */
  467. public function visitTryAstNode( ezcTemplateTryAstNode $try )
  468. {
  469. array_unshift( $this->nodePath, $try );
  470. $try->body->accept( $this );
  471. $this->acceptAndUpdate( $try->body );
  472. foreach ( $try->catches as $key => $catch )
  473. {
  474. $this->acceptAndUpdate( $try->catches[$key] );
  475. }
  476. array_shift( $this->nodePath );
  477. }
  478. /**
  479. * visitCatchAstNode
  480. *
  481. * @param ezcTemplateCatchAstNode $catch
  482. * @return void
  483. */
  484. public function visitCatchAstNode( ezcTemplateCatchAstNode $catch )
  485. {
  486. array_unshift( $this->nodePath, $catch );
  487. $this->acceptAndUpdate( $catch->variableExpression );
  488. $this->acceptAndUpdate( $catch->body );
  489. array_shift( $this->nodePath );
  490. }
  491. /**
  492. * visitEchoAstNode
  493. *
  494. * @param ezcTemplateEchoAstNode $echo
  495. * @return void
  496. */
  497. public function visitEchoAstNode( ezcTemplateEchoAstNode $echo )
  498. {
  499. array_unshift( $this->nodePath, $echo );
  500. $outputList = $echo->getOutputList();
  501. foreach ( $outputList as $i => $output )
  502. {
  503. $this->acceptAndUpdate( $echo->outputList[$i] );
  504. }
  505. array_shift( $this->nodePath );
  506. }
  507. /**
  508. * visitPrintAstNode
  509. *
  510. * @param ezcTemplatePrintAstNode $print
  511. * @return void
  512. */
  513. public function visitPrintAstNode( ezcTemplatePrintAstNode $print )
  514. {
  515. array_unshift( $this->nodePath, $print );
  516. $this->acceptAndUpdate( $print->expression );
  517. array_shift( $this->nodePath );
  518. }
  519. /**
  520. * visitIssetAstNode
  521. *
  522. * @param ezcTemplateIssetAstNode $isset
  523. * @return void
  524. */
  525. public function visitIssetAstNode( ezcTemplateIssetAstNode $isset )
  526. {
  527. }
  528. /**
  529. * visitUnsetAstNode
  530. *
  531. * @param ezcTemplateUnsetAstNode $unset
  532. * @return void
  533. */
  534. public function visitUnsetAstNode( ezcTemplateUnsetAstNode $unset )
  535. {
  536. }
  537. /**
  538. * visitEmptyAstNode
  539. *
  540. * @param ezcTemplateEmptyAstNode $empty
  541. * @return void
  542. */
  543. public function visitEmptyAstNode( ezcTemplateEmptyAstNode $empty )
  544. {
  545. array_unshift( $this->nodePath, $empty );
  546. $this->acceptAndUpdate( $empty->expression );
  547. array_shift( $this->nodePath );
  548. }
  549. /**
  550. * visitParenthesisAstNode
  551. *
  552. * @param ezcTemplateParenthesisAstNode $parenthesis
  553. * @return void
  554. */
  555. public function visitParenthesisAstNode( ezcTemplateParenthesisAstNode $parenthesis )
  556. {
  557. array_unshift( $this->nodePath, $parenthesis );
  558. $this->acceptAndUpdate( $parenthesis->expression );
  559. array_shift( $this->nodePath );
  560. }
  561. /**
  562. * visitCurlyBracesAstNode
  563. *
  564. * @param ezcTemplateCurlyBracesAstNode $curly
  565. * @return void
  566. */
  567. public function visitCurlyBracesAstNode( ezcTemplateCurlyBracesAstNode $curly )
  568. {
  569. array_unshift( $this->nodePath, $curly );
  570. $this->acceptAndUpdate( $parenthesis->expression );
  571. array_shift( $this->nodePath );
  572. }
  573. /**
  574. * visitIdentifierAstNode
  575. *
  576. * @param ezcTemplateIdentifierAstNode $node
  577. * @return void
  578. */
  579. public function visitIdentifierAstNode( ezcTemplateIdentifierAstNode $node )
  580. {
  581. }
  582. /**
  583. * visitNewAstNode
  584. *
  585. * @param ezcTemplateNewAstNode $node
  586. * @return void
  587. */
  588. public function visitNewAstNode( ezcTemplateNewAstNode $node )
  589. {
  590. }
  591. /**
  592. * visitCloneAstNode
  593. *
  594. * @param ezcTemplateCloneAstNode $node
  595. * @return void
  596. */
  597. public function visitCloneAstNode( ezcTemplateCloneAstNode $node )
  598. {
  599. }
  600. /**
  601. * visitPhpCodeAstNode
  602. *
  603. * @param ezcTemplatePhpCodeAstNode $node
  604. * @return void
  605. */
  606. public function visitPhpCodeAstNode( ezcTemplatePhpCodeAstNode $node )
  607. {
  608. }
  609. /**
  610. * visitThrowExceptionAstNode
  611. *
  612. * @param ezcTemplateThrowExceptionAstNode $node
  613. * @return void
  614. */
  615. public function visitThrowExceptionAstNode( ezcTemplateThrowExceptionAstNode $node )
  616. {
  617. array_unshift( $this->nodePath, $node );
  618. $this->acceptAndUpdate( $node->message );
  619. array_shift( $this->nodePath );
  620. }
  621. /**
  622. * visitNopAstNode
  623. *
  624. * @param ezcTemplateNopAstNode $node
  625. * @return void
  626. */
  627. public function visitNopAstNode( ezcTemplateNopAstNode $node )
  628. {
  629. }
  630. /**
  631. * Internal function called to call the accept function and change the given node.
  632. *
  633. * @param ezcTemplateAstNode $node Notice that the parameter will be changed.
  634. * @return void
  635. */
  636. protected function acceptAndUpdate( ezcTemplateAstNode &$node )
  637. {
  638. $ret = $node->accept( $this );
  639. if ( $ret !== null ) $node = $ret;
  640. }
  641. }
  642. ?>