/**
* @param Node $node
* A node to parse
*
* @return Context
* A new or an unchanged context resulting from
* parsing the node
*/
public function visitNew(Node $node) : Context
{
try {
$context_node = new ContextNode($this->code_base, $this->context, $node);
$method = $context_node->getMethod('__construct', false);
// Add a reference to each class this method
// could be called on
foreach ($context_node->getClassList() as $class) {
$class->addReference($this->context);
if ($class->isDeprecated()) {
$this->emitIssue(Issue::DeprecatedClass, $node->lineno ?? 0, (string) $class->getFQSEN(), $class->getContext()->getFile(), (string) $class->getContext()->getLineNumberStart());
}
}
$this->analyzeCallToMethod($this->code_base, $method, $node);
$class_list = $context_node->getClassList();
foreach ($class_list as $class) {
// Make sure we're not instantiating an abstract
// class
if ($class->isAbstract() && (!$this->context->isInClassScope() || $class->getFQSEN() != $this->context->getClassFQSEN())) {
$this->emitIssue(Issue::TypeInstantiateAbstract, $node->lineno ?? 0, (string) $class->getFQSEN());
}
// Make sure we're not instantiating an interface
if ($class->isInterface()) {
$this->emitIssue(Issue::TypeInstantiateInterface, $node->lineno ?? 0, (string) $class->getFQSEN());
}
}
} catch (IssueException $exception) {
Issue::maybeEmitInstance($this->code_base, $this->context, $exception->getIssueInstance());
} catch (\Exception $exception) {
// If we can't figure out what kind of a call
// this is, don't worry about it
return $this->context;
}
return $this->context;
}