mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Remove TSqlSelectString and related dependency
This commit is contained in:
parent
ea930b8875
commit
a1eb191f57
@ -23,7 +23,6 @@
|
||||
"symfony/console": "^3.3||^4.0",
|
||||
"amphp/amp": "^2.1",
|
||||
"amphp/byte-stream": "^1.5",
|
||||
"phpmyadmin/sql-parser": "^5.0",
|
||||
"sebastian/diff": "^3.0"
|
||||
},
|
||||
"bin": ["psalm", "psalter", "psalm-language-server", "psalm-plugin"],
|
||||
@ -47,7 +46,8 @@
|
||||
"phpunit/phpunit": "^7.5 || ^8.0",
|
||||
"squizlabs/php_codesniffer": "3.4.0",
|
||||
"bamarni/composer-bin-plugin": "^1.2",
|
||||
"psalm/plugin-phpunit": "^0.6"
|
||||
"psalm/plugin-phpunit": "^0.6",
|
||||
"phpmyadmin/sql-parser": "^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-igbinary": "^2.0.5"
|
||||
|
@ -320,6 +320,13 @@ class Config
|
||||
*/
|
||||
public $after_statement_checks = [];
|
||||
|
||||
/**
|
||||
* Static methods to be called after method checks have completed
|
||||
*
|
||||
* @var class-string<Hook\StringInterpreterInterface>[]
|
||||
*/
|
||||
public $string_interpreters = [];
|
||||
|
||||
/**
|
||||
* Static methods to be called after classlike exists checks have completed
|
||||
*
|
||||
|
13
src/Psalm/Plugin/Hook/StringInterpreterInterface.php
Normal file
13
src/Psalm/Plugin/Hook/StringInterpreterInterface.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace Psalm\Plugin\Hook;
|
||||
|
||||
use Psalm\Type;
|
||||
|
||||
interface StringInterpreterInterface
|
||||
{
|
||||
/**
|
||||
* Called after a statement has been checked
|
||||
*/
|
||||
public static function getTypeFromValue(string $value
|
||||
) : ?Type\Atomic\TLiteralString;
|
||||
}
|
@ -112,5 +112,9 @@ class PluginRegistrationSocket implements RegistrationInterface
|
||||
if (is_subclass_of($handler, Hook\AfterAnalysisInterface::class)) {
|
||||
$this->config->after_analysis[$handler] = $handler;
|
||||
}
|
||||
|
||||
if (is_subclass_of($handler, Hook\StringInterpreterInterface::class)) {
|
||||
$this->config->string_interpreters[$handler] = $handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ use Psalm\Type\Atomic\TObject;
|
||||
use Psalm\Type\Atomic\TObjectWithProperties;
|
||||
use Psalm\Type\Atomic\TResource;
|
||||
use Psalm\Type\Atomic\TSingleLetter;
|
||||
use Psalm\Type\Atomic\TSqlSelectString;
|
||||
use Psalm\Type\Atomic\TString;
|
||||
use Psalm\Type\Atomic\TTrue;
|
||||
use Psalm\Type\Atomic\TVoid;
|
||||
@ -933,16 +932,10 @@ abstract class Type
|
||||
if ($value !== null) {
|
||||
$config = \Psalm\Config::getInstance();
|
||||
|
||||
if ($config->parse_sql && stripos($value, 'select ') !== false) {
|
||||
try {
|
||||
$parser = new \PhpMyAdmin\SqlParser\Parser($value);
|
||||
|
||||
if (!$parser->errors) {
|
||||
$type = new TSqlSelectString($value);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
if (strlen($value) < $config->max_string_length) {
|
||||
$type = new TLiteralString($value);
|
||||
if ($config->string_interpreters) {
|
||||
foreach ($config->string_interpreters as $string_interpreter) {
|
||||
if ($type = $string_interpreter::getTypeFromValue($value)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
25
tests/Config/Plugin/Hook/SqlStringProvider.php
Normal file
25
tests/Config/Plugin/Hook/SqlStringProvider.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace Psalm\Test\Config\Plugin\Hook;
|
||||
|
||||
use Psalm\Plugin\Hook\StringInterpreterInterface;
|
||||
use Psalm\Type\Atomic\TLiteralString;
|
||||
|
||||
class SqlStringProvider implements StringInterpreterInterface
|
||||
{
|
||||
public static function getTypeFromValue(string $value) : ?TLiteralString
|
||||
{
|
||||
if (stripos($value, 'select ') !== false) {
|
||||
try {
|
||||
$parser = new \PhpMyAdmin\SqlParser\Parser($value);
|
||||
|
||||
if (!$parser->errors) {
|
||||
return new StringProvider\TSqlSelectString($value);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
<?php
|
||||
namespace Psalm\Type\Atomic;
|
||||
|
||||
class TSqlSelectString extends TLiteralString
|
||||
namespace Psalm\Test\Config\Plugin\Hook\StringProvider;
|
||||
|
||||
class TSqlSelectString extends \Psalm\Type\Atomic\TLiteralString
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
@ -10,7 +11,6 @@ class TSqlSelectString extends TLiteralString
|
||||
{
|
||||
return 'sql-select-string';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@ -18,7 +18,6 @@ class TSqlSelectString extends TLiteralString
|
||||
{
|
||||
return 'sql-select-string(' . $this->value . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
18
tests/Config/Plugin/SqlStringProviderPlugin.php
Normal file
18
tests/Config/Plugin/SqlStringProviderPlugin.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace Psalm\Test\Config\Plugin;
|
||||
|
||||
use Psalm\Plugin;
|
||||
use SimpleXMLElement;
|
||||
|
||||
/** @psalm-suppress UnusedClass */
|
||||
class SqlStringProviderPlugin implements \Psalm\Plugin\PluginEntryPointInterface
|
||||
{
|
||||
/** @return void */
|
||||
public function __invoke(Plugin\RegistrationInterface $registration, SimpleXMLElement $config = null)
|
||||
{
|
||||
require_once __DIR__ . '/Hook/SqlStringProvider.php';
|
||||
require_once __DIR__ . '/Hook/StringProvider/TSqlSelectString.php';
|
||||
|
||||
$registration->registerHooksFromClass(Hook\SqlStringProvider::class);
|
||||
}
|
||||
}
|
@ -618,6 +618,46 @@ class PluginTest extends \Psalm\Tests\TestCase
|
||||
$this->analyzeFile($file_path, new Context());
|
||||
}
|
||||
|
||||
/** @return void */
|
||||
public function testSqlStringProviderHooks()
|
||||
{
|
||||
require_once __DIR__ . '/Plugin/SqlStringProviderPlugin.php';
|
||||
|
||||
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
||||
TestConfig::loadFromXML(
|
||||
dirname(__DIR__, 2) . DIRECTORY_SEPARATOR,
|
||||
'<?xml version="1.0"?>
|
||||
<psalm>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
</projectFiles>
|
||||
<plugins>
|
||||
<pluginClass class="Psalm\\Test\\Config\\Plugin\\SqlStringProviderPlugin" />
|
||||
</plugins>
|
||||
</psalm>'
|
||||
)
|
||||
);
|
||||
|
||||
$this->project_analyzer->getCodebase()->config->initializePlugins($this->project_analyzer);
|
||||
|
||||
$file_path = getcwd() . '/src/somefile.php';
|
||||
|
||||
$this->addFile(
|
||||
$file_path,
|
||||
'<?php
|
||||
$a = "select * from videos;";'
|
||||
);
|
||||
|
||||
$context = new Context();
|
||||
$this->analyzeFile($file_path, $context);
|
||||
|
||||
$this->assertTrue(isset($context->vars_in_scope['$a']));
|
||||
|
||||
foreach ($context->vars_in_scope['$a']->getTypes() as $type) {
|
||||
$this->assertInstanceOf(\Psalm\Test\Config\Plugin\Hook\StringProvider\TSqlSelectString::class, $type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return void
|
||||
|
@ -486,17 +486,6 @@ class ValueTest extends TestCase
|
||||
'assertions' => [],
|
||||
'error_levels' => ['MissingParamType', 'MixedAssignment'],
|
||||
],
|
||||
'sqlTypes' => [
|
||||
'<?php
|
||||
$a = "select * from foo";
|
||||
$b = "select * from";
|
||||
$c = "select * from foo where i = :i";',
|
||||
'assertions' => [
|
||||
'$a===' => 'sql-select-string(select * from foo)',
|
||||
'$b===' => 'string(select * from)',
|
||||
'$c===' => 'sql-select-string(select * from foo where i = :i)',
|
||||
],
|
||||
],
|
||||
'numericToStringComparison' => [
|
||||
'<?php
|
||||
/** @psalm-suppress MissingParamType */
|
||||
|
Loading…
Reference in New Issue
Block a user