annotate vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php @ 19:fa3358dc1485 tip

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