annotate vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php @ 5:12f9dff5fda9 tip

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:34:47 +0100
parents a9cd425dd02b
children
rev   line source
Chris@0 1 <?php declare(strict_types=1);
Chris@0 2
Chris@0 3 namespace PhpParser;
Chris@0 4
Chris@0 5 use PhpParser\Node\Expr;
Chris@0 6 use PhpParser\Node\Identifier;
Chris@0 7 use PhpParser\Node\Name;
Chris@0 8 use PhpParser\Node\NullableType;
Chris@0 9 use PhpParser\Node\Scalar;
Chris@0 10 use PhpParser\Node\Stmt;
Chris@0 11
Chris@0 12 /**
Chris@0 13 * This class defines helpers used in the implementation of builders. Don't use it directly.
Chris@0 14 *
Chris@0 15 * @internal
Chris@0 16 */
Chris@0 17 final class BuilderHelpers
Chris@0 18 {
Chris@0 19 /**
Chris@0 20 * Normalizes a node: Converts builder objects to nodes.
Chris@0 21 *
Chris@0 22 * @param Node|Builder $node The node to normalize
Chris@0 23 *
Chris@0 24 * @return Node The normalized node
Chris@0 25 */
Chris@0 26 public static function normalizeNode($node) : Node {
Chris@0 27 if ($node instanceof Builder) {
Chris@0 28 return $node->getNode();
Chris@0 29 } elseif ($node instanceof Node) {
Chris@0 30 return $node;
Chris@0 31 }
Chris@0 32
Chris@0 33 throw new \LogicException('Expected node or builder object');
Chris@0 34 }
Chris@0 35
Chris@0 36 /**
Chris@0 37 * Normalizes a node to a statement.
Chris@0 38 *
Chris@0 39 * Expressions are wrapped in a Stmt\Expression node.
Chris@0 40 *
Chris@0 41 * @param Node|Builder $node The node to normalize
Chris@0 42 *
Chris@0 43 * @return Stmt The normalized statement node
Chris@0 44 */
Chris@0 45 public static function normalizeStmt($node) : Stmt {
Chris@0 46 $node = self::normalizeNode($node);
Chris@0 47 if ($node instanceof Stmt) {
Chris@0 48 return $node;
Chris@0 49 }
Chris@0 50
Chris@0 51 if ($node instanceof Expr) {
Chris@0 52 return new Stmt\Expression($node);
Chris@0 53 }
Chris@0 54
Chris@0 55 throw new \LogicException('Expected statement or expression node');
Chris@0 56 }
Chris@0 57
Chris@0 58 /**
Chris@0 59 * Normalizes strings to Identifier.
Chris@0 60 *
Chris@0 61 * @param string|Identifier $name The identifier to normalize
Chris@0 62 *
Chris@0 63 * @return Identifier The normalized identifier
Chris@0 64 */
Chris@0 65 public static function normalizeIdentifier($name) : Identifier {
Chris@0 66 if ($name instanceof Identifier) {
Chris@0 67 return $name;
Chris@0 68 }
Chris@0 69
Chris@0 70 if (\is_string($name)) {
Chris@0 71 return new Identifier($name);
Chris@0 72 }
Chris@0 73
Chris@4 74 throw new \LogicException('Expected string or instance of Node\Identifier');
Chris@0 75 }
Chris@0 76
Chris@0 77 /**
Chris@0 78 * Normalizes strings to Identifier, also allowing expressions.
Chris@0 79 *
Chris@0 80 * @param string|Identifier|Expr $name The identifier to normalize
Chris@0 81 *
Chris@0 82 * @return Identifier|Expr The normalized identifier or expression
Chris@0 83 */
Chris@0 84 public static function normalizeIdentifierOrExpr($name) {
Chris@0 85 if ($name instanceof Identifier || $name instanceof Expr) {
Chris@0 86 return $name;
Chris@0 87 }
Chris@0 88
Chris@0 89 if (\is_string($name)) {
Chris@0 90 return new Identifier($name);
Chris@0 91 }
Chris@0 92
Chris@0 93 throw new \LogicException('Expected string or instance of Node\Identifier or Node\Expr');
Chris@0 94 }
Chris@0 95
Chris@0 96 /**
Chris@0 97 * Normalizes a name: Converts string names to Name nodes.
Chris@0 98 *
Chris@0 99 * @param Name|string $name The name to normalize
Chris@0 100 *
Chris@0 101 * @return Name The normalized name
Chris@0 102 */
Chris@0 103 public static function normalizeName($name) : Name {
Chris@0 104 return self::normalizeNameCommon($name, false);
Chris@0 105 }
Chris@0 106
Chris@0 107 /**
Chris@0 108 * Normalizes a name: Converts string names to Name nodes, while also allowing expressions.
Chris@0 109 *
Chris@0 110 * @param Expr|Name|string $name The name to normalize
Chris@0 111 *
Chris@0 112 * @return Name|Expr The normalized name or expression
Chris@0 113 */
Chris@0 114 public static function normalizeNameOrExpr($name) {
Chris@0 115 return self::normalizeNameCommon($name, true);
Chris@0 116 }
Chris@0 117
Chris@0 118 /**
Chris@0 119 * Normalizes a name: Converts string names to Name nodes, optionally allowing expressions.
Chris@0 120 *
Chris@0 121 * @param Expr|Name|string $name The name to normalize
Chris@0 122 * @param bool $allowExpr Whether to also allow expressions
Chris@0 123 *
Chris@0 124 * @return Name|Expr The normalized name, or expression (if allowed)
Chris@0 125 */
Chris@0 126 private static function normalizeNameCommon($name, bool $allowExpr) {
Chris@0 127 if ($name instanceof Name) {
Chris@0 128 return $name;
Chris@0 129 } elseif (is_string($name)) {
Chris@0 130 if (!$name) {
Chris@0 131 throw new \LogicException('Name cannot be empty');
Chris@0 132 }
Chris@0 133
Chris@0 134 if ($name[0] === '\\') {
Chris@0 135 return new Name\FullyQualified(substr($name, 1));
Chris@0 136 } elseif (0 === strpos($name, 'namespace\\')) {
Chris@0 137 return new Name\Relative(substr($name, strlen('namespace\\')));
Chris@0 138 } else {
Chris@0 139 return new Name($name);
Chris@0 140 }
Chris@0 141 }
Chris@0 142
Chris@0 143 if ($allowExpr) {
Chris@0 144 if ($name instanceof Expr) {
Chris@0 145 return $name;
Chris@0 146 }
Chris@0 147 throw new \LogicException(
Chris@0 148 'Name must be a string or an instance of Node\Name or Node\Expr'
Chris@0 149 );
Chris@0 150 } else {
Chris@0 151 throw new \LogicException('Name must be a string or an instance of Node\Name');
Chris@0 152 }
Chris@0 153 }
Chris@0 154
Chris@0 155 /**
Chris@0 156 * Normalizes a type: Converts plain-text type names into proper AST representation.
Chris@0 157 *
Chris@0 158 * In particular, builtin types become Identifiers, custom types become Names and nullables
Chris@0 159 * are wrapped in NullableType nodes.
Chris@0 160 *
Chris@0 161 * @param string|Name|Identifier|NullableType $type The type to normalize
Chris@0 162 *
Chris@0 163 * @return Name|Identifier|NullableType The normalized type
Chris@0 164 */
Chris@0 165 public static function normalizeType($type) {
Chris@0 166 if (!is_string($type)) {
Chris@0 167 if (!$type instanceof Name && !$type instanceof Identifier
Chris@0 168 && !$type instanceof NullableType) {
Chris@0 169 throw new \LogicException(
Chris@0 170 'Type must be a string, or an instance of Name, Identifier or NullableType');
Chris@0 171 }
Chris@0 172 return $type;
Chris@0 173 }
Chris@0 174
Chris@0 175 $nullable = false;
Chris@0 176 if (strlen($type) > 0 && $type[0] === '?') {
Chris@0 177 $nullable = true;
Chris@0 178 $type = substr($type, 1);
Chris@0 179 }
Chris@0 180
Chris@0 181 $builtinTypes = [
Chris@0 182 'array', 'callable', 'string', 'int', 'float', 'bool', 'iterable', 'void', 'object'
Chris@0 183 ];
Chris@0 184
Chris@0 185 $lowerType = strtolower($type);
Chris@0 186 if (in_array($lowerType, $builtinTypes)) {
Chris@0 187 $type = new Identifier($lowerType);
Chris@0 188 } else {
Chris@0 189 $type = self::normalizeName($type);
Chris@0 190 }
Chris@0 191
Chris@0 192 if ($nullable && (string) $type === 'void') {
Chris@0 193 throw new \LogicException('void type cannot be nullable');
Chris@0 194 }
Chris@0 195
Chris@0 196 return $nullable ? new Node\NullableType($type) : $type;
Chris@0 197 }
Chris@0 198
Chris@0 199 /**
Chris@0 200 * Normalizes a value: Converts nulls, booleans, integers,
Chris@0 201 * floats, strings and arrays into their respective nodes
Chris@0 202 *
Chris@0 203 * @param Node\Expr|bool|null|int|float|string|array $value The value to normalize
Chris@0 204 *
Chris@0 205 * @return Expr The normalized value
Chris@0 206 */
Chris@0 207 public static function normalizeValue($value) : Expr {
Chris@0 208 if ($value instanceof Node\Expr) {
Chris@0 209 return $value;
Chris@0 210 } elseif (is_null($value)) {
Chris@0 211 return new Expr\ConstFetch(
Chris@0 212 new Name('null')
Chris@0 213 );
Chris@0 214 } elseif (is_bool($value)) {
Chris@0 215 return new Expr\ConstFetch(
Chris@0 216 new Name($value ? 'true' : 'false')
Chris@0 217 );
Chris@0 218 } elseif (is_int($value)) {
Chris@0 219 return new Scalar\LNumber($value);
Chris@0 220 } elseif (is_float($value)) {
Chris@0 221 return new Scalar\DNumber($value);
Chris@0 222 } elseif (is_string($value)) {
Chris@0 223 return new Scalar\String_($value);
Chris@0 224 } elseif (is_array($value)) {
Chris@0 225 $items = [];
Chris@0 226 $lastKey = -1;
Chris@0 227 foreach ($value as $itemKey => $itemValue) {
Chris@0 228 // for consecutive, numeric keys don't generate keys
Chris@0 229 if (null !== $lastKey && ++$lastKey === $itemKey) {
Chris@0 230 $items[] = new Expr\ArrayItem(
Chris@0 231 self::normalizeValue($itemValue)
Chris@0 232 );
Chris@0 233 } else {
Chris@0 234 $lastKey = null;
Chris@0 235 $items[] = new Expr\ArrayItem(
Chris@0 236 self::normalizeValue($itemValue),
Chris@0 237 self::normalizeValue($itemKey)
Chris@0 238 );
Chris@0 239 }
Chris@0 240 }
Chris@0 241
Chris@0 242 return new Expr\Array_($items);
Chris@0 243 } else {
Chris@0 244 throw new \LogicException('Invalid value');
Chris@0 245 }
Chris@0 246 }
Chris@0 247
Chris@0 248 /**
Chris@0 249 * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc.
Chris@0 250 *
Chris@0 251 * @param Comment\Doc|string $docComment The doc comment to normalize
Chris@0 252 *
Chris@0 253 * @return Comment\Doc The normalized doc comment
Chris@0 254 */
Chris@0 255 public static function normalizeDocComment($docComment) : Comment\Doc {
Chris@0 256 if ($docComment instanceof Comment\Doc) {
Chris@0 257 return $docComment;
Chris@0 258 } elseif (is_string($docComment)) {
Chris@0 259 return new Comment\Doc($docComment);
Chris@0 260 } else {
Chris@0 261 throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc');
Chris@0 262 }
Chris@0 263 }
Chris@0 264
Chris@0 265 /**
Chris@0 266 * Adds a modifier and returns new modifier bitmask.
Chris@0 267 *
Chris@0 268 * @param int $modifiers Existing modifiers
Chris@0 269 * @param int $modifier Modifier to set
Chris@0 270 *
Chris@0 271 * @return int New modifiers
Chris@0 272 */
Chris@0 273 public static function addModifier(int $modifiers, int $modifier) : int {
Chris@0 274 Stmt\Class_::verifyModifier($modifiers, $modifier);
Chris@0 275 return $modifiers | $modifier;
Chris@0 276 }
Chris@0 277 }