From 296544089c0b5ec2dcd19e02406b0fbeb7b11f57 Mon Sep 17 00:00:00 2001 From: Vladimir Razuvaev Date: Mon, 10 Jul 2017 19:50:26 +0700 Subject: [PATCH] Moved GraphQL\Utils to GraphQL\Utils\Utils --- UPGRADE.md | 4 + benchmarks/Utils/QueryGenerator.php | 2 +- docs/type-system/scalar-types.md | 2 +- examples/01-blog/Blog/AppContext.php | 2 - examples/01-blog/Blog/Data/Comment.php | 2 +- examples/01-blog/Blog/Data/Image.php | 2 +- examples/01-blog/Blog/Data/Story.php | 2 +- examples/01-blog/Blog/Data/User.php | 2 +- .../01-blog/Blog/Type/Scalar/EmailType.php | 2 +- examples/01-blog/Blog/Type/Scalar/UrlType.php | 2 +- src/Error/Error.php | 2 +- src/Error/FormattedError.php | 4 +- src/Executor/Executor.php | 5 +- .../Promise/Adapter/ReactPromiseAdapter.php | 2 +- src/Executor/Promise/Adapter/SyncPromise.php | 2 +- .../Promise/Adapter/SyncPromiseAdapter.php | 2 +- src/Executor/Promise/Promise.php | 2 +- src/Executor/Values.php | 14 +- src/Language/AST/Node.php | 2 +- src/Language/Lexer.php | 2 +- src/Language/Source.php | 2 +- src/Schema.php | 4 +- src/Schema/Config.php | 2 +- src/Schema/Descriptor.php | 2 +- src/Server.php | 1 + src/Type/Definition/Config.php | 2 +- src/Type/Definition/EnumType.php | 9 +- src/Type/Definition/EnumValueDefinition.php | 2 +- src/Type/Definition/FieldDefinition.php | 2 +- src/Type/Definition/FloatType.php | 2 +- src/Type/Definition/InputObjectType.php | 2 +- src/Type/Definition/IntType.php | 2 +- src/Type/Definition/InterfaceType.php | 2 +- src/Type/Definition/ListOfType.php | 2 +- src/Type/Definition/NonNull.php | 2 +- src/Type/Definition/ObjectType.php | 2 +- src/Type/Definition/ResolveInfo.php | 2 +- src/Type/Definition/ScalarType.php | 2 +- src/Type/Definition/Type.php | 2 +- src/Type/Definition/UnionType.php | 2 +- src/Type/EagerResolution.php | 5 +- src/Type/Introspection.php | 2 +- src/Type/LazyResolution.php | 2 +- src/Utils.php | 371 +----------------- src/Utils/AST.php | 2 +- src/Utils/BuildSchema.php | 3 +- src/Utils/MixedStore.php | 2 +- src/Utils/SchemaPrinter.php | 2 +- src/Utils/TypeInfo.php | 2 +- src/Utils/Utils.php | 371 ++++++++++++++++++ src/Validator/DocumentValidator.php | 2 +- src/Validator/Rules/FieldsOnCorrectType.php | 2 +- src/Validator/Rules/KnownArgumentNames.php | 2 +- .../Rules/LoneAnonymousOperation.php | 2 +- src/Validator/Rules/NoFragmentCycles.php | 2 +- .../Rules/OverlappingFieldsCanBeMerged.php | 2 +- .../Rules/ProvidedNonNullArguments.php | 2 +- .../Rules/VariablesAreInputTypes.php | 4 +- tests/Executor/DeferredFieldsTest.php | 2 +- tests/Language/LexerTest.php | 2 +- tests/Language/ParserTest.php | 2 +- tests/Type/ConfigTest.php | 2 +- tests/Type/DefinitionTest.php | 2 +- tests/Utils/MixedStoreTest.php | 2 +- tests/Utils/ValueFromAstTest.php | 2 +- tests/UtilsTest.php | 2 +- 66 files changed, 461 insertions(+), 442 deletions(-) create mode 100644 src/Utils/Utils.php diff --git a/UPGRADE.md b/UPGRADE.md index 7c0bbd4..e4985c4 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,9 @@ # Upgrade +## Upgrade v0.9.x > v0.10.x +### Deprecated: GraphQL\Utils moved to GraphQL\Utils\Utils +Old class still exists, but triggers deprecation warning. + ## Upgrade v0.7.x > v0.8.x All of those changes apply to those who extends various parts of this library. If you only use the library and don't try to extend it - everything should work without breaks. diff --git a/benchmarks/Utils/QueryGenerator.php b/benchmarks/Utils/QueryGenerator.php index f89b5be..e99f43a 100644 --- a/benchmarks/Utils/QueryGenerator.php +++ b/benchmarks/Utils/QueryGenerator.php @@ -12,7 +12,7 @@ use GraphQL\Type\Definition\FieldDefinition; use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\WrappingType; -use GraphQL\Utils; +use GraphQL\Utils\Utils; class QueryGenerator { diff --git a/docs/type-system/scalar-types.md b/docs/type-system/scalar-types.md index bd0ac1d..cce575b 100644 --- a/docs/type-system/scalar-types.md +++ b/docs/type-system/scalar-types.md @@ -44,7 +44,7 @@ namespace MyApp; use GraphQL\Error\Error; use GraphQL\Language\AST\StringValueNode; use GraphQL\Type\Definition\ScalarType; -use GraphQL\Utils; +use GraphQL\Utils\Utils; class EmailType extends ScalarType { diff --git a/examples/01-blog/Blog/AppContext.php b/examples/01-blog/Blog/AppContext.php index 2b42406..f6c16cf 100644 --- a/examples/01-blog/Blog/AppContext.php +++ b/examples/01-blog/Blog/AppContext.php @@ -1,9 +1,7 @@ exeContext->schema, $typeConditionNode); + $conditionalType = TypeInfo::typeFromAST($this->exeContext->schema, $typeConditionNode); if ($conditionalType === $type) { return true; } diff --git a/src/Executor/Promise/Adapter/ReactPromiseAdapter.php b/src/Executor/Promise/Adapter/ReactPromiseAdapter.php index a0ca273..747ed42 100644 --- a/src/Executor/Promise/Adapter/ReactPromiseAdapter.php +++ b/src/Executor/Promise/Adapter/ReactPromiseAdapter.php @@ -3,7 +3,7 @@ namespace GraphQL\Executor\Promise\Adapter; use GraphQL\Executor\Promise\Promise; use GraphQL\Executor\Promise\PromiseAdapter; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use React\Promise\Promise as ReactPromise; use React\Promise\PromiseInterface as ReactPromiseInterface; diff --git a/src/Executor/Promise/Adapter/SyncPromise.php b/src/Executor/Promise/Adapter/SyncPromise.php index 3a74da8..9376bf7 100644 --- a/src/Executor/Promise/Adapter/SyncPromise.php +++ b/src/Executor/Promise/Adapter/SyncPromise.php @@ -1,7 +1,7 @@ variable->name->value; - $varType = Utils\TypeInfo::typeFromAST($schema, $definitionNode->type); + $varType = TypeInfo::typeFromAST($schema, $definitionNode->type); if (!Type::isInputType($varType)) { throw new Error( @@ -57,7 +59,7 @@ class Values if (!array_key_exists($varName, $inputs)) { $defaultValue = $definitionNode->defaultValue; if ($defaultValue) { - $coercedValues[$varName] = Utils\AST::valueFromAST($defaultValue, $varType); + $coercedValues[$varName] = AST::valueFromAST($defaultValue, $varType); } if ($varType instanceof NonNull) { throw new Error( @@ -148,7 +150,7 @@ class Values } } else { $valueNode = $argumentNode->value; - $coercedValue = Utils\AST::valueFromAST($valueNode, $argType, $variableValues); + $coercedValue = AST::valueFromAST($valueNode, $argType, $variableValues); if ($coercedValue === $undefined) { $errors = DocumentValidator::isValidLiteralValue($argType, $valueNode); $message = !empty($errors) ? ("\n" . implode("\n", $errors)) : ''; @@ -191,7 +193,7 @@ class Values } /** - * @deprecated as of 8.0 (Moved to Utils\AST::valueFromAST) + * @deprecated as of 8.0 (Moved to \GraphQL\Utils\AST::valueFromAST) * * @param $valueNode * @param InputType $type @@ -200,7 +202,7 @@ class Values */ public static function valueFromAST($valueNode, InputType $type, $variables = null) { - return Utils\AST::valueFromAST($valueNode, $type, $variables); + return AST::valueFromAST($valueNode, $type, $variables); } /** diff --git a/src/Language/AST/Node.php b/src/Language/AST/Node.php index 3ce3be1..0ea1b5b 100644 --- a/src/Language/AST/Node.php +++ b/src/Language/AST/Node.php @@ -1,7 +1,7 @@ + * @var MixedStore */ private $valueLookup; @@ -138,12 +139,12 @@ class EnumType extends Type implements InputType, OutputType, LeafType } /** - * @return Utils\MixedStore + * @return MixedStore */ private function getValueLookup() { if (null === $this->valueLookup) { - $this->valueLookup = new Utils\MixedStore(); + $this->valueLookup = new MixedStore(); foreach ($this->getValues() as $valueName => $value) { $this->valueLookup->offsetSet($value->value, $value); diff --git a/src/Type/Definition/EnumValueDefinition.php b/src/Type/Definition/EnumValueDefinition.php index a28ce88..3895399 100644 --- a/src/Type/Definition/EnumValueDefinition.php +++ b/src/Type/Definition/EnumValueDefinition.php @@ -1,6 +1,6 @@ typeMap = $typeMap + Type::getInternalTypes(); diff --git a/src/Type/Introspection.php b/src/Type/Introspection.php index 35c21ba..98c8946 100644 --- a/src/Type/Introspection.php +++ b/src/Type/Introspection.php @@ -20,7 +20,7 @@ use GraphQL\Type\Definition\ScalarType; use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\UnionType; use GraphQL\Type\Definition\WrappingType; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use GraphQL\Utils\AST; class TypeKind { diff --git a/src/Type/LazyResolution.php b/src/Type/LazyResolution.php index 998bcfe..6efc06c 100644 --- a/src/Type/LazyResolution.php +++ b/src/Type/LazyResolution.php @@ -5,7 +5,7 @@ use GraphQL\Error\InvariantViolation; use GraphQL\Type\Definition\AbstractType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; -use GraphQL\Utils; +use GraphQL\Utils\Utils; /** * EXPERIMENTAL! diff --git a/src/Utils.php b/src/Utils.php index 252c9c0..b73186f 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -1,372 +1,11 @@ $value) { - if (!property_exists($obj, $key)) { - $cls = get_class($obj); - Warning::warn( - "Trying to set non-existing property '$key' on class '$cls'", - Warning::ASSIGN_WARNING - ); - } - $obj->{$key} = $value; - } - return $obj; - } - - /** - * @param array|Traversable $traversable - * @param callable $predicate - * @return null - */ - public static function find($traversable, callable $predicate) - { - self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); - - foreach ($traversable as $key => $value) { - if ($predicate($value, $key)) { - return $value; - } - } - return null; - } - - /** - * @param $traversable - * @param callable $predicate - * @return array - * @throws \Exception - */ - public static function filter($traversable, callable $predicate) - { - self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); - - $result = []; - $assoc = false; - foreach ($traversable as $key => $value) { - if (!$assoc && !is_int($key)) { - $assoc = true; - } - if ($predicate($value, $key)) { - $result[$key] = $value; - } - } - - return $assoc ? $result : array_values($result); - } - - /** - * @param array|\Traversable $traversable - * @param callable $fn function($value, $key) => $newValue - * @return array - * @throws \Exception - */ - public static function map($traversable, callable $fn) - { - self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); - - $map = []; - foreach ($traversable as $key => $value) { - $map[$key] = $fn($value, $key); - } - return $map; - } - - /** - * @param $traversable - * @param callable $fn - * @return array - * @throws \Exception - */ - public static function mapKeyValue($traversable, callable $fn) - { - self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); - - $map = []; - foreach ($traversable as $key => $value) { - list($newKey, $newValue) = $fn($value, $key); - $map[$newKey] = $newValue; - } - return $map; - } - - /** - * @param $traversable - * @param callable $keyFn function($value, $key) => $newKey - * @return array - * @throws \Exception - */ - public static function keyMap($traversable, callable $keyFn) - { - self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); - - $map = []; - foreach ($traversable as $key => $value) { - $newKey = $keyFn($value, $key); - if (is_scalar($newKey)) { - $map[$newKey] = $value; - } - } - return $map; - } - - /** - * @param $traversable - * @param callable $fn - */ - public static function each($traversable, callable $fn) - { - self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); - - foreach ($traversable as $key => $item) { - $fn($item, $key); - } - } - - /** - * Splits original traversable to several arrays with keys equal to $keyFn return - * - * E.g. Utils::groupBy([1, 2, 3, 4, 5], function($value) {return $value % 3}) will output: - * [ - * 1 => [1, 4], - * 2 => [2, 5], - * 0 => [3], - * ] - * - * $keyFn is also allowed to return array of keys. Then value will be added to all arrays with given keys - * - * @param $traversable - * @param callable $keyFn function($value, $key) => $newKey(s) - * @return array - */ - public static function groupBy($traversable, callable $keyFn) - { - self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); - - $grouped = []; - foreach ($traversable as $key => $value) { - $newKeys = (array) $keyFn($value, $key); - foreach ($newKeys as $key) { - $grouped[$key][] = $value; - } - } - - return $grouped; - } - - public static function keyValMap($traversable, callable $keyFn, callable $valFn) - { - return array_reduce($traversable, function ($map, $item) use ($keyFn, $valFn) { - $map[$keyFn($item)] = $valFn($item); - return $map; - }, []); - } - - /** - * @param $traversable - * @param callable $predicate - * @return bool - */ - public static function every($traversable, callable $predicate) - { - foreach ($traversable as $key => $value) { - if (!$predicate($value, $key)) { - return false; - } - } - return true; - } - - /** - * @param $test - * @param string $message - * @param mixed $sprintfParam1 - * @param mixed $sprintfParam2 ... - * @throws \Exception - */ - public static function invariant($test, $message = '') - { - if (!$test) { - if (func_num_args() > 2) { - $args = func_get_args(); - array_shift($args); - $message = call_user_func_array('sprintf', $args); - } - throw new InvariantViolation($message); - } - } - - /** - * @param $var - * @return string - */ - public static function getVariableType($var) - { - if ($var instanceof Type) { - // FIXME: Replace with schema printer call - if ($var instanceof WrappingType) { - $var = $var->getWrappedType(true); - } - return $var->name; - } - return is_object($var) ? get_class($var) : gettype($var); - } - - /** - * @param $var - * @return string - */ - public static function printSafe($var) - { - if ($var instanceof Type) { - return $var->toString(); - } - if (is_object($var)) { - return 'instance of ' . get_class($var); - } - if ('' === $var) { - return '(empty string)'; - } - if (is_string($var)) { - return "\"$var\""; - } - if (is_scalar($var)) { - return (string) $var; - } - if (null === $var) { - return 'null'; - } - return gettype($var); - } - - /** - * UTF-8 compatible chr() - * - * @param string $ord - * @param string $encoding - * @return string - */ - public static function chr($ord, $encoding = 'UTF-8') - { - if ($ord <= 255) { - return chr($ord); - } - if ($encoding === 'UCS-4BE') { - return pack("N", $ord); - } else { - return mb_convert_encoding(self::chr($ord, 'UCS-4BE'), $encoding, 'UCS-4BE'); - } - } - - /** - * UTF-8 compatible ord() - * - * @param string $char - * @param string $encoding - * @return mixed - */ - public static function ord($char, $encoding = 'UTF-8') - { - if (!$char && '0' !== $char) { - return 0; - } - if (!isset($char[1])) { - return ord($char); - } - if ($encoding !== 'UCS-4BE') { - $char = mb_convert_encoding($char, 'UCS-4BE', $encoding); - } - list(, $ord) = unpack('N', $char); - return $ord; - } - - /** - * Returns UTF-8 char code at given $positing of the $string - * - * @param $string - * @param $position - * @return mixed - */ - public static function charCodeAt($string, $position) - { - $char = mb_substr($string, $position, 1, 'UTF-8'); - return self::ord($char); - } - - /** - * @param $code - * @return string - */ - public static function printCharCode($code) - { - if (null === $code) { - return ''; - } - return $code < 0x007F - // Trust JSON for ASCII. - ? json_encode(Utils::chr($code)) - // Otherwise print the escaped form. - : '"\\u' . dechex($code) . '"'; - } - - /** - * @param $name - * @param bool $isIntrospection - * @throws Error - */ - public static function assertValidName($name, $isIntrospection = false) - { - $regex = '/^[_a-zA-Z][_a-zA-Z0-9]*$/'; - - if (!$name || !is_string($name)) { - throw new InvariantViolation( - "Must be named. Unexpected name: " . self::printSafe($name) - ); - } - - if (!$isIntrospection && isset($name[1]) && $name[0] === '_' && $name[1] === '_') { - Warning::warnOnce( - 'Name "'.$name.'" must not begin with "__", which is reserved by ' . - 'GraphQL introspection. In a future release of graphql this will ' . - 'become an exception', - Warning::NAME_WARNING - ); - } - - if (!preg_match($regex, $name)) { - throw new InvariantViolation( - 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "'.$name.'" does not.' - ); - } - } } diff --git a/src/Utils/AST.php b/src/Utils/AST.php index 1eaed83..27cc776 100644 --- a/src/Utils/AST.php +++ b/src/Utils/AST.php @@ -22,7 +22,7 @@ use GraphQL\Type\Definition\InputType; use GraphQL\Type\Definition\LeafType; use GraphQL\Type\Definition\ListOfType; use GraphQL\Type\Definition\NonNull; -use GraphQL\Utils; +use GraphQL\Utils\Utils; /** * Class AST diff --git a/src/Utils/BuildSchema.php b/src/Utils/BuildSchema.php index 1cfc7ca..269de36 100644 --- a/src/Utils/BuildSchema.php +++ b/src/Utils/BuildSchema.php @@ -31,7 +31,6 @@ use GraphQL\Type\Definition\CustomScalarType; use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\UnionType; use GraphQL\Type\Introspection; -use GraphQL\Utils; /** * Class BuildSchema @@ -394,7 +393,7 @@ class BuildSchema 'description' => $this->getDescription($value) ]; if (isset($value->defaultValue)) { - $config['defaultValue'] = Utils\AST::valueFromAST($value->defaultValue, $type); + $config['defaultValue'] = AST::valueFromAST($value->defaultValue, $type); } return $config; } diff --git a/src/Utils/MixedStore.php b/src/Utils/MixedStore.php index 76d5444..124dd70 100644 --- a/src/Utils/MixedStore.php +++ b/src/Utils/MixedStore.php @@ -1,6 +1,6 @@ $value) { + if (!property_exists($obj, $key)) { + $cls = get_class($obj); + Warning::warn( + "Trying to set non-existing property '$key' on class '$cls'", + Warning::ASSIGN_WARNING + ); + } + $obj->{$key} = $value; + } + return $obj; + } + + /** + * @param array|Traversable $traversable + * @param callable $predicate + * @return null + */ + public static function find($traversable, callable $predicate) + { + self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); + + foreach ($traversable as $key => $value) { + if ($predicate($value, $key)) { + return $value; + } + } + return null; + } + + /** + * @param $traversable + * @param callable $predicate + * @return array + * @throws \Exception + */ + public static function filter($traversable, callable $predicate) + { + self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); + + $result = []; + $assoc = false; + foreach ($traversable as $key => $value) { + if (!$assoc && !is_int($key)) { + $assoc = true; + } + if ($predicate($value, $key)) { + $result[$key] = $value; + } + } + + return $assoc ? $result : array_values($result); + } + + /** + * @param array|\Traversable $traversable + * @param callable $fn function($value, $key) => $newValue + * @return array + * @throws \Exception + */ + public static function map($traversable, callable $fn) + { + self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); + + $map = []; + foreach ($traversable as $key => $value) { + $map[$key] = $fn($value, $key); + } + return $map; + } + + /** + * @param $traversable + * @param callable $fn + * @return array + * @throws \Exception + */ + public static function mapKeyValue($traversable, callable $fn) + { + self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); + + $map = []; + foreach ($traversable as $key => $value) { + list($newKey, $newValue) = $fn($value, $key); + $map[$newKey] = $newValue; + } + return $map; + } + + /** + * @param $traversable + * @param callable $keyFn function($value, $key) => $newKey + * @return array + * @throws \Exception + */ + public static function keyMap($traversable, callable $keyFn) + { + self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); + + $map = []; + foreach ($traversable as $key => $value) { + $newKey = $keyFn($value, $key); + if (is_scalar($newKey)) { + $map[$newKey] = $value; + } + } + return $map; + } + + /** + * @param $traversable + * @param callable $fn + */ + public static function each($traversable, callable $fn) + { + self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); + + foreach ($traversable as $key => $item) { + $fn($item, $key); + } + } + + /** + * Splits original traversable to several arrays with keys equal to $keyFn return + * + * E.g. Utils::groupBy([1, 2, 3, 4, 5], function($value) {return $value % 3}) will output: + * [ + * 1 => [1, 4], + * 2 => [2, 5], + * 0 => [3], + * ] + * + * $keyFn is also allowed to return array of keys. Then value will be added to all arrays with given keys + * + * @param $traversable + * @param callable $keyFn function($value, $key) => $newKey(s) + * @return array + */ + public static function groupBy($traversable, callable $keyFn) + { + self::invariant(is_array($traversable) || $traversable instanceof \Traversable, __METHOD__ . ' expects array or Traversable'); + + $grouped = []; + foreach ($traversable as $key => $value) { + $newKeys = (array) $keyFn($value, $key); + foreach ($newKeys as $key) { + $grouped[$key][] = $value; + } + } + + return $grouped; + } + + public static function keyValMap($traversable, callable $keyFn, callable $valFn) + { + return array_reduce($traversable, function ($map, $item) use ($keyFn, $valFn) { + $map[$keyFn($item)] = $valFn($item); + return $map; + }, []); + } + + /** + * @param $traversable + * @param callable $predicate + * @return bool + */ + public static function every($traversable, callable $predicate) + { + foreach ($traversable as $key => $value) { + if (!$predicate($value, $key)) { + return false; + } + } + return true; + } + + /** + * @param $test + * @param string $message + * @param mixed $sprintfParam1 + * @param mixed $sprintfParam2 ... + * @throws \Exception + */ + public static function invariant($test, $message = '') + { + if (!$test) { + if (func_num_args() > 2) { + $args = func_get_args(); + array_shift($args); + $message = call_user_func_array('sprintf', $args); + } + throw new InvariantViolation($message); + } + } + + /** + * @param $var + * @return string + */ + public static function getVariableType($var) + { + if ($var instanceof Type) { + // FIXME: Replace with schema printer call + if ($var instanceof WrappingType) { + $var = $var->getWrappedType(true); + } + return $var->name; + } + return is_object($var) ? get_class($var) : gettype($var); + } + + /** + * @param $var + * @return string + */ + public static function printSafe($var) + { + if ($var instanceof Type) { + return $var->toString(); + } + if (is_object($var)) { + return 'instance of ' . get_class($var); + } + if ('' === $var) { + return '(empty string)'; + } + if (is_string($var)) { + return "\"$var\""; + } + if (is_scalar($var)) { + return (string) $var; + } + if (null === $var) { + return 'null'; + } + return gettype($var); + } + + /** + * UTF-8 compatible chr() + * + * @param string $ord + * @param string $encoding + * @return string + */ + public static function chr($ord, $encoding = 'UTF-8') + { + if ($ord <= 255) { + return chr($ord); + } + if ($encoding === 'UCS-4BE') { + return pack("N", $ord); + } else { + return mb_convert_encoding(self::chr($ord, 'UCS-4BE'), $encoding, 'UCS-4BE'); + } + } + + /** + * UTF-8 compatible ord() + * + * @param string $char + * @param string $encoding + * @return mixed + */ + public static function ord($char, $encoding = 'UTF-8') + { + if (!$char && '0' !== $char) { + return 0; + } + if (!isset($char[1])) { + return ord($char); + } + if ($encoding !== 'UCS-4BE') { + $char = mb_convert_encoding($char, 'UCS-4BE', $encoding); + } + list(, $ord) = unpack('N', $char); + return $ord; + } + + /** + * Returns UTF-8 char code at given $positing of the $string + * + * @param $string + * @param $position + * @return mixed + */ + public static function charCodeAt($string, $position) + { + $char = mb_substr($string, $position, 1, 'UTF-8'); + return self::ord($char); + } + + /** + * @param $code + * @return string + */ + public static function printCharCode($code) + { + if (null === $code) { + return ''; + } + return $code < 0x007F + // Trust JSON for ASCII. + ? json_encode(Utils::chr($code)) + // Otherwise print the escaped form. + : '"\\u' . dechex($code) . '"'; + } + + /** + * @param $name + * @param bool $isIntrospection + * @throws Error + */ + public static function assertValidName($name, $isIntrospection = false) + { + $regex = '/^[_a-zA-Z][_a-zA-Z0-9]*$/'; + + if (!$name || !is_string($name)) { + throw new InvariantViolation( + "Must be named. Unexpected name: " . self::printSafe($name) + ); + } + + if (!$isIntrospection && isset($name[1]) && $name[0] === '_' && $name[1] === '_') { + Warning::warnOnce( + 'Name "'.$name.'" must not begin with "__", which is reserved by ' . + 'GraphQL introspection. In a future release of graphql this will ' . + 'become an exception', + Warning::NAME_WARNING + ); + } + + if (!preg_match($regex, $name)) { + throw new InvariantViolation( + 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "'.$name.'" does not.' + ); + } + } +} diff --git a/src/Validator/DocumentValidator.php b/src/Validator/DocumentValidator.php index b5fae95..f00dfb9 100644 --- a/src/Validator/DocumentValidator.php +++ b/src/Validator/DocumentValidator.php @@ -15,7 +15,7 @@ use GraphQL\Type\Definition\LeafType; use GraphQL\Type\Definition\ListOfType; use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\Type; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use GraphQL\Utils\TypeInfo; use GraphQL\Validator\Rules\ArgumentsOfCorrectType; use GraphQL\Validator\Rules\DefaultValuesOfCorrectType; diff --git a/src/Validator/Rules/FieldsOnCorrectType.php b/src/Validator/Rules/FieldsOnCorrectType.php index 9051697..3382169 100644 --- a/src/Validator/Rules/FieldsOnCorrectType.php +++ b/src/Validator/Rules/FieldsOnCorrectType.php @@ -6,7 +6,7 @@ use GraphQL\Language\AST\FieldNode; use GraphQL\Language\AST\NodeKind; use GraphQL\Schema; use GraphQL\Type\Definition\AbstractType; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use GraphQL\Validator\ValidationContext; class FieldsOnCorrectType diff --git a/src/Validator/Rules/KnownArgumentNames.php b/src/Validator/Rules/KnownArgumentNames.php index a5694e9..b2dfdb8 100644 --- a/src/Validator/Rules/KnownArgumentNames.php +++ b/src/Validator/Rules/KnownArgumentNames.php @@ -4,7 +4,7 @@ namespace GraphQL\Validator\Rules; use GraphQL\Error\Error; use GraphQL\Language\AST\ArgumentNode; use GraphQL\Language\AST\NodeKind; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use GraphQL\Validator\ValidationContext; class KnownArgumentNames diff --git a/src/Validator/Rules/LoneAnonymousOperation.php b/src/Validator/Rules/LoneAnonymousOperation.php index 3a9ab6d..1d735b5 100644 --- a/src/Validator/Rules/LoneAnonymousOperation.php +++ b/src/Validator/Rules/LoneAnonymousOperation.php @@ -6,7 +6,7 @@ use GraphQL\Language\AST\DocumentNode; use GraphQL\Language\AST\Node; use GraphQL\Language\AST\NodeKind; use GraphQL\Language\AST\OperationDefinitionNode; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use GraphQL\Validator\ValidationContext; /** diff --git a/src/Validator/Rules/NoFragmentCycles.php b/src/Validator/Rules/NoFragmentCycles.php index d98ce9b..06d9f18 100644 --- a/src/Validator/Rules/NoFragmentCycles.php +++ b/src/Validator/Rules/NoFragmentCycles.php @@ -15,7 +15,7 @@ use GraphQL\Language\AST\FragmentSpreadNode; use GraphQL\Language\AST\Node; use GraphQL\Language\AST\NodeKind; use GraphQL\Language\Visitor; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use GraphQL\Validator\ValidationContext; class NoFragmentCycles diff --git a/src/Validator/Rules/OverlappingFieldsCanBeMerged.php b/src/Validator/Rules/OverlappingFieldsCanBeMerged.php index 2edcabe..8bc52d0 100644 --- a/src/Validator/Rules/OverlappingFieldsCanBeMerged.php +++ b/src/Validator/Rules/OverlappingFieldsCanBeMerged.php @@ -18,7 +18,7 @@ use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\OutputType; use GraphQL\Type\Definition\Type; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use GraphQL\Utils\PairSet; use GraphQL\Utils\TypeInfo; use GraphQL\Validator\ValidationContext; diff --git a/src/Validator/Rules/ProvidedNonNullArguments.php b/src/Validator/Rules/ProvidedNonNullArguments.php index ecc3d65..1fe8bfc 100644 --- a/src/Validator/Rules/ProvidedNonNullArguments.php +++ b/src/Validator/Rules/ProvidedNonNullArguments.php @@ -9,7 +9,7 @@ use GraphQL\Language\AST\Node; use GraphQL\Language\AST\NodeKind; use GraphQL\Language\Visitor; use GraphQL\Type\Definition\NonNull; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use GraphQL\Validator\ValidationContext; class ProvidedNonNullArguments diff --git a/src/Validator/Rules/VariablesAreInputTypes.php b/src/Validator/Rules/VariablesAreInputTypes.php index f44e889..4db3193 100644 --- a/src/Validator/Rules/VariablesAreInputTypes.php +++ b/src/Validator/Rules/VariablesAreInputTypes.php @@ -9,7 +9,7 @@ use GraphQL\Language\AST\VariableDefinitionNode; use GraphQL\Language\Printer; use GraphQL\Type\Definition\InputType; use GraphQL\Type\Definition\Type; -use GraphQL\Utils; +use GraphQL\Utils\TypeInfo; use GraphQL\Validator\ValidationContext; class VariablesAreInputTypes @@ -23,7 +23,7 @@ class VariablesAreInputTypes { return [ NodeKind::VARIABLE_DEFINITION => function(VariableDefinitionNode $node) use ($context) { - $type = Utils\TypeInfo::typeFromAST($context->getSchema(), $node->type); + $type = TypeInfo::typeFromAST($context->getSchema(), $node->type); // If the variable type is not an input type, return an error. if ($type && !Type::isInputType($type)) { diff --git a/tests/Executor/DeferredFieldsTest.php b/tests/Executor/DeferredFieldsTest.php index 27e3a2f..1c9cc06 100644 --- a/tests/Executor/DeferredFieldsTest.php +++ b/tests/Executor/DeferredFieldsTest.php @@ -9,7 +9,7 @@ use GraphQL\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\Type; -use GraphQL\Utils; +use GraphQL\Utils\Utils; class DeferredFieldsTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/Language/LexerTest.php b/tests/Language/LexerTest.php index 7ef80d3..3509b83 100644 --- a/tests/Language/LexerTest.php +++ b/tests/Language/LexerTest.php @@ -5,7 +5,7 @@ use GraphQL\Language\Lexer; use GraphQL\Language\Source; use GraphQL\Language\Token; use GraphQL\Error\SyntaxError; -use GraphQL\Utils; +use GraphQL\Utils\Utils; class LexerTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/Language/ParserTest.php b/tests/Language/ParserTest.php index b63b263..d829efc 100644 --- a/tests/Language/ParserTest.php +++ b/tests/Language/ParserTest.php @@ -13,7 +13,7 @@ use GraphQL\Language\Parser; use GraphQL\Language\Source; use GraphQL\Language\SourceLocation; use GraphQL\Error\SyntaxError; -use GraphQL\Utils; +use GraphQL\Utils\Utils; class ParserTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/Type/ConfigTest.php b/tests/Type/ConfigTest.php index 8ab3622..6746d2f 100644 --- a/tests/Type/ConfigTest.php +++ b/tests/Type/ConfigTest.php @@ -8,7 +8,7 @@ use GraphQL\Type\Definition\InputObjectType; use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; -use GraphQL\Utils; +use GraphQL\Utils\Utils; class ConfigTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/Type/DefinitionTest.php b/tests/Type/DefinitionTest.php index aa7c6fb..6ee89ed 100644 --- a/tests/Type/DefinitionTest.php +++ b/tests/Type/DefinitionTest.php @@ -13,7 +13,7 @@ use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\UnionType; -use GraphQL\Utils; +use GraphQL\Utils\Utils; class DefinitionTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/Utils/MixedStoreTest.php b/tests/Utils/MixedStoreTest.php index 9ebfe6f..3f2fe3e 100644 --- a/tests/Utils/MixedStoreTest.php +++ b/tests/Utils/MixedStoreTest.php @@ -2,7 +2,7 @@ namespace GraphQL\Tests\Utils; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use GraphQL\Utils\MixedStore; class MixedStoreTest extends \PHPUnit_Framework_TestCase diff --git a/tests/Utils/ValueFromAstTest.php b/tests/Utils/ValueFromAstTest.php index 755ca31..fc8870e 100644 --- a/tests/Utils/ValueFromAstTest.php +++ b/tests/Utils/ValueFromAstTest.php @@ -6,7 +6,7 @@ use GraphQL\Language\Parser; use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\InputObjectType; use GraphQL\Type\Definition\Type; -use GraphQL\Utils; +use GraphQL\Utils\Utils; use GraphQL\Utils\AST; class ValueFromAstTest extends \PHPUnit_Framework_TestCase diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php index cadb73d..46f4248 100644 --- a/tests/UtilsTest.php +++ b/tests/UtilsTest.php @@ -1,7 +1,7 @@