Class_.php 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. namespace PhpParser\Node\Stmt;
  3. use PhpParser\Error;
  4. use PhpParser\Node;
  5. class Class_ extends ClassLike
  6. {
  7. const MODIFIER_PUBLIC = 1;
  8. const MODIFIER_PROTECTED = 2;
  9. const MODIFIER_PRIVATE = 4;
  10. const MODIFIER_STATIC = 8;
  11. const MODIFIER_ABSTRACT = 16;
  12. const MODIFIER_FINAL = 32;
  13. const VISIBILITY_MODIFER_MASK = 7; // 1 | 2 | 4
  14. /** @var int Type */
  15. public $flags;
  16. /** @var null|Node\Name Name of extended class */
  17. public $extends;
  18. /** @var Node\Name[] Names of implemented interfaces */
  19. public $implements;
  20. /** @deprecated Use $flags instead */
  21. public $type;
  22. protected static $specialNames = array(
  23. 'self' => true,
  24. 'parent' => true,
  25. 'static' => true,
  26. );
  27. /**
  28. * Constructs a class node.
  29. *
  30. * @param string|null $name Name
  31. * @param array $subNodes Array of the following optional subnodes:
  32. * 'flags' => 0 : Flags
  33. * 'extends' => null : Name of extended class
  34. * 'implements' => array(): Names of implemented interfaces
  35. * 'stmts' => array(): Statements
  36. * @param array $attributes Additional attributes
  37. */
  38. public function __construct($name, array $subNodes = array(), array $attributes = array()) {
  39. parent::__construct($attributes);
  40. $this->flags = isset($subNodes['flags']) ? $subNodes['flags']
  41. : (isset($subNodes['type']) ? $subNodes['type'] : 0);
  42. $this->type = $this->flags;
  43. $this->name = $name;
  44. $this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : null;
  45. $this->implements = isset($subNodes['implements']) ? $subNodes['implements'] : array();
  46. $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array();
  47. }
  48. public function getSubNodeNames() {
  49. return array('flags', 'name', 'extends', 'implements', 'stmts');
  50. }
  51. public function isAbstract() {
  52. return (bool) ($this->flags & self::MODIFIER_ABSTRACT);
  53. }
  54. public function isFinal() {
  55. return (bool) ($this->flags & self::MODIFIER_FINAL);
  56. }
  57. public function isAnonymous() {
  58. return null === $this->name;
  59. }
  60. /**
  61. * @internal
  62. */
  63. public static function verifyModifier($a, $b) {
  64. if ($a & self::VISIBILITY_MODIFER_MASK && $b & self::VISIBILITY_MODIFER_MASK) {
  65. throw new Error('Multiple access type modifiers are not allowed');
  66. }
  67. if ($a & self::MODIFIER_ABSTRACT && $b & self::MODIFIER_ABSTRACT) {
  68. throw new Error('Multiple abstract modifiers are not allowed');
  69. }
  70. if ($a & self::MODIFIER_STATIC && $b & self::MODIFIER_STATIC) {
  71. throw new Error('Multiple static modifiers are not allowed');
  72. }
  73. if ($a & self::MODIFIER_FINAL && $b & self::MODIFIER_FINAL) {
  74. throw new Error('Multiple final modifiers are not allowed');
  75. }
  76. if ($a & 48 && $b & 48) {
  77. throw new Error('Cannot use the final modifier on an abstract class member');
  78. }
  79. }
  80. }