Chris@13: inClass = false; Chris@13: } Chris@13: Chris@13: /** Chris@13: * @throws ErrorException if get_class or get_called_class is called without an object from outside a class Chris@13: * Chris@13: * @param Node $node Chris@13: */ Chris@13: public function enterNode(Node $node) Chris@13: { Chris@13: if ($node instanceof Class_ || $node instanceof Trait_) { Chris@13: $this->inClass = true; Chris@13: } elseif ($node instanceof FuncCall && !$this->inClass) { Chris@13: // We'll give any args at all (besides null) a pass. Chris@13: // Technically we should be checking whether the args are objects, but this will do for now. Chris@13: // Chris@13: // @todo switch this to actually validate args when we get context-aware code cleaner passes. Chris@13: if (!empty($node->args) && !$this->isNull($node->args[0])) { Chris@13: return; Chris@13: } Chris@13: Chris@13: // We'll ignore name expressions as well (things like `$foo()`) Chris@13: if (!($node->name instanceof Name)) { Chris@13: return; Chris@13: } Chris@13: Chris@17: $name = \strtolower($node->name); Chris@17: if (\in_array($name, ['get_class', 'get_called_class'])) { Chris@17: $msg = \sprintf('%s() called without object from outside a class', $name); Chris@13: throw new ErrorException($msg, 0, E_USER_WARNING, null, $node->getLine()); Chris@13: } Chris@13: } Chris@13: } Chris@13: Chris@13: /** Chris@13: * @param Node $node Chris@13: */ Chris@13: public function leaveNode(Node $node) Chris@13: { Chris@13: if ($node instanceof Class_) { Chris@13: $this->inClass = false; Chris@13: } Chris@13: } Chris@13: Chris@13: private function isNull(Node $node) Chris@13: { Chris@17: return $node->value instanceof ConstFetch && \strtolower($node->value->name) === 'null'; Chris@13: } Chris@13: }