protected function buildObjectType($typeId, $classType)
{
$typeData = $this->getObjectTypeData($classType);
$methodReturnTypeMap = $typeData['methods'];
$fieldTypeMap = $typeData['fields'];
$staticFieldTypeMap = $typeData['static-fields'];
$reflection = new \ReflectionClass($classType);
$constructor = new Constructor($this, $typeId, $reflection->getConstructor());
$methods = [];
$fields = [];
$indexer = null;
$invoker = null;
$unaryOperations = $this->buildTypeOperations($this->objectUnaryOperations($typeId));
$casts = $this->buildTypeOperations($this->objectCasts($typeId));
$parentTypes = array_map([$this, 'getObjectType'], $reflection->getInterfaceNames());
if ($parentClass = $reflection->getParentClass()) {
$parentTypes[] = $this->getObjectType($parentClass->getName());
}
$parentType = $this->getCompositeType($parentTypes);
if ($reflection->hasMethod('__toString')) {
$methodReturnTypeMap += ['__toString' => INativeType::TYPE_STRING];
}
foreach ($methodReturnTypeMap as $name => $type) {
$methods[$name] = new Method($this, $typeId, $reflection->getMethod($name), $type);
}
foreach ($reflection->getMethods() as $method) {
if ($method->getDeclaringClass()->getName() === $classType && !isset($methods[$method->getName()])) {
$methods[$method->getName()] = new Method($this, $typeId, $method, INativeType::TYPE_MIXED);
}
}
foreach ($staticFieldTypeMap + $fieldTypeMap as $name => $type) {
$fields[$name] = new Field($this, $typeId, $name, isset($staticFieldTypeMap[$name]), $type);
}
foreach ($reflection->getProperties() as $field) {
if ($field->getDeclaringClass()->getName() === $classType && !isset($fields[$field->getName()])) {
$fields[$field->getName()] = new Field($this, $typeId, $field->getName(), $field->isStatic(), INativeType::TYPE_MIXED);
}
}
if ($reflection->implementsInterface('ArrayAccess') && isset($methods['offsetGet'])) {
$indexer = $methods['offsetGet'];
}
if (isset($methods['__invoke'])) {
$invoker = $methods['__invoke'];
}
if (isset($methods['__toString'])) {
$casts[Operators\Cast::STRING] = $methods['__toString'];
}
return new ObjectType($typeId, $reflection, $parentType, $constructor, $methods, $fields, $unaryOperations, $casts, $invoker, $indexer);
}