public function getFQCN(Name $node = null) { if ($node === null) { return $node; } if ($node->isFullyQualified()) { return $this->parseFQCN($node->toString()); } $fqcn = $this->uses->find($node->getFirst()); if ($fqcn) { return $fqcn; } return $this->createFQCN($node->toString()); }
private function checkFunction(Name $name, FuncCall $node) { // check for a function inside the class namespace as well as imported // functions first. $func = $this->getContext()->getClassName($name->toString()); if (!function_exists($func)) { // get the plain function name without namespaces $func = $name->toString(); } // check if the function exists in the global namespace if (!function_exists($func)) { $this->addError($this->createUndefinedFunctionError($func, $node)); return; } $refl = new ReflectionFunction($func); $params = $refl->getParameters(); // it's not possible to check for default values/optionalness etc. on // internal functions if (!$refl->isInternal()) { // verify number of arguments if (count($node->args) > count($params)) { // cannot error on this as php functions can use func_get_args() } $requiredParams = 0; foreach ($params as $param) { if ($param->isOptional() || $param->isDefaultValueAvailable()) { break; } $requiredParams++; } if (count($node->args) < $requiredParams) { $this->addError($this->createNotEnoughParamsError($node, $func, $requiredParams)); } } // look for function parameters passed by reference foreach ($params as $param) { if ($param->isPassedByReference()) { $pos = $param->getPosition(); if (isset($node->args[$pos])) { $var = $node->args[$pos]->value; if ($var instanceof Variable) { $this->getContext()->setVariable($var->name, $var); } } } } }
protected function resolveClassName(PhpParser\Node\Name $name) { if ($name->isFullyQualified()) { return $name; } $old = $name->toString(); $resolved = parent::resolveClassName($name); $this->resolvedClasses[$old] = $resolved->toString(); return $resolved; }
/** * {@inheritdoc} */ public function isValidBetween(Name $from, Name $to) { $this->lastResult = $this->inspector->isAllowed($from->toString(), $to->toString()); if (!is_null($this->collector) && $this->lastResult->isDenied()) { $this->collector->major(new PolicyViolation($from, $to, $this->lastResult)); } if (!is_null($this->collector) && $this->lastResult->isUndefined()) { $this->collector->undefined(new PolicyViolation($from, $to, $this->lastResult)); } return $this->lastResult->isAllowed(); }
/** * @param Name $name * @return Vertex */ private function createVertexBy(Name $name) { $vertex = $this->getGraph()->createVertex($name->toString(), true); if ($groupId = $this->groupGenerator->getIdFor($name)) { $vertex->setGroup($groupId); $vertex->setAttribute('graphviz.group', $groupId); } $this->bindLayoutTo($vertex, $this->layout->getVertex()); return $vertex; }
/** * @param Name|string $name * * @return string */ private function getFullClassName($name) { if ($name instanceof Name) { if ($name->isFullyQualified()) { return $name->toString(); } } $name = (string) $name; if (isset($this->namespace->uses[$name])) { return $this->namespace->uses[$name]; } if ($this->namespace->name) { return $this->namespace->name . '\\' . $name; } return $name; }
/** * @param Node\Name $expr * @return CompiledExpression */ public function getNodeName(Node\Name $expr) { $nodeString = $expr->toString(); if ($nodeString === 'null') { return new CompiledExpression(CompiledExpression::NULL); } if (in_array($nodeString, ['parent'], true)) { /** @var ClassDefinition $scope */ $scope = $this->context->scope; assert($scope instanceof ClassDefinition); if ($scope->getExtendsClass()) { $definition = $scope->getExtendsClassDefinition(); if ($definition) { return new CompiledExpression(CompiledExpression::OBJECT, $definition); } } else { $this->context->notice('language_error', 'Cannot access parent:: when current class scope has no parent', $expr); } } if (in_array($nodeString, ['self', 'static'], true)) { return CompiledExpression::fromZvalValue($this->context->scope); } if (defined($nodeString)) { return CompiledExpression::fromZvalValue(constant($expr)); } return new CompiledExpression(CompiledExpression::STRING, $expr->toString()); }
/** * @param Node\Name $namespacedString */ public function addNamespacedString(Node\Name $namespacedString) { $this->namespacedStrings[$namespacedString->toString()] = $namespacedString; }
/** * Utility method to fetch reflection class instance by name * * Supports: * 'self' keyword * 'parent' keyword * not-FQN class names * * @param Node\Name $node Class name node * * @return bool|\ReflectionClass * * @throws ReflectionException */ private function fetchReflectionClass(Node\Name $node) { $className = $node->toString(); $isFQNClass = $node instanceof Node\Name\FullyQualified; if ($isFQNClass) { return new ReflectionClass($className); } if ('self' === $className) { if ($this->context instanceof \ReflectionClass) { return $this->context; } elseif (method_exists($this->context, 'getDeclaringClass')) { return $this->context->getDeclaringClass(); } } if ('parent' === $className) { if ($this->context instanceof \ReflectionClass) { return $this->context->getParentClass(); } elseif (method_exists($this->context, 'getDeclaringClass')) { return $this->context->getDeclaringClass()->getParentClass(); } } if (method_exists($this->context, 'getFileName')) { /** @var ReflectionFileNamespace|null $fileNamespace */ $fileName = $this->context->getFileName(); $namespaceName = $this->context->getNamespaceName(); $fileNamespace = new ReflectionFileNamespace($fileName, $namespaceName); return $fileNamespace->getClass($className); } throw new ReflectionException("Can not resolve class {$className}"); }
/** * @param Node\Name $usedTraitNamespace */ public function addUsedTraitNamespace(Node\Name $usedTraitNamespace) { $this->usedTraitNamespaces[$usedTraitNamespace->toString()] = $usedTraitNamespace; }
protected function resolveClassName(Name $name) { // don't resolve special class names if (in_array(strtolower($name->toString()), array('self', 'parent', 'static'))) { if (!$name->isUnqualified()) { $this->errorHandler->handleError(new Error(sprintf("'\\%s' is an invalid class name", $name->toString()), $name->getAttributes())); } return $name; } // fully qualified names are already resolved if ($name->isFullyQualified()) { return $name; } $aliasName = strtolower($name->getFirst()); if (!$name->isRelative() && isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName])) { // resolve aliases (for non-relative names) $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName]; return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes()); } // if no alias exists prepend current namespace return FullyQualified::concat($this->namespace, $name, $name->getAttributes()); }
/** * Rename a given name node. * * When $this->addAsUse, a new use statement is added for each name that is * not renamed. * * @param Name $name Name node to rename. * @param Meta $meta Node meta information. * @return Name Renamed node if renamed, otherwise original. */ private function rename(Name $name, Meta $meta) { $originalName = $name->toString(); // Skip references to self or parent. if ($originalName == "self" || $originalName == "parent") { return $name; } // Either add-as-use or fix uses. if ($this->addAsUse) { // Check if there is a existing rename. if (!$this->isRenamed($originalName) || $this->doNotReuse) { $scrambledName = $this->scrambleString($originalName . uniqid()); $this->renamed($originalName, $scrambledName); // A new use statement is needed for this rename. Add it to // the current namespace. if ($meta->namespace) { $key = $meta->namespace->name->toString(); } else { $key = ""; } if (!isset($this->inserts[$key])) { $this->inserts[$key] = []; } $this->inserts[$key][] = new UseStatement([new UseUse(new Name($originalName), $scrambledName)]); } return new Name($this->getNewName($originalName)); } else { // See if (a subset of) parts matches a renamed one. For instance, // A\B\C\D may have A\B renamed, which will eventually lead to // Renamed\C\D. $clonedName = clone $name; $removed = []; while ($clonedName->parts) { $originalName = $clonedName->toString(); if ($this->isRenamed($originalName)) { array_unshift($removed, $this->getNewName($originalName)); return new Name($removed); } // Remove one name from the parts list and try again. $removed[] = array_pop($clonedName->parts); } } // No luck. return $name; }
private function getQualifiedName(Name $type) { $parts = $type->parts; if ($type->isFullyQualified()) { $qualifiedName = "\\{$type->toString()}"; } else { if (isset($this->aliases[$parts[0]])) { $use = $this->aliases[$parts[0]]; $parts[0] = "\\" . $use->getName(); $use->markUsed(); } else { $parts[0] = $this->namespace . "\\" . $parts[0]; } $qualifiedName = implode("\\", $parts); } return $this->cannonicalize($qualifiedName); }
protected function resolveClassName(Name $name) { // don't resolve special class names if (in_array(strtolower($name->toString()), array('self', 'parent', 'static'))) { if (!$name->isUnqualified()) { throw new Error(sprintf("'\\%s' is an invalid class name", $name->toString()), $name->getLine()); } return $name; } // fully qualified names are already resolved if ($name->isFullyQualified()) { return $name; } $aliasName = strtolower($name->getFirst()); if (!$name->isRelative() && isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName])) { // resolve aliases (for non-relative names) $name->setFirst($this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName]); } elseif (null !== $this->namespace) { // if no alias exists prepend current namespace $name->prepend($this->namespace); } return new Name\FullyQualified($name->parts, $name->getAttributes()); }
/** * @param NodeInterface\Name $trait */ public function addTraitUseAlias(TraitUseAliasNode $adaptation, $trait) { if (is_null($adaptation->trait)) { $this->context->getReflection()->addTraitMethodAlias((string) $trait->toString(), (string) $adaptation->method, (string) $adaptation->newName); } else { $this->context->getReflection()->addTraitMethodAlias((string) $adaptation->trait->toString(), (string) $adaptation->method, (string) $adaptation->newName); } }
protected function handleScalarTypes(Name $name) { $scalarTypes = ['bool' => true, 'int' => true, 'float' => true, 'string' => true]; if (!$name->isUnqualified()) { return $name; } $lowerName = strtolower($name->toString()); return isset($scalarTypes[$lowerName]) ? $lowerName : $name; }
/** * @param Node\Name $name * @return bool */ private function excludes(Node\Name $name) { $isIgnored = false; if ($this->minDepth > 0) { $isIgnored = count($name->parts) < $this->minDepth; } if (!$isIgnored && $this->excludePattern) { $isIgnored = (bool) preg_match($this->excludePattern, $name->toString()); } return $isIgnored; }