NodeAbstract.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php declare(strict_types=1);
  2. namespace PhpParser;
  3. abstract class NodeAbstract implements Node, \JsonSerializable
  4. {
  5. protected $attributes;
  6. /**
  7. * Creates a Node.
  8. *
  9. * @param array $attributes Array of attributes
  10. */
  11. public function __construct(array $attributes = []) {
  12. $this->attributes = $attributes;
  13. }
  14. /**
  15. * Gets line the node started in (alias of getStartLine).
  16. *
  17. * @return int Start line (or -1 if not available)
  18. */
  19. public function getLine() : int {
  20. return $this->attributes['startLine'] ?? -1;
  21. }
  22. /**
  23. * Gets line the node started in.
  24. *
  25. * Requires the 'startLine' attribute to be enabled in the lexer (enabled by default).
  26. *
  27. * @return int Start line (or -1 if not available)
  28. */
  29. public function getStartLine() : int {
  30. return $this->attributes['startLine'] ?? -1;
  31. }
  32. /**
  33. * Gets the line the node ended in.
  34. *
  35. * Requires the 'endLine' attribute to be enabled in the lexer (enabled by default).
  36. *
  37. * @return int End line (or -1 if not available)
  38. */
  39. public function getEndLine() : int {
  40. return $this->attributes['endLine'] ?? -1;
  41. }
  42. /**
  43. * Gets the token offset of the first token that is part of this node.
  44. *
  45. * The offset is an index into the array returned by Lexer::getTokens().
  46. *
  47. * Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default).
  48. *
  49. * @return int Token start position (or -1 if not available)
  50. */
  51. public function getStartTokenPos() : int {
  52. return $this->attributes['startTokenPos'] ?? -1;
  53. }
  54. /**
  55. * Gets the token offset of the last token that is part of this node.
  56. *
  57. * The offset is an index into the array returned by Lexer::getTokens().
  58. *
  59. * Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default).
  60. *
  61. * @return int Token end position (or -1 if not available)
  62. */
  63. public function getEndTokenPos() : int {
  64. return $this->attributes['endTokenPos'] ?? -1;
  65. }
  66. /**
  67. * Gets the file offset of the first character that is part of this node.
  68. *
  69. * Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default).
  70. *
  71. * @return int File start position (or -1 if not available)
  72. */
  73. public function getStartFilePos() : int {
  74. return $this->attributes['startFilePos'] ?? -1;
  75. }
  76. /**
  77. * Gets the file offset of the last character that is part of this node.
  78. *
  79. * Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default).
  80. *
  81. * @return int File end position (or -1 if not available)
  82. */
  83. public function getEndFilePos() : int {
  84. return $this->attributes['endFilePos'] ?? -1;
  85. }
  86. /**
  87. * Gets all comments directly preceding this node.
  88. *
  89. * The comments are also available through the "comments" attribute.
  90. *
  91. * @return Comment[]
  92. */
  93. public function getComments() : array {
  94. return $this->attributes['comments'] ?? [];
  95. }
  96. /**
  97. * Gets the doc comment of the node.
  98. *
  99. * @return null|Comment\Doc Doc comment object or null
  100. */
  101. public function getDocComment() {
  102. $comments = $this->getComments();
  103. for ($i = count($comments) - 1; $i >= 0; $i--) {
  104. $comment = $comments[$i];
  105. if ($comment instanceof Comment\Doc) {
  106. return $comment;
  107. }
  108. }
  109. return null;
  110. }
  111. /**
  112. * Sets the doc comment of the node.
  113. *
  114. * This will either replace an existing doc comment or add it to the comments array.
  115. *
  116. * @param Comment\Doc $docComment Doc comment to set
  117. */
  118. public function setDocComment(Comment\Doc $docComment) {
  119. $comments = $this->getComments();
  120. for ($i = count($comments) - 1; $i >= 0; $i--) {
  121. if ($comments[$i] instanceof Comment\Doc) {
  122. // Replace existing doc comment.
  123. $comments[$i] = $docComment;
  124. $this->setAttribute('comments', $comments);
  125. return;
  126. }
  127. }
  128. // Append new doc comment.
  129. $comments[] = $docComment;
  130. $this->setAttribute('comments', $comments);
  131. }
  132. public function setAttribute(string $key, $value) {
  133. $this->attributes[$key] = $value;
  134. }
  135. public function hasAttribute(string $key) : bool {
  136. return array_key_exists($key, $this->attributes);
  137. }
  138. public function getAttribute(string $key, $default = null) {
  139. if (array_key_exists($key, $this->attributes)) {
  140. return $this->attributes[$key];
  141. }
  142. return $default;
  143. }
  144. public function getAttributes() : array {
  145. return $this->attributes;
  146. }
  147. public function setAttributes(array $attributes) {
  148. $this->attributes = $attributes;
  149. }
  150. /**
  151. * @return array
  152. */
  153. public function jsonSerialize() : array {
  154. return ['nodeType' => $this->getType()] + get_object_vars($this);
  155. }
  156. }