1
0
Fork 0

don't use generator during iteration

pull/357/head
Sara Itani 2017-04-10 14:18:19 -07:00
parent b02c164c2b
commit 3d5d46d4e7
1 changed files with 92 additions and 65 deletions

View File

@ -27,6 +27,8 @@ class TolerantTreeAnalyzer implements TreeAnalyzerInterface {
private $diagnostics; private $diagnostics;
private $content;
/** /**
* TolerantTreeAnalyzer constructor. * TolerantTreeAnalyzer constructor.
* @param Tolerant\Parser $parser * @param Tolerant\Parser $parser
@ -45,73 +47,98 @@ class TolerantTreeAnalyzer implements TreeAnalyzerInterface {
// TODO - docblock errors // TODO - docblock errors
foreach ($this->stmts->getDescendantNodesAndTokens() as $node) { $this->collectDefinitionsAndReferences($this->stmts);
if ($node instanceof Tolerant\Node) { }
$fqn = $definitionResolver::getDefinedFqn($node);
// Only index definitions with an FQN (no variables) public function collectDefinitionsAndReferences(Tolerant\Node $stmts) {
if ($fqn !== null) { foreach ($stmts::CHILD_NAMES as $name) {
$this->definitionNodes[$fqn] = $node; $node = $stmts->$name;
$this->definitions[$fqn] = $this->definitionResolver->createDefinitionFromNode($node, $fqn);
if ($node === null) {
continue;
}
if (\is_array($node)) {
foreach ($node as $child) {
if ($child instanceof Tolerant\Node) {
$this->update($child);
}
}
continue;
}
if ($node instanceof Tolerant\Node) {
$this->update($node);
}
if (($_error = Tolerant\DiagnosticsProvider::checkDiagnostics($node)) !== null) {
$range = Tolerant\PositionUtilities::getRangeFromPosition($_error->start, $_error->length, $this->content);
$this->diagnostics[] = new Diagnostic(
$_error->message,
new Range(
new Position($range->start->line, $range->start->character),
new Position($range->end->line, $range->start->character)
)
);
}
}
}
public function update($node) {
$fqn = ($this->definitionResolver)::getDefinedFqn($node);
// Only index definitions with an FQN (no variables)
if ($fqn !== null) {
$this->definitionNodes[$fqn] = $node;
$this->definitions[$fqn] = $this->definitionResolver->createDefinitionFromNode($node, $fqn);
}
$parent = $node->parent;
if (!(
($node instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression
&& !(
$node->parent instanceof Tolerant\Node\Expression\CallExpression ||
$node->memberName instanceof Tolerant\Token
))
|| ($parent instanceof Tolerant\Node\Statement\NamespaceDefinition && $parent->name !== null && $parent->name->getStart() === $node->getStart()))
) {
$fqn = $this->definitionResolver->resolveReferenceNodeToFqn($node);
if ($fqn !== null) {
$this->addReference($fqn, $node);
if (
$node instanceof Tolerant\Node\QualifiedName
&& $node->isQualifiedName()
&& !($parent instanceof Tolerant\Node\Statement\NamespaceDefinition && $parent->name->getStart() === $node->getStart()
)
) {
// Add references for each referenced namespace
$ns = $fqn;
while (($pos = strrpos($ns, '\\')) !== false) {
$ns = substr($ns, 0, $pos);
$this->addReference($ns, $node);
}
} }
$parent = $node->parent; // Namespaced constant access and function calls also need to register a reference
if ( // to the global version because PHP falls back to global at runtime
($node instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression // http://php.net/manual/en/language.namespaces.fallback.php
&& !( if (TolerantDefinitionResolver::isConstantFetch($node) ||
$node->parent instanceof Tolerant\Node\Expression\CallExpression || ($parent instanceof Tolerant\Node\Expression\CallExpression
$node->memberName instanceof Tolerant\Token && !(
)) $node instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression
|| ($parent instanceof Tolerant\Node\Statement\NamespaceDefinition && $parent->name !== null && $parent->name->getStart() === $node->getStart()) ))) {
) { $parts = explode('\\', $fqn);
continue; if (count($parts) > 1) {
} $globalFqn = end($parts);
$fqn = $definitionResolver->resolveReferenceNodeToFqn($node); $this->addReference($globalFqn, $node);
if ($fqn !== null) { }
$this->addReference($fqn, $node); }
}
}
if ( $this->collectDefinitionsAndReferences($node);
$node instanceof Tolerant\Node\QualifiedName
&& $node->isQualifiedName()
&& !($parent instanceof Tolerant\Node\Statement\NamespaceDefinition && $parent->name->getStart() === $node->getStart()
)
) {
// Add references for each referenced namespace
$ns = $fqn;
while (($pos = strrpos($ns, '\\')) !== false) {
$ns = substr($ns, 0, $pos);
$this->addReference($ns, $node);
}
}
// Namespaced constant access and function calls also need to register a reference
// to the global version because PHP falls back to global at runtime
// http://php.net/manual/en/language.namespaces.fallback.php
if (TolerantDefinitionResolver::isConstantFetch($node) ||
($parent instanceof Tolerant\Node\Expression\CallExpression
&& !(
$node instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression
))) {
$parts = explode('\\', $fqn);
if (count($parts) > 1) {
$globalFqn = end($parts);
$this->addReference($globalFqn, $node);
}
}
}
}
if (($_error = Tolerant\DiagnosticsProvider::checkDiagnostics($node)) !== null) {
$range = Tolerant\PositionUtilities::getRangeFromPosition($_error->start, $_error->length, $content);
$this->diagnostics[] = new Diagnostic(
$_error->message,
new Range(
new Position($range->start->line, $range->start->character),
new Position($range->end->line, $range->start->character)
)
);
}
}
} }
public function getDiagnostics() { public function getDiagnostics() {