/** * Visit a node with kind `\ast\AST_CLASS` * * @param Node $node * A node to parse * * @return Context * A new or an unchanged context resulting from * parsing the node */ public function visitClass(Node $node) : Context { if ($node->flags & \ast\flags\CLASS_ANONYMOUS) { $class_name = AST::unqualifiedNameForAnonymousClassNode($node, $this->context); } else { $class_name = $node->name; } // This happens now and then and I have no idea // why. if (empty($class_name)) { return $this->context; } assert(!empty($class_name), "Class must have name in {$this->context}"); $class_fqsen = FullyQualifiedClassName::fromStringInContext($class_name, $this->context); // Hunt for an available alternate ID if necessary $alternate_id = 0; while ($this->code_base->hasClassWithFQSEN($class_fqsen)) { $class_fqsen = $class_fqsen->withAlternateId(++$alternate_id); } // Build the class from what we know so far $clazz = new Clazz($this->context->withLineNumberStart($node->lineno ?? 0)->withLineNumberEnd($node->endLineno ?? -1), $class_name, UnionType::fromStringInContext($class_name, $this->context), $node->flags ?? 0); // Override the FQSEN with the found alternate ID $clazz->setFQSEN($class_fqsen); // Add the class to the code base as a globally // accessible object $this->code_base->addClass($clazz); // Look to see if we have a parent class if (!empty($node->children['extends'])) { $parent_class_name = $node->children['extends']->children['name']; // Check to see if the name isn't fully qualified if ($node->children['extends']->flags & \ast\flags\NAME_NOT_FQ) { if ($this->context->hasNamespaceMapFor(T_CLASS, $parent_class_name)) { // Get a fully-qualified name $parent_class_name = (string) $this->context->getNamespaceMapFor(T_CLASS, $parent_class_name); } else { $parent_class_name = $this->context->getNamespace() . '\\' . $parent_class_name; } } // The name is fully qualified. Make sure it looks // like it is if (0 !== strpos($parent_class_name, '\\')) { $parent_class_name = '\\' . $parent_class_name; } $parent_fqsen = FullyQualifiedClassName::fromStringInContext($parent_class_name, $this->context); // Set the parent for the class $clazz->setParentClassFQSEN($parent_fqsen); } // Add any implemeneted interfaces if (!empty($node->children['implements'])) { $interface_list = AST::qualifiedNameList($this->context, $node->children['implements']); foreach ($interface_list as $name) { $clazz->addInterfaceClassFQSEN(FullyQualifiedClassName::fromFullyQualifiedString($name)); } } // Update the context to signal that we're now // within a class context. $context = $clazz->getContext()->withClassFQSEN($class_fqsen); return $context; }
private static function computeHasCustomFieldSerializer(Clazz $instanceType) { assert($instanceType != null); $qualifiedTypeName = $instanceType->getName(); $simpleSerializerName = $qualifiedTypeName . '_CustomFieldSerializer'; $customSerializer = self::getCustomFieldSerializer($simpleSerializerName); if ($customSerializer != null) { return $customSerializer; } $customSerializerClass = self::getCustomFieldSerializer(self::JRE_SERIALIZER_PACKAGE . '.' . $simpleSerializerName); if (!is_null($customSerializerClass)) { return $customSerializerClass; } return null; }
function testArrayIndexGraphDereferencedFromStaticMethodCall() { $x = Clazz::method()[42]; return pow($x, 2); }
private static function printTypeName(Clazz $type) { // Primitives // if ($type === Integer::typeClass()) { return 'int'; } else { if ($type === Long::typeClass()) { return 'long'; } else { if ($type === Short::typeClass()) { return 'short'; } else { if ($type === Byte::typeClass()) { return 'byte'; } else { if ($type === Character::typeClass()) { return 'char'; } else { if ($type === Boolean::typeClass()) { return 'boolean'; } else { if ($type === Float::typeClass()) { return 'float'; } else { if ($type === Double::typeClass()) { return 'double'; } } } } } } } } // Arrays // if ($type->isArray()) { $componentType = $type->getComponentType(); return self::printTypeName($componentType) . '[]'; } // Everything else // return str_replace('$', '.', $type->getName()); }
private function serializeWithCustomSerializer(Clazz $customSerializer, $instance, Clazz $instanceClass, Clazz $manuallySerializedType) { assert(!$instanceClass->isArray()); foreach ($customSerializer->getMethods() as $method) { if ($method->getName() === 'serialize') { assert($method->isStatic()); $toReturn = new InvokeCustomFieldSerializerCommand($instanceClass, $customSerializer, $manuallySerializedType); $this->identityMap->put($instance, $toReturn); $subWriter = new CommandServerSerializationStreamWriter(new HasValuesCommandSink($toReturn), $this->clientOracle, $this->identityMap); $method->invoke($subWriter, $instance); return $toReturn; } } throw new NoSuchMethodException('Could not find serialize method in custom serializer ' . $customSerializer->getName()); }
private function validateTypeVersions(Clazz $instanceClass, SerializedInstanceReference $serializedInstRef) { $clientTypeSignature = $serializedInstRef->getSignature(); if (empty($clientTypeSignature)) { throw new SerializationException('Missin type signature for "' . $instanceClass->getFullName() . '"'); } $serverTypeSignature = SerializabilityUtilEx::getSerializationSignature($instanceClass, $this->serializationPolicy); if ($clientTypeSignature !== $serverTypeSignature) { throw new SerializationException('Invalid type signature for "' . $instanceClass->getFullName() . '"'); } }
<?php namespace nspace; class Clazz { function method() { throw new \InvalidArgumentException('Lorem ipsum...', 123); } } $obj = new Clazz(); $obj->method();
private function serializeWithCustomSerializer(Clazz $customSerializer, $instance, Clazz $instanceClass) { assert(!$instanceClass->isArray()); foreach ($customSerializer->getMethods() as $method) { if ($method->getName() === 'serialize') { $method->invoke($this, $instance); return; } } throw new NoSuchMethodException('serialize'); }
public function subClassOf(Clazz $clazz) { return $this->reflect->isSubclassOf($clazz->getName()); }
function testGraphDereferencedArrayFromStaticMethodCallAndMultipleMethodInvocations() { return Clazz::foo(23)[42]->bar()[17]->baz()[0]; }
public function getFieldName(Clazz $clazz, $fieldId) { while ($clazz != null) { if ($clazz->hasField($fieldId)) { return (object) array('class' => $clazz, 'fieldName' => $fieldId); } $clazz = $clazz->getSuperClass(); } return null; //return (object) array('class' => $clazz, 'fieldName' => $fieldId); }
$v = BITMASK; } $end = microtime(true) * 1000; $results["Constant assignments: %fms"] = $end - $start; $start = microtime(true) * 1000; for ($a = 0; $a < LIMIT; ++$a) { $v = Clazz::BITMASK; } $end = microtime(true) * 1000; $results["Class constant assignments: %fms"] = $end - $start; $start = microtime(true) * 1000; for ($a = 0; $a < LIMIT; ++$a) { $v = 1; } $end = microtime(true) * 1000; $results["Value assignments (integer syntax): %fms"] = $end - $start; $start = microtime(true) * 1000; for ($a = 0; $a < LIMIT; ++$a) { $v = 0b1; } $end = microtime(true) * 1000; $results["Value assignments (binary syntax): %fms"] = $end - $start; Clazz::staticVariableAssignment($results); Clazz::variableAssignment($results); Clazz::constantAssignmentStatic($results); Clazz::constantAssignmentSelf($results); Clazz::constantAssignmentFq($results); asort($results); foreach ($results as $description => $result) { printf($description . "\n", $result); }
private function isInstantiable(Clazz $clazz) { if ($clazz->isPrimitive()) { return true; } if ($clazz->isArray()) { return $this->isInstantiable($clazz->getComponentType()); } if (Classes::classOf('IsSerializable')->isAssignableFrom($clazz)) { return true; } return Serializability::hasCustomFieldSerializer($clazz) != null; }
private function canonicalName(Clazz $clazz) { if ($clazz->isArray()) { $leafType = $clazz; do { $leafType = $leafType->getComponentType(); } while ($leafType->isArray()); $enclosing = $leafType->getEnclosingClass(); if (!is_null($enclosing)) { // com.foo.Enclosing$Name[] return $this->canonicalName($enclosing) . '$' . $clazz->getName(); } else { if ($leafType->getPackage() === '') { // Name0[ return $clazz->getName(); } else { // com.foo.Name[] return $leafType->getPackage() . '.' . $clazz->getName(); } } } else { return $clazz->getFullName(); } }
public function writeValue(Clazz $clazz, $instance) { if ($clazz === Boolean::typeClass()) { $this->writeObject(new Boolean($instance)); } else { if ($clazz === Byte::typeClass()) { $this->writeObject(new Byte($instance)); } else { if ($clazz === Character::typeClass()) { $this->writeObject(new Character($instance)); } else { if ($clazz === Double::typeClass()) { $this->writeObject(new Double($instance)); } else { if ($clazz === Float::typeClass()) { $this->writeObject(new Float($instance)); } else { if ($clazz === Integer::typeClass()) { $this->writeObject(new Integer($instance)); } else { if ($clazz === Long::typeClass()) { $this->writeObject(new Long($instance)); } else { if ($clazz === Short::typeClass()) { $this->writeObject(new Short($instance)); } else { if ($clazz === String::clazz()) { $this->writeString($instance); } else { if ($clazz->isEnum()) { $this->writeEnum($clazz, $instance); } else { $this->writeObject($instance); } } } } } } } } } } }
private function getJavahSignatureName(Clazz $clazz) { if ($clazz->isArray()) { $leafType = $clazz; $dims = 0; do { $dims++; $leafType = $leafType->getComponentType(); } while (!is_null($leafType->getComponentType())); assert($dims > 0); $s = $this->getJavahSignatureName($leafType); for ($i = 0; $i < $dims; ++$i) { $s = '_3' . $s; } return $s; } else { if ($clazz->isPrimitive()) { return WebModeClientOracle::jsniName($clazz); } else { $name = $clazz->getFullName(); $name = str_replace('_', '_1', $name); $name = str_replace('.', '_', $name); return 'L' . $name . '_2'; } } }
public static function getSerializedTypeName(Clazz $instanceType) { if ($instanceType->isPrimitive()) { return self::$SERIALIZED_PRIMITIVE_TYPE_NAMES->get($instanceType->getFullName()); } return $instanceType->getFullName(); }