/** * Get parameter's type. * * @return lang.Type */ public function getType() { try { if ($c = $this->_reflect->getClass()) { return new XPClass($c); } } catch (\ReflectionException $e) { throw new ClassFormatException(sprintf('Typehint for %s::%s()\'s parameter "%s" cannot be resolved: %s', strtr($this->_details[0], '\\', '.'), $this->_details[1], $this->_reflect->getName(), $e->getMessage())); } if (!($details = XPClass::detailsForMethod($this->_reflect->getDeclaringClass(), $this->_details[1])) || !isset($details[DETAIL_ARGUMENTS][$this->_details[2]])) { // Cannot parse api doc, fall back to PHP native syntax. The reason for not doing // this the other way around is that we have "richer" information, e.g. "string[]", // where PHP simply knows about "arrays" (of whatever). if ($t = $this->_reflect->getType()) { return Type::forName((string) $t); } else { if (defined('HHVM_VERSION')) { return Type::forName($this->_reflect->getTypeText() ?: 'var'); } else { return Type::$VAR; } } } $t = rtrim(ltrim($details[DETAIL_ARGUMENTS][$this->_details[2]], '&'), '.'); if ('self' === $t) { return new XPClass($this->_details[0]); } else { return Type::forName($t); } }
/** * Define handler for a given condition * * @param var $type Either NULL, a string type reference or a `lang.Type` instance. * @param function(?): var $function * @return self */ public function when($type, $function) { if (null === $type) { $this->primitive[null] = self::$HANDLE->cast($function); } else { $t = $type instanceof Type ? $type : Type::forName($type); $name = $t->getName(); if (isset(self::$GETTYPE[$name])) { $this->primitive[self::$GETTYPE[$name]] = self::$HANDLE->cast($function); } else { $this->instance[] = new Conditional(new IsInstance($t), self::$HANDLE->cast($function)); } } return $this; }
/** * Gets field type * * @return lang.Type */ public function getType() { $raw = $this->_reflect->getDocComment(); if (false === $raw) { if ($details = \lang\XPClass::detailsForField($this->_reflect->getDeclaringClass()->getName(), $this->_reflect->getName())) { if (isset($details[DETAIL_ANNOTATIONS]['type'])) { return \lang\Type::forName($details[DETAIL_ANNOTATIONS]['type']); } } } else { if (preg_match('/@(var|type)\\s*([^\\r\\n]+)/', $raw, $matches)) { return \lang\Type::forName(ClassParser::typeIn($matches[2])); } } return \lang\Type::$VAR; }
/** * Get parameter's type. * * @return lang.Type */ public function getType() { try { if ($c = $this->_reflect->getClass()) { return new \lang\XPClass($c); } } catch (\ReflectionException $e) { throw new \lang\ClassFormatException(sprintf('Typehint for %s::%s()\'s parameter "%s" cannot be resolved: %s', strtr($this->_details[0], '\\', '.'), $this->_details[1], $this->_reflect->getName(), $e->getMessage())); } if (!($details = \lang\XPClass::detailsForMethod($this->_details[0], $this->_details[1])) || !isset($details[DETAIL_ARGUMENTS][$this->_details[2]])) { // Unknown or unparseable, return ANYTYPE return \lang\Type::$VAR; } if ('self' === ($t = ltrim($details[DETAIL_ARGUMENTS][$this->_details[2]], '&'))) { return new \lang\XPClass($this->_details[0]); } else { return \lang\Type::forName($t); } }
public function echoClass() { $class = self::define('class', 'EchoClass', null, '{ public static string[] echoArgs(string[] $args) { return $args; } }'); $this->assertEquals('SourceEchoClass', $class->getName()); $this->assertFalse($class->isInterface()); $this->assertFalse($class->isEnum()); with($method = $class->getMethod('echoArgs')); $this->assertEquals('echoArgs', $method->getName()); $this->assertEquals(MODIFIER_STATIC | MODIFIER_PUBLIC, $method->getModifiers()); $this->assertEquals(Type::forName('string[]'), $method->getReturnType()); with($params = $method->getParameters()); $this->assertEquals(1, sizeof($params)); $this->assertEquals(Type::forName('string[]'), $params[0]->getType()); $in = ['Hello', 'World']; $this->assertEquals($in, $method->invoke(null, [$in])); }
/** * Builds a stub instance for the specified type. * * @param string typeName * @param boolean overrideAll * @return lang.Object */ public function createMock($typeName, $overrideAll = true) { $type = Type::forName($typeName); if (!$type instanceof XPClass) { throw new IllegalArgumentException('Cannot mock other types than XPClass types.'); } $parentClass = null; $interfaces = [XPClass::forName('unittest.mock.IMock')]; if ($type->isInterface()) { $interfaces[] = $type; } else { $parentClass = $type; } $proxy = new MockProxyBuilder(); $proxy->setOverwriteExisting($overrideAll); $proxyClass = $proxy->createProxyClass(ClassLoader::getDefault(), $interfaces, $parentClass); $mock = $proxyClass->newInstance(new MockProxy()); $this->mocks[] = $mock; return $mock; }
/** * Maps reflection type * * @param php.ReflectionMethod|php.ReflectionParameter $reflect * @param string $name * @return php.Closure */ private function mapReflectionType($reflect, $name) { if ('self' === $name) { return function () use($reflect) { return new XPClass($reflect->getDeclaringClass()); }; } else { if ('parent' === $name) { return function () use($reflect) { if ($parent = $reflect->getDeclaringClass()->getParentClass()) { return new XPClass($parent); } throw new IllegalStateException('Cannot resolve parent type of class without parent'); }; } else { return function () use($name) { return Type::forName($name); }; } } }
/** Gets field type */ public function getType() : Type { if ($details = XPClass::detailsForField($this->_reflect->getDeclaringClass(), $this->_reflect->getName())) { if (isset($details[DETAIL_RETURNS])) { $type = $details[DETAIL_RETURNS]; } else { if (isset($details[DETAIL_ANNOTATIONS]['type'])) { $type = $details[DETAIL_ANNOTATIONS]['type']; } else { if (defined('HHVM_VERSION')) { $type = $this->_reflect->getTypeText() ?: 'var'; } else { return \lang\Type::$VAR; } } } if ('self' === $type) { return new XPClass($this->_reflect->getDeclaringClass()); } else { return \lang\Type::forName($type); } } return \lang\Type::$VAR; }
public function typeForName() { $this->assertInstanceOf(MapType::class, Type::forName('[:string]')); }
/** * Get error * * @param var type target type of deserialization, either a lang.Type or a string * @return var * @throws webservices.rest.RestException if the status code is > 399 */ public function error($type = null) { if (!$this->isError()) { throw new RestException('Expected an error but have ' . $this->response->statusCode() . ' ' . $this->response->message()); } if (null === $type) { $target = \lang\Type::$VAR; } else { if ($type instanceof \lang\Type) { $target = $type; } else { $target = \lang\Type::forName($type); } } if (null === $this->reader) { throw new \lang\IllegalArgumentException('Unknown content type "' . $this->headers['Content-Type'][0] . '"'); } return $this->handlePayloadOf($target); }
public function returns_is_resolved() { $this->assertEquals(Type::forName('lang.mirrors.Method'), $this->fixture('resolved')->returns()); }
public function typeForName() { $this->assertInstanceOf('lang.MapType', \lang\Type::forName('[:string]')); }
public function urlencoded_value() { $this->assertEquals(array('name' => 'Timm Friebe'), $this->fixture->deserialize($this->input('name=Timm%20Friebe'), Type::forName('[:string]'))); }
/** * Retrieve return type * * @return lang.Type */ public function getReturnType() { if (!($details = \lang\XPClass::detailsForMethod($this->_reflect->getDeclaringClass()->getName(), $this->_reflect->getName()))) { return \lang\Type::$VAR; } if (null === $details[DETAIL_RETURNS]) { return \lang\Type::$VAR; } else { if ('self' === ($t = ltrim($details[DETAIL_RETURNS], '&'))) { return new \lang\XPClass($this->_reflect->getDeclaringClass()); } else { return \lang\Type::forName($t); } } }
/** * Assert that a given object is a subclass of a specified class * * @param var type either a type name or a lang.Type instance * @param var var * @param string error default 'instanceof' * @return void */ public function assertInstanceOf($type, $var, $error = 'instanceof') { if (!$type instanceof \lang\Type) { $type = \lang\Type::forName($type); } $type->isInstance($var) || $this->fail($error, \xp::typeOf($var), $type->getName()); }
function typeof($arg) { if ($arg instanceof \lang\Generic) { return new \lang\XPClass($arg); } else { if (null === $arg) { return \lang\Type::$VOID; } else { if ($arg instanceof \Closure) { $r = new \ReflectionFunction($arg); $signature = []; foreach ($r->getParameters() as $param) { if ($param->isArray()) { $signature[] = \lang\Primitive::$ARRAY; } else { if ($param->isCallable()) { $signature[] = \lang\Primitive::$CALLABLE; } else { if (null === ($class = $param->getClass())) { $signature[] = \lang\Type::$VAR; } else { $signature[] = new \lang\XPClass($class); } } } } return new \lang\FunctionType($signature, \lang\Type::$VAR); } else { if (is_array($arg)) { return 0 === key($arg) ? \lang\ArrayType::forName('var[]') : \lang\MapType::forName('[:var]'); } else { return \lang\Type::forName(gettype($arg)); } } } } }
public function resourceType() { $this->assertEquals(Type::$VAR, Type::forName('resource')); }
public function memoryLimit() { $this->assertEquals(\lang\Primitive::$INT, \lang\Type::forName(gettype(Runtime::getInstance()->memoryLimit()))); }
public function typeForName() { $this->assertInstanceOf('lang.ArrayType', \lang\Type::forName('string[]')); }
public function partiallyClosedNS() { $this->assertEquals(Type::forName('net.xp_framework.unittest.core.generics.NSLookup<lang.Type, string>'), Type::forName('net.xp_framework.unittest.core.generics.NSTypeLookup<string>')->getParentclass()); }
public function type_determined_via_apidoc($comment, $expected) { $this->assertEquals(Type::forName($expected), $this->mirror('{ ' . $comment . ' public $fixture; }')->fields()->named('fixture')->type()); }
public function xmlContent() { $fixture = $this->fixtureWith(HttpConstants::STATUS_OK, '<issue><title>Found a bug</title></issue>', ['Content-Type' => 'text/xml']); $response = $fixture->execute(new RestRequest()); $this->assertEquals(['title' => 'Found a bug'], $response->data(Type::forName('[:var]'))); }
/** * Get a binding * * @param string|lang.Type $type * @param string $name * @return var or NULL if none exists */ public function get($type, $name = null) { $t = $type instanceof Type ? $type : Type::forName($type); if ($t instanceof TypeUnion) { foreach ($t->types() as $type) { if ($instance = $this->get($type, $name)) { return $instance; } } } else { if (self::$PROVIDER->isAssignableFrom($t)) { $literal = $t->genericArguments()[0]->literal(); if (isset($this->bindings[$literal][$name])) { return $this->bindings[$literal][$name]->provider($this); } } else { $literal = $t->literal(); if (isset($this->bindings[$literal][$name])) { return $this->bindings[$literal][$name]->resolve($this); } else { if (null === $name && $t instanceof XPClass && !($t->isInterface() || $t->getModifiers() & MODIFIER_ABSTRACT)) { return $this->newInstance($t); } } } } return null; }
/** * Map * * @param string $type * @return lang.Type */ public function map($type) { if ('self' === $type || 'HH\\this' === $type) { return new XPClass($this->reflect); } else { if ('parent' === $type) { return new XPClass($this->reflect->getParentClass()); } else { if ('array' === $type) { return Type::$ARRAY; } else { if ('callable' === $type) { return Type::$CALLABLE; } else { if ('HH\\mixed' === $type) { return Type::$VAR; } else { if (0 === strncmp($type, 'array<', 6)) { return $this->arrayType($type); } else { if (0 === strncmp($type, '(function', 9)) { return $this->functionType($type); } else { return Type::forName(ltrim(strtr($type, ['HH\\' => '']), '?')); } } } } } } } }
/** * Creates a new custom response * * @param int status * @param string body * @return net.xp_framework.unittest.webservices.rest.CustomRestResponse */ protected function newResponse($status, $body) { return new CustomRestResponse(new \peer\http\HttpResponse(new \io\streams\MemoryInputStream(sprintf("HTTP/1.1 %d Test\r\nContent-Type: application/json\r\nContent-Length: %d\r\n\r\n%s", $status, strlen($body), $body))), new ResponseReader(new RestJsonDeserializer(), new RestMarshalling()), \lang\Type::forName('[:var]')); }
/** * Tests whether this class is assignable from a given type * * <code> * // util.Date instanceof lang.Object * XPClass::forName('lang.Object')->isAssignableFrom('util.Date'); // TRUE * </code> * * @param var type * @return bool */ public function isAssignableFrom($type) { $t = $type instanceof Type ? $type : Type::forName($type); return $t instanceof self ? $t->name === $this->name || $t->reflect()->isSubclassOf($this->reflect()) : false; }
public function wildcard_types_cannot_be_instantiated() { Type::forName('util.collections.Vector<?>')->newInstance(); }
/** * Assert a given value is an instance of a given type * * @param string|lang.Type $type * @return self */ public function isInstanceOf($type) { return $this->is(new Instance($type instanceof Type ? $type : Type::forName($type))); }
/** * Adds a type marshaller * * @param var type either a full qualified type name or a type instance * @return webservices.rest.TypeMarshaller The added marshaller */ public function getMarshaller($type) { return $this->marshallers[$type instanceof Type ? $type : Type::forName($type)]; }
public function bool_primitive_typed_parameter_with_default() { $this->assertEquals(Type::forName('bool'), $this->method('fixture')->getParameter(6)->getType()); }