Fix misc. issues, add more test cases, update validation test
parent
4382821b8c
commit
54f385f9ec
|
@ -6,7 +6,8 @@ use Microsoft\PhpParser as Tolerant;
|
|||
use LanguageServer\Index\ReadableIndex;
|
||||
|
||||
class ParserResourceFactory {
|
||||
const PARSER_KIND = ParserKind::DIAGNOSTIC_TOLERANT_PHP_PARSER;
|
||||
const PARSER_KIND = ParserKind::TOLERANT_PHP_PARSER;
|
||||
|
||||
private static function getParserKind () {
|
||||
global $parserKind;
|
||||
return isset($parserKind) ? $parserKind : self::PARSER_KIND;
|
||||
|
|
|
@ -280,12 +280,14 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface
|
|||
$name = $node->getResolvedName();
|
||||
|
||||
if (($useClause = $node->getFirstAncestor(Tolerant\Node\NamespaceUseGroupClause::class, Tolerant\Node\Statement\NamespaceUseDeclaration::class)) !== null) {
|
||||
$name = (string)($name ?? $node->getText());
|
||||
$name = (string)($name ?? Tolerant\ResolvedName::buildName($node->nameParts, $node->getFileContents()));
|
||||
if ($useClause instanceof Tolerant\Node\NamespaceUseGroupClause) {
|
||||
$prefix = $useClause->parent->parent->namespaceName;
|
||||
$prefix = $prefix === null ? "" : $prefix->getText();
|
||||
|
||||
$name = $prefix . "\\" . $name;
|
||||
if ($prefix === null) {
|
||||
return null;
|
||||
}
|
||||
$prefixName = Tolerant\ResolvedName::buildName($prefix->nameParts, $useClause->getFileContents());
|
||||
$name = (string)$prefixName . "\\" . $name;
|
||||
|
||||
if ($useClause->functionOrConst === null) {
|
||||
$useClause = $node->getFirstAncestor(Tolerant\Node\Statement\NamespaceUseDeclaration::class);
|
||||
|
@ -449,12 +451,25 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface
|
|||
return
|
||||
(
|
||||
$node instanceof Tolerant\Node\QualifiedName &&
|
||||
($node->parent instanceof Tolerant\Node\Statement\ExpressionStatement || $node->parent instanceof Tolerant\Node\Expression || $node->parent instanceof Tolerant\Node\DelimitedList\ExpressionList) &&
|
||||
(
|
||||
// $node->parent instanceof Tolerant\Node\Statement\ExpressionStatement ||
|
||||
$node->parent instanceof Tolerant\Node\Expression ||
|
||||
$node->parent instanceof Tolerant\Node\DelimitedList\ExpressionList ||
|
||||
$node->parent instanceof Tolerant\Node\ArrayElement ||
|
||||
($node->parent instanceof Tolerant\Node\Parameter && $node->parent->default === $node) ||
|
||||
$node->parent instanceof Tolerant\Node\StatementNode ||
|
||||
$node->parent instanceof Tolerant\Node\CaseStatementNode
|
||||
) &&
|
||||
!(
|
||||
$node->parent instanceof Tolerant\Node\Expression\MemberAccessExpression || $node->parent instanceof Tolerant\Node\Expression\CallExpression ||
|
||||
$node->parent instanceof Tolerant\Node\Expression\MemberAccessExpression ||
|
||||
$node->parent instanceof Tolerant\Node\Expression\CallExpression ||
|
||||
$node->parent instanceof Tolerant\Node\Expression\ObjectCreationExpression ||
|
||||
$node->parent instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression || $node->parent instanceof Tolerant\Node\Expression\AnonymousFunctionCreationExpression ||
|
||||
($node->parent instanceof Tolerant\Node\Expression\BinaryExpression && $node->parent->operator->kind === Tolerant\TokenKind::InstanceOfKeyword)
|
||||
$node->parent instanceof Tolerant\Node\Expression\ScopedPropertyAccessExpression ||
|
||||
$node->parent instanceof Tolerant\Node\Expression\AnonymousFunctionCreationExpression ||
|
||||
(
|
||||
$node->parent instanceof Tolerant\Node\Expression\BinaryExpression &&
|
||||
$node->parent->operator->kind === Tolerant\TokenKind::InstanceOfKeyword
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -859,6 +874,7 @@ class TolerantDefinitionResolver implements DefinitionResolverInterface
|
|||
return new Types\Object_;
|
||||
}
|
||||
$className = (string)$class->getResolvedName();
|
||||
var_dump($className);
|
||||
if ($className === 'static') {
|
||||
return new Types\Static_;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ class TolerantTreeAnalyzer implements TreeAnalyzerInterface {
|
|||
|
||||
if (
|
||||
$node instanceof Tolerant\Node\QualifiedName
|
||||
&& $node->isQualifiedName()
|
||||
&& ($node->isQualifiedName() || $node->parent instanceof Tolerant\Node\NamespaceUseClause)
|
||||
&& !($parent instanceof Tolerant\Node\Statement\NamespaceDefinition && $parent->name->getStart() === $node->getStart()
|
||||
)
|
||||
) {
|
||||
|
|
|
@ -29,13 +29,13 @@ class ValidationTest extends TestCase
|
|||
foreach ($frameworks as $frameworkDir) {
|
||||
$frameworkName = basename($frameworkDir);
|
||||
if ($frameworkName !== "broken") {
|
||||
continue;
|
||||
// continue;
|
||||
}
|
||||
$iterator = new RecursiveDirectoryIterator(__DIR__ . "/../../validation/frameworks/" . $frameworkName);
|
||||
|
||||
foreach (new RecursiveIteratorIterator($iterator) as $file) {
|
||||
if (strpos(\strrev((string)$file), \strrev(".php")) === 0
|
||||
// && strpos((string)$file, "ConsoleIoTest.php")!== false
|
||||
// && strpos((string)$file, "taxonomy.php")!== false
|
||||
) {
|
||||
if ($file->getSize() < 100000) {
|
||||
$testProviderArray[$frameworkName . "::" . $file->getBasename()] = [$file->getPathname(), $frameworkName];
|
||||
|
@ -106,14 +106,15 @@ class ValidationTest extends TestCase
|
|||
$parserKinds = [ParserKind::PHP_PARSER, ParserKind::TOLERANT_PHP_PARSER];
|
||||
|
||||
$maxRecursion = [];
|
||||
$definitions = [];
|
||||
$instantiated = [];
|
||||
$types = [];
|
||||
$symbolInfo = [];
|
||||
$extend = [];
|
||||
$isGlobal = [];
|
||||
$documentation = [];
|
||||
$isStatic = [];
|
||||
|
||||
$definitions = null;
|
||||
$instantiated = null;
|
||||
$types = null;
|
||||
$symbolInfo = null;
|
||||
$extend = null;
|
||||
$isGlobal = null;
|
||||
$documentation = null;
|
||||
$isStatic = null;
|
||||
|
||||
foreach ($parserKinds as $kind) {
|
||||
echo ("=====================================\n");
|
||||
|
@ -128,8 +129,12 @@ class ValidationTest extends TestCase
|
|||
|
||||
try {
|
||||
$document = new PhpDocument($testCaseFile, $fileContents, $index, $parser, $docBlockFactory, $definitionResolver);
|
||||
} catch (\Exception $e) {
|
||||
continue;
|
||||
} catch (Exception $e) {
|
||||
if ($kind === $parserKinds[0]) {
|
||||
$this->markTestIncomplete("baseline parser failed: " . $e->getTraceAsString());
|
||||
}
|
||||
throw $e;
|
||||
|
||||
}
|
||||
|
||||
if ($document->getStmts() === null) {
|
||||
|
@ -157,21 +162,26 @@ class ValidationTest extends TestCase
|
|||
$docs[$defn->fqn] = $defn->documentation;
|
||||
$static[$defn->fqn] = $defn->isStatic;
|
||||
}
|
||||
if ($definitions !== null) {
|
||||
|
||||
if (isset($definitions[$testCaseFile])) {
|
||||
$this->assertEquals($definitions[$testCaseFile], $fqns, 'defn->fqn does not match');
|
||||
// $this->assertEquals($types[$testCaseFile], $currentTypes, "defn->type does not match");
|
||||
$this->assertEquals($instantiated[$testCaseFile], $canBeInstantiated, "defn->canBeInstantiated does not match");
|
||||
$this->assertEquals($extend[$testCaseFile], $extends, 'defn->extends does not match');
|
||||
$this->assertEquals($isGlobal[$testCaseFile], $global, 'defn->isGlobal does not match');
|
||||
$this->assertEquals($documentation[$testCaseFile], $docs, 'defn->documentation does not match');
|
||||
$this->assertEquals($isStatic[$testCaseFile], $static, 'defn->isStatic does not match');
|
||||
$this->assertEquals($definitions, $fqns, 'defn->fqn does not match');
|
||||
// $this->assertEquals($types, $currentTypes, "defn->type does not match");
|
||||
$this->assertEquals($instantiated, $canBeInstantiated, "defn->canBeInstantiated does not match");
|
||||
$this->assertEquals($extend, $extends, 'defn->extends does not match');
|
||||
$this->assertEquals($isGlobal, $global, 'defn->isGlobal does not match');
|
||||
$this->assertEquals($documentation, $docs, 'defn->documentation does not match');
|
||||
$this->assertEquals($isStatic, $static, 'defn->isStatic does not match');
|
||||
|
||||
$this->assertEquals($symbolInfo[$testCaseFile], $symbols, "defn->symbolInformation does not match");
|
||||
$this->assertEquals($symbolInfo, $symbols, "defn->symbolInformation does not match");
|
||||
|
||||
|
||||
// $skipped = ['false', 'true', 'null', 'FALSE', 'TRUE', 'NULL', 'parent', 'PARENT', 'self', 'static'];
|
||||
$skipped = [];
|
||||
$skipped = [
|
||||
'false', 'true', 'null', 'FALSE', 'TRUE', 'NULL',
|
||||
'__', // magic constants are treated as normal constants
|
||||
'Exception', // catch exception types missing from old definition resolver
|
||||
'Trait' // use Trait references are missing from old definition resolve
|
||||
];
|
||||
foreach ($this->getIndex($parserKinds[0], $frameworkName)->references as $key=>$value) {
|
||||
foreach ($skipped as $s) {
|
||||
if (strpos($key, $s) !== false) {
|
||||
|
@ -179,6 +189,13 @@ class ValidationTest extends TestCase
|
|||
}
|
||||
}
|
||||
}
|
||||
foreach ($this->getIndex($parserKinds[1], $frameworkName)->references as $key=>$value) {
|
||||
foreach ($skipped as $s) {
|
||||
if (strpos($key, $s) !== false) {
|
||||
unset($this->getIndex($parserKinds[1], $frameworkName)->references[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unset($this->getIndex($parserKinds[1])->references['__LINE__']);
|
||||
// unset($this->getIndex($parserKinds[1])->references['__FILE__']);
|
||||
|
@ -188,22 +205,31 @@ class ValidationTest extends TestCase
|
|||
// unset($this->getIndex($parserKinds[1])->references['Requests_Exception']);
|
||||
|
||||
try {
|
||||
|
||||
// $this->assertEquals($this->getIndex($parserKinds[0], $frameworkName)->references, $this->getIndex($parserKinds[1], $frameworkName)->references,
|
||||
// "references do not match");
|
||||
|
||||
$this->assertArraySubset($this->getIndex($parserKinds[0], $frameworkName)->references, $this->getIndex($parserKinds[1], $frameworkName)->references);
|
||||
var_dump(array_keys($this->getIndex($parserKinds[1], $frameworkName)->references));
|
||||
} catch (\Throwable $e) {
|
||||
// var_dump(array_keys($this->getIndex($parserKinds[1], $frameworkName)->references));
|
||||
}
|
||||
catch (\Throwable $e) {
|
||||
$this->assertEquals($this->getIndex($parserKinds[0], $frameworkName)->references, $this->getIndex($parserKinds[1], $frameworkName)->references,
|
||||
"references do not match");
|
||||
}
|
||||
finally {
|
||||
unset($this->index[$parserKinds[0]][$frameworkName]);
|
||||
unset($this->index[$parserKinds[1]][$frameworkName]);
|
||||
}
|
||||
}
|
||||
|
||||
$definitions[$testCaseFile] = $fqns;
|
||||
$types[$testCaseFile] = $currentTypes;
|
||||
$instantiated[$testCaseFile] = $canBeInstantiated;
|
||||
$symbolInfo[$testCaseFile] = $symbols;
|
||||
$extend[$testCaseFile] = $extends;
|
||||
$isGlobal[$testCaseFile] = $global;
|
||||
$documentation[$testCaseFile] = $docs;
|
||||
$isStatic[$testCaseFile] = $static;
|
||||
$definitions = $fqns;
|
||||
$types = $currentTypes;
|
||||
$instantiated = $canBeInstantiated;
|
||||
$symbolInfo = $symbols;
|
||||
$extend = $extends;
|
||||
$isGlobal = $global;
|
||||
$documentation = $docs;
|
||||
$isStatic = $static;
|
||||
|
||||
// $maxRecursion[$testCaseFile] = $definitionResolver::$maxRecursion;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace MyNamespace;
|
||||
switch ($a) {
|
||||
case A:
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace MyNamespace;
|
||||
|
||||
class A
|
||||
{
|
||||
public function suite()
|
||||
{
|
||||
return HI;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace MyNamespace;
|
||||
|
||||
try {
|
||||
|
||||
} catch (Exception $e) {
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Batch;
|
||||
|
||||
/**
|
||||
* Helper methods for the batch system.
|
||||
*/
|
||||
class Percentage {
|
||||
|
||||
/**
|
||||
* Formats the percent completion for a batch set.
|
||||
*
|
||||
* @param int $total
|
||||
* The total number of operations.
|
||||
* @param int $current
|
||||
* The number of the current operation. This may be a floating point number
|
||||
* rather than an integer in the case of a multi-step operation that is not
|
||||
* yet complete; in that case, the fractional part of $current represents the
|
||||
* fraction of the operation that has been completed.
|
||||
*
|
||||
* @return string
|
||||
* The properly formatted percentage, as a string. We output percentages
|
||||
* using the correct number of decimal places so that we never print "100%"
|
||||
* until we are finished, but we also never print more decimal places than
|
||||
* are meaningful.
|
||||
*
|
||||
* @see _batch_process()
|
||||
*/
|
||||
public static function format($total, $current) {
|
||||
if (!$total || $total == $current) {
|
||||
// If $total doesn't evaluate as true or is equal to the current set, then
|
||||
// we're finished, and we can return "100".
|
||||
$percentage = '100';
|
||||
}
|
||||
else {
|
||||
// We add a new digit at 200, 2000, etc. (since, for example, 199/200
|
||||
// would round up to 100% if we didn't).
|
||||
$decimal_places = max(0, floor(log10($total / 2.0)) - 1);
|
||||
do {
|
||||
// Calculate the percentage to the specified number of decimal places.
|
||||
$percentage = sprintf('%01.' . $decimal_places . 'f', round($current / $total * 100, $decimal_places));
|
||||
// When $current is an integer, the above calculation will always be
|
||||
// correct. However, if $current is a floating point number (in the case
|
||||
// of a multi-step batch operation that is not yet complete), $percentage
|
||||
// may be erroneously rounded up to 100%. To prevent that, we add one
|
||||
// more decimal place and try again.
|
||||
$decimal_places++;
|
||||
} while ($percentage == '100');
|
||||
}
|
||||
return $percentage;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace MyNamespace;
|
||||
if (A) {
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace B;
|
||||
|
||||
echo __FILE__;
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
namespace B;
|
||||
use LanguageServer\Protocol\{TextDocumentIdentifier, Position, ReferenceContext, Location, Range};
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace MyNamespace;
|
||||
function init(Hi $view)
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue