public function testFullyQualifiedFunctionName() { $this->assertFQSENEqual(FullyQualifiedFunctionName::make('\\Name\\Space', 'g'), '\\Name\\Space\\g'); $this->assertFQSENEqual(FullyQualifiedFunctionName::make('', 'g'), '\\g'); $this->assertFQSENEqual(FullyQualifiedGlobalConstantName::make('', 'g'), '\\g'); $this->assertFQSENEqual(FullyQualifiedFunctionName::fromFullyQualifiedString('\\g'), '\\g'); $this->assertFQSENEqual(FullyQualifiedFunctionName::fromStringInContext('g', $this->context), '\\g'); }
public static function createSchema() : Schema { $schema = new Schema('File', [new Column('file_path', Column::TYPE_STRING, true), new Column('modification_time', Column::TYPE_INT)]); $schema->addAssociation(new ListAssociation('FileClassFQSEN', Column::TYPE_STRING, function (File $file, array $class_fqsen_string_list) { $file->getFile()->setClassFQSENList(array_map(function (string $fqsen_string) { return FullyQualifiedClassName::fromFullyQualifiedString($fqsen_string); }, $class_fqsen_string_list)); }, function (File $file) { return array_map(function (FullyQualifiedClassName $fqsen) { return (string) $fqsen; }, $file->getFile()->getClassFQSENList()); })); $schema->addAssociation(new ListAssociation('FileMethodFQSEN', Column::TYPE_STRING, function (File $file, array $method_fqsen_string_list) { $file->getFile()->setMethodFQSENList(array_map(function (string $fqsen_string) { if (false !== strpos($fqsen_string, '::')) { return FullyQualifiedMethodName::fromFullyQualifiedString($fqsen_string); } else { return FullyQualifiedFunctionName::fromFullyQualifiedString($fqsen_string); } }, $method_fqsen_string_list)); }, function (File $file) { return array_map(function (FQSEN $fqsen) { return (string) $fqsen; }, $file->getFile()->getMethodFQSENList()); })); $schema->addAssociation(new ListAssociation('FilePropertyFQSEN', Column::TYPE_STRING, function (File $file, array $fqsen_string_list) { $file->getFile()->setPropertyFQSENList(array_map(function (string $fqsen_string) { if (false !== strpos($fqsen_string, '::')) { return FullyQualifiedPropertyName::fromFullyQualifiedString($fqsen_string); } else { return FullyQualifiedFunctionName::fromFullyQualifiedString($fqsen_string); } }, $fqsen_string_list)); }, function (File $file) { return array_map(function (FQSEN $fqsen) { return (string) $fqsen; }, $file->getFile()->getPropertyFQSENList()); })); $schema->addAssociation(new ListAssociation('FileConstantFQSEN', Column::TYPE_STRING, function (File $file, array $fqsen_string_list) { $file->getFile()->setConstantFQSENList(array_map(function (string $fqsen_string) { if (false !== strpos($fqsen_string, '::')) { return FullyQualifiedClassConstantName::fromFullyQualifiedString($fqsen_string); } else { return FullyQualifiedGlobalConstantName::fromFullyQualifiedString($fqsen_string); } }, $fqsen_string_list)); }, function (File $file) { return array_map(function (FQSEN $fqsen) { return (string) $fqsen; }, $file->getFile()->getConstantFQSENList()); })); return $schema; }
/** * @return array * A map from alias to target */ private function aliasTargetMapFromUseNode(Node $node, string $prefix = '') : array { assert($node->kind == \ast\AST_USE, 'Method takes AST_USE nodes'); $map = []; foreach ($node->children ?? [] as $child_node) { $target = $child_node->children['name']; if (empty($child_node->children['alias'])) { if (($pos = strrpos($target, '\\')) !== false) { $alias = substr($target, $pos + 1); } else { $alias = $target; } } else { $alias = $child_node->children['alias']; } // if AST_USE does not have any flags set, then its AST_USE_ELEM // children will (this will be for AST_GROUP_USE) if ($node->flags !== 0) { $target_node = $node; } else { $target_node = $child_node; } if ($target_node->flags == T_FUNCTION) { $parts = explode('\\', $target); $function_name = array_pop($parts); $target = FullyQualifiedFunctionName::make($prefix . '\\' . implode('\\', $parts), $function_name); } else { if ($target_node->flags == T_CONST) { $parts = explode('\\', $target); $name = array_pop($parts); $target = FullyQualifiedGlobalConstantName::make($prefix . '\\' . implode('\\', $parts), $name); } else { $target = FullyQualifiedClassName::fromFullyQualifiedString($prefix . '\\' . $target); } } $map[$alias] = [$target_node->flags, $target]; } return $map; }
/** * @param Node $node * The node where the constant was found * * @param string $name * The name of the constant * * @param Node|mixed $value * Either a node or a constant to be used as the value of * the constant. * * @param int $flags * Any flags on the definition of the constant * * @return void */ private function addConstant(Node $node, string $name, $value, int $flags = 0) { // Give it a fully-qualified name $fqsen = FullyQualifiedGlobalConstantName::fromStringInContext($name, $this->context); // Create the constant $constant = new GlobalConstant($this->context->withLineNumberStart($node->lineno ?? 0), $name, new UnionType(), $flags, $fqsen); $constant->setFutureUnionType(new FutureUnionType($this->code_base, $this->context, $value)); $this->code_base->addGlobalConstant($constant); }
/** * @return ClassConstant * Get the (non-class) constant associated with this node * in this context * * @throws NodeException * An exception is thrown if we can't understand the node * * @throws CodeBaseExtension * An exception is thrown if we can't find the given * class */ public function getConst() : ClassConstant { assert($this->node->kind === \ast\AST_CONST, "Node must be of type \\ast\\AST_CONST"); if ($this->node->children['name']->kind !== \ast\AST_NAME) { throw new NodeException($this->node, "Can't determine constant name"); } $constant_name = $this->node->children['name']->children['name']; $fqsen = FullyQualifiedGlobalConstantName::fromStringInContext($constant_name, $this->context); if (!$this->code_base->hasGlobalConstantWithFQSEN($fqsen)) { throw new IssueException(Issue::fromType(Issue::UndeclaredConstant)($this->context->getFile(), $this->node->lineno ?? 0, [$constant_name])); } return $this->code_base->getGlobalConstantByFQSEN($fqsen); }
/** * @param array * A map from column name to value * * @return Constant * An instance of the model derived from row data */ public static function fromRow(array $row) : Constant { list($scope, $name) = explode('|', $row['scope_name']); $constant = new Constant(new ConstantElement(unserialize(base64_decode($row['context'])), $row['name'], UnionType::fromFullyQualifiedString($row['type']), (int) $row['flags']), $scope, $name); if (false !== strpos($row['fqsen'], '::')) { $fqsen = FullyQualifiedClassConstantName::fromFullyQualifiedString($row['fqsen']); } else { $fqsen = FullyQualifiedGlobalConstantName::fromFullyQualifiedString($row['fqsen']); } $constant->getConstant()->setFQSEN($fqsen); return $constant; }