mirror of
https://github.com/dg/dibi.git
synced 2025-08-06 06:07:39 +02:00
DibiObject: shows suggestions for undeclared members
This commit is contained in:
@@ -92,6 +92,26 @@ class DibiHelpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the best suggestion.
|
||||||
|
* @return string|NULL
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public static function getSuggestion(array $items, $value)
|
||||||
|
{
|
||||||
|
$best = NULL;
|
||||||
|
$min = (int) (strlen($value) / 4) + 2;
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$item = is_object($item) ? $item->getName() : $item;
|
||||||
|
if (($len = levenshtein($item, $value)) > 0 && $len < $min) {
|
||||||
|
$min = $len;
|
||||||
|
$best = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $best;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
public static function escape($driver, $value, $type)
|
public static function escape($driver, $value, $type)
|
||||||
{
|
{
|
||||||
|
@@ -27,7 +27,9 @@ trait DibiStrict
|
|||||||
return call_user_func_array($cb, $args);
|
return call_user_func_array($cb, $args);
|
||||||
}
|
}
|
||||||
$class = method_exists($this, $name) ? 'parent' : get_class($this);
|
$class = method_exists($this, $name) ? 'parent' : get_class($this);
|
||||||
throw new LogicException("Call to undefined method $class::$name().");
|
$items = (new ReflectionClass($this))->getMethods(ReflectionMethod::IS_PUBLIC);
|
||||||
|
$hint = ($t = DibiHelpers::getSuggestion($items, $name)) ? ", did you mean $t()?" : '.';
|
||||||
|
throw new LogicException("Call to undefined method $class::$name()$hint");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -37,8 +39,10 @@ trait DibiStrict
|
|||||||
*/
|
*/
|
||||||
public static function __callStatic($name, $args)
|
public static function __callStatic($name, $args)
|
||||||
{
|
{
|
||||||
$class = get_called_class();
|
$rc = new ReflectionClass(get_called_class());
|
||||||
throw new LogicException("Call to undefined static method $class::$name().");
|
$items = array_intersect($rc->getMethods(ReflectionMethod::IS_PUBLIC), $rc->getMethods(ReflectionMethod::IS_STATIC));
|
||||||
|
$hint = ($t = DibiHelpers::getSuggestion($items, $name)) ? ", did you mean $t()?" : '.';
|
||||||
|
throw new LogicException("Call to undefined static method {$rc->getName()}::$name()$hint");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -54,8 +58,10 @@ trait DibiStrict
|
|||||||
$ret = $this->$m();
|
$ret = $this->$m();
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
$class = get_class($this);
|
$rc = new ReflectionClass($this);
|
||||||
throw new LogicException("Attempt to read undeclared property $class::$$name.");
|
$items = array_diff($rc->getProperties(ReflectionProperty::IS_PUBLIC), $rc->getProperties(ReflectionProperty::IS_STATIC));
|
||||||
|
$hint = ($t = DibiHelpers::getSuggestion($items, $name)) ? ", did you mean $$t?" : '.';
|
||||||
|
throw new LogicException("Attempt to read undeclared property {$rc->getName()}::$$name$hint");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -65,8 +71,10 @@ trait DibiStrict
|
|||||||
*/
|
*/
|
||||||
public function __set($name, $value)
|
public function __set($name, $value)
|
||||||
{
|
{
|
||||||
$class = get_class($this);
|
$rc = new ReflectionClass($this);
|
||||||
throw new LogicException("Attempt to write to undeclared property $class::$$name.");
|
$items = array_diff($rc->getProperties(ReflectionProperty::IS_PUBLIC), $rc->getProperties(ReflectionProperty::IS_STATIC));
|
||||||
|
$hint = ($t = DibiHelpers::getSuggestion($items, $name)) ? ", did you mean $$t?" : '.';
|
||||||
|
throw new LogicException("Attempt to write to undeclared property {$rc->getName()}::$$name$hint");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -9,6 +9,24 @@ class TestClass
|
|||||||
{
|
{
|
||||||
use DibiStrict;
|
use DibiStrict;
|
||||||
|
|
||||||
|
public $public;
|
||||||
|
|
||||||
|
protected $protected;
|
||||||
|
|
||||||
|
public static $publicStatic;
|
||||||
|
|
||||||
|
public function publicMethod()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public static function publicMethodStatic()
|
||||||
|
{}
|
||||||
|
|
||||||
|
protected function protectedMethod()
|
||||||
|
{}
|
||||||
|
|
||||||
|
protected static function protectedMethodS()
|
||||||
|
{}
|
||||||
|
|
||||||
public function getBar()
|
public function getBar()
|
||||||
{
|
{
|
||||||
return 123;
|
return 123;
|
||||||
@@ -44,6 +62,21 @@ Assert::exception(function () {
|
|||||||
$obj->callParent();
|
$obj->callParent();
|
||||||
}, 'LogicException', 'Call to undefined method parent::callParent().');
|
}, 'LogicException', 'Call to undefined method parent::callParent().');
|
||||||
|
|
||||||
|
Assert::exception(function () {
|
||||||
|
$obj = new TestClass;
|
||||||
|
$obj->publicMethodX();
|
||||||
|
}, 'LogicException', 'Call to undefined method TestClass::publicMethodX(), did you mean publicMethod()?');
|
||||||
|
|
||||||
|
Assert::exception(function () { // suggest static method
|
||||||
|
$obj = new TestClass;
|
||||||
|
$obj->publicMethodStaticX();
|
||||||
|
}, 'LogicException', 'Call to undefined method TestClass::publicMethodStaticX(), did you mean publicMethodStatic()?');
|
||||||
|
|
||||||
|
Assert::exception(function () { // suggest only public method
|
||||||
|
$obj = new TestClass;
|
||||||
|
$obj->protectedMethodX();
|
||||||
|
}, 'LogicException', 'Call to undefined method TestClass::protectedMethodX().');
|
||||||
|
|
||||||
|
|
||||||
// writing
|
// writing
|
||||||
Assert::exception(function () {
|
Assert::exception(function () {
|
||||||
@@ -51,6 +84,21 @@ Assert::exception(function () {
|
|||||||
$obj->undeclared = 'value';
|
$obj->undeclared = 'value';
|
||||||
}, 'LogicException', 'Attempt to write to undeclared property TestClass::$undeclared.');
|
}, 'LogicException', 'Attempt to write to undeclared property TestClass::$undeclared.');
|
||||||
|
|
||||||
|
Assert::exception(function () {
|
||||||
|
$obj = new TestClass;
|
||||||
|
$obj->publicX = 'value';
|
||||||
|
}, 'LogicException', 'Attempt to write to undeclared property TestClass::$publicX, did you mean $public?');
|
||||||
|
|
||||||
|
Assert::exception(function () { // suggest only non-static property
|
||||||
|
$obj = new TestClass;
|
||||||
|
$obj->publicStaticX = 'value';
|
||||||
|
}, 'LogicException', 'Attempt to write to undeclared property TestClass::$publicStaticX.');
|
||||||
|
|
||||||
|
Assert::exception(function () { // suggest only public property
|
||||||
|
$obj = new TestClass;
|
||||||
|
$obj->protectedX = 'value';
|
||||||
|
}, 'LogicException', 'Attempt to write to undeclared property TestClass::$protectedX.');
|
||||||
|
|
||||||
|
|
||||||
// property getter
|
// property getter
|
||||||
$obj = new TestClass;
|
$obj = new TestClass;
|
||||||
@@ -66,6 +114,21 @@ Assert::exception(function () {
|
|||||||
$val = $obj->undeclared;
|
$val = $obj->undeclared;
|
||||||
}, 'LogicException', 'Attempt to read undeclared property TestClass::$undeclared.');
|
}, 'LogicException', 'Attempt to read undeclared property TestClass::$undeclared.');
|
||||||
|
|
||||||
|
Assert::exception(function () {
|
||||||
|
$obj = new TestClass;
|
||||||
|
$val = $obj->publicX;
|
||||||
|
}, 'LogicException', 'Attempt to read undeclared property TestClass::$publicX, did you mean $public?');
|
||||||
|
|
||||||
|
Assert::exception(function () { // suggest only non-static property
|
||||||
|
$obj = new TestClass;
|
||||||
|
$val = $obj->publicStaticX;
|
||||||
|
}, 'LogicException', 'Attempt to read undeclared property TestClass::$publicStaticX.');
|
||||||
|
|
||||||
|
Assert::exception(function () { // suggest only public property
|
||||||
|
$obj = new TestClass;
|
||||||
|
$val = $obj->protectedX;
|
||||||
|
}, 'LogicException', 'Attempt to read undeclared property TestClass::$protectedX.');
|
||||||
|
|
||||||
|
|
||||||
// unset/isset
|
// unset/isset
|
||||||
Assert::exception(function () {
|
Assert::exception(function () {
|
||||||
|
Reference in New Issue
Block a user