NodeAbstract.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. * The doc comment has to be the last comment associated with the node.
  100. *
  101. * @return null|Comment\Doc Doc comment object or null
  102. */
  103. public function getDocComment() {
  104. $comments = $this->getComments();
  105. if (!$comments) {
  106. return null;
  107. }
  108. $lastComment = $comments[count($comments) - 1];
  109. if (!$lastComment instanceof Comment\Doc) {
  110. return null;
  111. }
  112. return $lastComment;
  113. }
  114. /**
  115. * Sets the doc comment of the node.
  116. *
  117. * This will either replace an existing doc comment or add it to the comments array.
  118. *
  119. * @param Comment\Doc $docComment Doc comment to set
  120. */
  121. public function setDocComment(Comment\Doc $docComment) {
  122. $comments = $this->getComments();
  123. $numComments = count($comments);
  124. if ($numComments > 0 && $comments[$numComments - 1] instanceof Comment\Doc) {
  125. // Replace existing doc comment
  126. $comments[$numComments - 1] = $docComment;
  127. } else {
  128. // Append new comment
  129. $comments[] = $docComment;
  130. }
  131. $this->setAttribute('comments', $comments);
  132. }
  133. public function setAttribute(string $key, $value) {
  134. $this->attributes[$key] = $value;
  135. }
  136. public function hasAttribute(string $key) : bool {
  137. return array_key_exists($key, $this->attributes);
  138. }
  139. public function getAttribute(string $key, $default = null) {
  140. if (array_key_exists($key, $this->attributes)) {
  141. return $this->attributes[$key];
  142. }
  143. return $default;
  144. }
  145. public function getAttributes() : array {
  146. return $this->attributes;
  147. }
  148. public function setAttributes(array $attributes) {
  149. $this->attributes = $attributes;
  150. }
  151. /**
  152. * @return array
  153. */
  154. public function jsonSerialize() : array {
  155. return ['nodeType' => $this->getType()] + get_object_vars($this);
  156. }
  157. }