You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
3.5 KiB

3 years ago
  1. <?php
  2. /*
  3. Copyright (c) 2009 hamcrest.org
  4. */
  5. class FactoryParameter
  6. {
  7. /**
  8. * @var FactoryMethod
  9. */
  10. private $method;
  11. /**
  12. * @var ReflectionParameter
  13. */
  14. private $reflector;
  15. public function __construct(FactoryMethod $method, ReflectionParameter $reflector)
  16. {
  17. $this->method = $method;
  18. $this->reflector = $reflector;
  19. }
  20. /**
  21. * Compute the declaration code.
  22. *
  23. * @return string
  24. */
  25. public function getDeclaration()
  26. {
  27. $code = $this->getTypeCode() . $this->getInvocation();
  28. if ($this->reflector->isOptional()) {
  29. $default = $this->reflector->getDefaultValue();
  30. if (is_null($default)) {
  31. $default = 'null';
  32. } elseif (is_bool($default)) {
  33. $default = $default ? 'true' : 'false';
  34. } elseif (is_string($default)) {
  35. $default = "'" . $default . "'";
  36. } elseif (is_numeric($default)) {
  37. $default = strval($default);
  38. } elseif (is_array($default)) {
  39. $default = 'array()';
  40. } else {
  41. echo 'Warning: unknown default type for ' . $this->getMethod()->getFullName() . "\n";
  42. var_dump($default);
  43. $default = 'null';
  44. }
  45. $code .= ' = ' . $default;
  46. }
  47. return $code;
  48. }
  49. /**
  50. * Compute the type code for the paramater.
  51. *
  52. * @return string
  53. */
  54. private function getTypeCode()
  55. {
  56. // Handle PHP 5 separately
  57. if (PHP_VERSION_ID < 70000) {
  58. if ($this->reflector->isArray()) {
  59. return 'array';
  60. }
  61. $class = $this->reflector->getClass();
  62. return $class ? sprintf('\\%s ', $class->getName()) : '';
  63. }
  64. if (!$this->reflector->hasType()) {
  65. return '';
  66. }
  67. $type = $this->reflector->getType();
  68. $name = self::getQualifiedName($type);
  69. // PHP 7.1+ supports nullable types via a leading question mark
  70. return (PHP_VERSION_ID >= 70100 && $type->allowsNull()) ? sprintf('?%s ', $name) : sprintf('%s ', $name);
  71. }
  72. /**
  73. * Compute qualified name for the given type.
  74. *
  75. * This function knows how to prefix class names with a leading slash and
  76. * also how to handle PHP 8's union types.
  77. *
  78. * @param ReflectionType $type
  79. *
  80. * @return string
  81. */
  82. private static function getQualifiedName(ReflectionType $type)
  83. {
  84. // PHP 8 union types can be recursively processed
  85. if ($type instanceof ReflectionUnionType) {
  86. return implode('|', array_map(function (ReflectionType $type) {
  87. // The "self::" call within a Closure is fine here because this
  88. // code will only ever be executed on PHP 7.0+
  89. return self::getQualifiedName($type);
  90. }, $type->getTypes()));
  91. }
  92. // PHP 7.0 doesn't have named types, but 7.1+ does
  93. $name = $type instanceof ReflectionNamedType ? $type->getName() : (string) $type;
  94. return $type->isBuiltin() ? $name : sprintf('\\%s', $name);
  95. }
  96. /**
  97. * Compute the invocation code.
  98. *
  99. * @return string
  100. */
  101. public function getInvocation()
  102. {
  103. return sprintf('$%s', $this->reflector->getName());
  104. }
  105. /**
  106. * Compute the method name.
  107. *
  108. * @return string
  109. */
  110. public function getMethod()
  111. {
  112. return $this->method;
  113. }
  114. }