/** * @param string[] $function_name_list * A list of function names to load type information for */ private function addFunctionsByNames(array $function_name_list) { foreach ($function_name_list as $i => $function_name) { foreach (FunctionFactory::functionListFromName($this, $function_name) as $method) { $this->addMethod($method); } } }
/** * @param string $scope * The scope of the method or function * * @param string $name * The name of the method (with an optional alternate id) * * @return bool */ private function hasMethodWithScopeAndName(string $scope, string $name) { if (!empty($this->method_map[$scope][$name])) { return true; } // For elements in the root namespace, check to see if // there's a static method signature for something that // hasn't been loaded into memory yet and create a // method out of it as its requested if ('\\' == $scope) { $function_signature_map = UnionType::internalFunctionSignatureMap(); $fqsen = FullyQualifiedFunctionName::make($scope, $name); if (!empty($function_signature_map[$name])) { $signature = $function_signature_map[$name]; // Add each method returned for the signature foreach (FunctionFactory::functionListFromSignature($this, $fqsen, $signature) as $method) { $this->addMethod($method); } return true; } } if (Database::isEnabled()) { // Otherwise, check the database try { MethodModel::read(Database::get(), $scope . '|' . $name); return true; } catch (NotFoundException $exception) { return false; } } else { return false; } }
/** * @param FullyQualifiedFunctionName * The FQSEN of a function we'd like to look up * * @return bool * If the FQSEN represents an internal function that * hasn't been loaded yet, true is returned. */ private function hasInternalFunctionWithFQSEN(FullyQualifiedFunctionName $fqsen) : bool { // Only root namespaced functions will be found in // the internal function map. if ($fqsen->getNamespace() != '\\') { return false; } // For elements in the root namespace, check to see if // there's a static method signature for something that // hasn't been loaded into memory yet and create a // method out of it as its requested $function_signature_map = UnionType::internalFunctionSignatureMap(); if (!empty($function_signature_map[$fqsen->getNameWithAlternateId()])) { $signature = $function_signature_map[$fqsen->getNameWithAlternateId()]; // Add each method returned for the signature foreach (FunctionFactory::functionListFromSignature($this, $fqsen, $signature) as $i => $function) { $this->addFunction($function); } return true; } return false; }
/** * @param CodeBase $code_base * A reference to the entire code base in which this * context exists * * @param ReflectionClass $class * A reflection class representing a builtin class. * * @return Clazz * A Class structural element representing the given named * builtin. */ public static function fromReflectionClass(CodeBase $code_base, \ReflectionClass $class) : Clazz { // Build a set of flags based on the constitution // of the built-in class $flags = 0; if ($class->isFinal()) { $flags = \ast\flags\CLASS_FINAL; } elseif ($class->isInterface()) { $flags = \ast\flags\CLASS_INTERFACE; } elseif ($class->isTrait()) { $flags = \ast\flags\CLASS_TRAIT; } if ($class->isAbstract()) { $flags |= \ast\flags\CLASS_ABSTRACT; } $context = new Context(); $class_fqsen = FullyQualifiedClassName::fromStringInContext($class->getName(), $context); // Build a base class element $clazz = new Clazz($context, $class->getName(), UnionType::fromStringInContext($class->getName(), $context), $flags, $class_fqsen); // If this class has a parent class, add it to the // class info if ($parent_class = $class->getParentClass()) { $parent_class_fqsen = FullyQualifiedClassName::fromFullyQualifiedString('\\' . $parent_class->getName()); $parent_type = $parent_class_fqsen->asType(); $clazz->setParentType($parent_type); } // n.b.: public properties on internal classes don't get // listed via reflection until they're set unless // they have a default value. Therefore, we don't // bother iterating over `$class->getProperties()` // `$class->getStaticProperties()`. foreach ($class->getDefaultProperties() as $name => $value) { $property_context = $context->withScope(new ClassScope(new GlobalScope(), $clazz->getFQSEN())); $property_fqsen = FullyQualifiedPropertyName::make($clazz->getFQSEN(), $name); $property = new Property($property_context, $name, Type::fromObject($value)->asUnionType(), 0, $property_fqsen); $clazz->addProperty($code_base, $property, new None()); } foreach (UnionType::internalPropertyMapForClassName($clazz->getName()) as $property_name => $property_type_string) { $property_context = $context->withScope(new ClassScope(new GlobalScope(), $clazz->getFQSEN())); $property_type = UnionType::fromStringInContext($property_type_string, new Context()); $property_fqsen = FullyQualifiedPropertyName::make($clazz->getFQSEN(), $property_name); $property = new Property($property_context, $property_name, $property_type, 0, $property_fqsen); $clazz->addProperty($code_base, $property, new None()); } foreach ($class->getInterfaceNames() as $name) { $clazz->addInterfaceClassFQSEN(FullyQualifiedClassName::fromFullyQualifiedString('\\' . $name)); } foreach ($class->getTraitNames() as $name) { $clazz->addTraitFQSEN(FullyQualifiedClassName::fromFullyQualifiedString('\\' . $name)); } foreach ($class->getConstants() as $name => $value) { $constant_fqsen = FullyQualifiedClassConstantName::make($clazz->getFQSEN(), $name); $constant = new ClassConstant($context, $name, Type::fromObject($value)->asUnionType(), 0, $constant_fqsen); $clazz->addConstant($code_base, $constant); } foreach ($class->getMethods() as $reflection_method) { $method_context = $context->withScope(new ClassScope(new GlobalScope(), $clazz->getFQSEN())); $method_list = FunctionFactory::methodListFromReflectionClassAndMethod($method_context, $code_base, $class, $reflection_method); foreach ($method_list as $method) { $clazz->addMethod($code_base, $method, new None()); } } return $clazz; }
/** * @param CodeBase $code_base * A reference to the entire code base in which this * context exists * * @param ReflectionClass $class * A reflection class representing a builtin class. * * @return Clazz * A Class structural element representing the given named * builtin. */ public static function fromReflectionClass(CodeBase $code_base, \ReflectionClass $class) : Clazz { // Build a set of flags based on the constitution // of the built-in class $flags = 0; if ($class->isFinal()) { $flags = \ast\flags\CLASS_FINAL; } elseif ($class->isInterface()) { $flags = \ast\flags\CLASS_INTERFACE; } elseif ($class->isTrait()) { $flags = \ast\flags\CLASS_TRAIT; } if ($class->isAbstract()) { $flags |= \ast\flags\CLASS_ABSTRACT; } $context = new Context(); // Build a base class element $clazz = new Clazz($context, $class->getName(), UnionType::fromStringInContext($class->getName(), $context), $flags); $clazz->setFQSEN(FullyQualifiedClassName::fromStringInContext($class->getName(), $context)); // If this class has a parent class, add it to the // class info if ($parent_class = $class->getParentClass()) { $parent_class_fqsen = FullyQualifiedClassName::fromFullyQualifiedString('\\' . $parent_class->getName()); $clazz->setParentClassFQSEN($parent_class_fqsen); } foreach ($class->getDefaultProperties() as $name => $value) { // TODO: whats going on here? $reflection_property = new \ReflectionProperty($class->getName(), $name); $property_context = $context->withClassFQSEN($clazz->getFQSEN()); $property = new Property($property_context, $name, Type::fromObject($value)->asUnionType(), 0); $property->setFQSEN(FullyQualifiedPropertyName::make($clazz->getFQSEN(), $name)); $clazz->addProperty($code_base, $property); } foreach ($class->getInterfaceNames() as $name) { $clazz->addInterfaceClassFQSEN(FullyQualifiedClassName::fromFullyQualifiedString('\\' . $name)); } foreach ($class->getTraitNames() as $name) { $clazz->addTraitFQSEN(FullyQualifiedClassName::fromFullyQualifiedString('\\' . $name)); } foreach ($class->getConstants() as $name => $value) { $constant = new ClassConstant($context, $name, Type::fromObject($value)->asUnionType(), 0); $constant->setFQSEN(FullyQualifiedClassConstantName::make($clazz->getFQSEN(), $name)); $clazz->addConstant($code_base, $constant); } foreach ($class->getMethods() as $reflection_method) { $method_list = FunctionFactory::methodListFromReflectionClassAndMethod($context->withClassFQSEN($clazz->getFQSEN()), $code_base, $class, $reflection_method); foreach ($method_list as $method) { $clazz->addMethod($code_base, $method); } } return $clazz; }