classCallEvaluator
final class CallEvaluator
Works out what a call produces.
A database call produces what the driver hands back: a statement handle from a preparing call, the statement text itself from a call that composes one. A call into the analyzed source produces what the callee returns for these arguments. Recording statements is not done here; it is done at each database call, from the call itself.
Methods§
public function __construct(
ProgramIndex $index,
SinkMatcher $sinks,
Registry $functions,
ExternalInput $external,
NodeText $text,
?CalleeReturns $returns = null,
)Wires the evaluator to everything a call may need.
Parameters
$index | ProgramIndex | |
$sinks | SinkMatcher | |
$functions | Registry | |
$external | ExternalInput | |
$text | NodeText | |
$returns | ?CalleeReturns |
public function evaluate(
CallLike $node,
Environment $environment,
FunctionScope $scope,
ExpressionEvaluator $expressions,
): DomainThe value a call produces.
Parameters
$node | CallLike | |
$environment | Environment | |
$scope | FunctionScope | |
$expressions | ExpressionEvaluator |
Returns
Test cases 4
Called from 1
Calls 17
- method-call
CallLike::isFirstClassCallable()line 81 - static-call Domain::of() line 82
- new ObjectTerm line 82
- method-call ExpressionEvaluator::evaluate() line 84
- method-call CallEvaluator::arguments() line 85
- method-call Registry::evaluateCall() line 88
- new CallContext line 88
- method-call CallEvaluator::applyEffects() line 92
- method-call CallEvaluator::invalidateEscapes() line 93
- method-call CallEvaluator::evaluateInstantiation() line 94
- method-call CallEvaluator::evaluateMethod() line 97
- method-call CallEvaluator::evaluateStatic() line 100
- method-call CallEvaluator::evaluateFunction() line 103
- static-call Domain::opaque() line 106
- static-call TypeShape::unknown() line 106
- class-const Origin::Call() line 106
- method-call NodeText::render() line 106
public function applyEffects(CallLike $node, Environment $environment): voidOpens arguments whose callees may write through references.
Parameters
$node | CallLike | |
$environment | Environment |
Called from 7
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluate() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:92
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateMethod() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:188
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateMethod() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:200
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateStatic() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:272
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateStatic() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:287
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateFunction() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:314
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateFunction() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:327
Calls 15
- method-call CallEvaluator::functionName() line 115
- method-call SinkMatcher::matchFunction() line 116
- method-call ProgramIndex::findFunction() line 119
- method-call Registry::supports() line 119
- method-call
CallLike::getArgs()line 120 - method-call Registry::normalize() line 121
- method-call WriteEffects::apply() line 122
- new WriteEffects line 122
- method-call ModifiedNames::targets() line 122
- new ModifiedNames line 122
- function-call
is_stringline 128 - method-call SinkMatcher::matchMethod() line 129
- method-call Environment::read() line 129
- method-call WriteEffects::own() line 133
- new ReferenceEffects line 134
public function evaluateInstantiation(New_ $node, FunctionScope $scope): DomainThe object an instantiation produces, which is how a driver gets its type.
Parameters
$node | New_ | |
$scope | FunctionScope |
Returns
Test cases 1
Called from 1
Calls 7
- static-call Domain::opaque() line 144
- static-call TypeShape::of() line 144
- class-const Origin::Call() line 144
- function-call
in_arrayline 147 - function-call
strtolowerline 147 - static-call Domain::of() line 151
- new ObjectTerm line 151
public function arguments(
CallLike $node,
Environment $environment,
FunctionScope $scope,
ExpressionEvaluator $expressions,
): list<Domain>The evaluated arguments of a call, in the order they are written.
Parameters
$node | CallLike | |
$environment | Environment | |
$scope | FunctionScope | |
$expressions | ExpressionEvaluator |
Returns
list<Domain>Test cases 1
Called from 1
Calls 2
- method-call
CallLike::getArgs()line 166 - method-call ExpressionEvaluator::evaluate() line 167
public function evaluateMethod(
MethodCall|NullsafeMethodCall $node,
list<Domain> $arguments,
Environment $environment,
FunctionScope $scope,
ExpressionEvaluator $expressions,
?Domain $receiver = null,
): DomainThe value of a method call, which may be a database call.
Parameters
$node | MethodCall|NullsafeMethodCall | |
$arguments | list<Domain> | |
$environment | Environment | |
$scope | FunctionScope | |
$expressions | ExpressionEvaluator | |
$receiver | ?Domain |
Returns
Test cases 4
CallEvaluatorTest::testEvaluateMethodFollowsAMethodDeclaredWithoutABodycallsCallEvaluatorTest::testEvaluateMethodFollowsIntoAClassNoExtensionModelscallsCallEvaluatorTest::testEvaluateMethodFollowsIntoAModelledClassOnlyFromItsOwnBodycallsCallEvaluatorTest::testEvaluateMethodGivesUpOnAMethodWhoseNameIsNotWrittencalls
Called from 1
Calls 18
- method-call CallEvaluator::applyEffects() line 188
- method-call CallEvaluator::invalidateEscapes() line 189
- method-call Environment::objects() line 190
- method-call ExpressionEvaluator::evaluate() line 190
- static-call Domain::opaque() line 191
- static-call TypeShape::unknown() line 191
- class-const Origin::Call() line 191
- method-call NodeText::render() line 191
- method-call Environment::refresh() line 194
- method-call SinkMatcher::matchMethod() line 195
- method-call Registry::evaluateCall() line 196
- new CallContext line 196
- method-call CallEvaluator::applySink() line 202
- method-call CallEvaluator::isOwnReceiver() line 204
- method-call SinkMatcher::models() line 204
- method-call ProgramIndex::findMethod() line 210
- method-call CallEvaluator::dispatch() line 212
- method-call CallEvaluator::follow() line 220
public function isOwnReceiver(MethodCall|NullsafeMethodCall $node): boolWhether the call is written on the object the body it is written in belongs to.
A class an extension models is not followed into from outside, but its own source is still read the way any other source is, so a call it makes on itself is followed like any other.
Parameters
$node | MethodCall|NullsafeMethodCall |
Returns
boolpublic function dispatch(
?string $className,
string $method,
list<Domain> $arguments,
FunctionScope $scope,
ExpressionEvaluator $expressions,
): ?DomainThe value a call resolves to across the implementations the source declares.
Parameters
$className | ?string | |
$method | string | |
$arguments | list<Domain> | |
$scope | FunctionScope | |
$expressions | ExpressionEvaluator |
Returns
Test cases 1
Called from 1
Calls 2
- method-call ProgramIndex::implementationsOf() line 248
- method-call CallEvaluator::follow() line 249
public function evaluateStatic(
StaticCall $node,
list<Domain> $arguments,
FunctionScope $scope,
ExpressionEvaluator $expressions,
?Environment $environment = null,
): DomainThe value of a static call, which may be a database call.
Parameters
$node | StaticCall | |
$arguments | list<Domain> | |
$scope | FunctionScope | |
$expressions | ExpressionEvaluator | |
$environment | ?Environment |
Returns
Test cases 3
Called from 1
Calls 15
- method-call CallEvaluator::applyEffects() line 272
- method-call CallEvaluator::invalidateEscapes() line 273
- static-call Domain::opaque() line 275
- static-call TypeShape::unknown() line 275
- class-const Origin::Call() line 275
- method-call NodeText::render() line 275
- function-call
in_arrayline 277 - function-call
strtolowerline 277 - method-call SinkMatcher::matchStatic() line 281
- new Environment line 282
- method-call Registry::evaluateCall() line 283
- new CallContext line 283
- method-call CallEvaluator::applySink() line 289
- method-call ProgramIndex::findMethod() line 293
- method-call CallEvaluator::follow() line 297
public function evaluateFunction(
FuncCall $node,
list<Domain> $arguments,
FunctionScope $scope,
ExpressionEvaluator $expressions,
?Environment $environment = null,
): DomainThe value of a function call, which may be a database call or a string builder.
Parameters
$node | FuncCall | |
$arguments | list<Domain> | |
$scope | FunctionScope | |
$expressions | ExpressionEvaluator | |
$environment | ?Environment |
Returns
Test cases 3
Called from 1
Calls 17
- method-call CallEvaluator::applyEffects() line 314
- method-call CallEvaluator::invalidateEscapes() line 315
- static-call Domain::opaque() line 317
- static-call TypeShape::unknown() line 317
- class-const Origin::Call() line 317
- method-call NodeText::render() line 317
- method-call CallEvaluator::functionName() line 319
- method-call SinkMatcher::matchFunction() line 321
- new Environment line 322
- method-call Registry::evaluateCall() line 323
- new CallContext line 323
- method-call CallEvaluator::applySink() line 329
- method-call Registry::evaluate() line 331
- method-call ExternalInput::isFunction() line 335
- class-const Origin::External() line 336
- method-call ProgramIndex::findFunction() line 341
- method-call CallEvaluator::follow() line 345
public function invalidateEscapes(CallLike $node, Environment $environment): voidUnknown calls may mutate objects passed directly or captured by callbacks.
Parameters
$node | CallLike | |
$environment | Environment |
Test cases 1
Called from 7
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluate() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:93
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateMethod() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:189
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateMethod() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:208
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateStatic() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:273
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateStatic() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:292
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateFunction() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:315
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateFunction() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:339
Calls 7
- function-call
array_mapline 353 - function-call
array_valuesline 353 - method-call
CallLike::getArgs()line 353 - method-call FreeNames::of() line 354
- new FreeNames line 354
- method-call Environment::objects() line 355
- method-call Environment::read() line 355
public function functionName(Name $name): stringResolves an unqualified call locally before PHP's global fallback.
Parameters
$name | Name |
Returns
stringCalled from 2
Calls 4
- method-call
Name::getAttribute()line 364 - method-call Registry::supports() line 366
- method-call ProgramIndex::findFunction() line 366
- method-call
Name::toString()line 371
public function applySink(
SinkSpec $sink,
CallLike $node,
list<Domain> $arguments,
FunctionScope $scope,
): DomainWhat a database call hands back.
A preparing call hands back a handle naming the call it came from, which is how a later execute() finds the statement it binds to. A composing call hands back the statement it was given.
Parameters
$sink | SinkSpec | |
$node | CallLike | |
$arguments | list<Domain> | |
$scope | FunctionScope |
Returns
Test cases 2
Called from 3
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateMethod() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:202
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateStatic() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:289
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateFunction() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:329
Calls 14
- class-const SinkRole::Compose() line 386
- static-call Domain::unknown() line 386
- class-const SinkRole::Prepare() line 387
- static-call Domain::of() line 387
- new ObjectTerm line 387
- method-call CallEvaluator::siteKeyOf() line 390
- class-const SinkRole::Query() line 392
- class-const SinkRole::Modelled() line 392
- static-call Domain::opaque() line 392
- static-call TypeShape::unknown() line 392
- class-const Origin::Call() line 392
- class-const SinkRole::Execute() line 393
- class-const SinkRole::Bind() line 393
- static-call TypeShape::of() line 393
public function follow(
MethodShape|FunctionShape $callee,
list<Domain> $arguments,
FunctionScope $scope,
ExpressionEvaluator $expressions,
): DomainWhat a call into the analyzed source returns for these arguments.
Parameters
$callee | MethodShape|FunctionShape | |
$arguments | list<Domain> | |
$scope | FunctionScope | |
$expressions | ExpressionEvaluator |
Returns
Test cases 1
Called from 4
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateMethod() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:220
- method-call SqlCatalog\Core\Analysis\CallEvaluator::dispatch() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:249
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateStatic() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:297
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateFunction() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:345
Calls 2
- static-call Domain::opaque() line 411
- class-const Origin::Call() line 411
public function siteKeyOf(CallLike $node, FunctionScope $scope, string $sinkId): stringWhat tells one call apart from every other, including one written on the same line.
The reported site names a line, because that is what a reader jumps to. Grouping the readings of a call needs more than that, since two queries on one line are two calls and must not be folded into each other.
Parameters
$node | CallLike | |
$scope | FunctionScope | |
$sinkId | string |
Returns
stringTest cases 2
Called from 1
Calls 1
- method-call CallEvaluator::callKeyOf() line 426
public function callKeyOf(CallLike $node, FunctionScope $scope): stringWhat tells one call apart from every other, by where it is written.
Parameters
$node | CallLike | |
$scope | FunctionScope |
Returns
stringTest cases 1
Called from 1
Calls 1
- method-call
CallLike::getStartFilePos()line 434
Private surface 7§
Implementation details, listed for orientation only.
private ProgramIndex $indexprivate SinkMatcher $sinksprivate Registry $functionsprivate ExternalInput $externalprivate NodeText $textprivate ?CalleeReturns $returnsprivate ?ReferenceEffects $references = nullTest cases 49§
Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.
Dedicated tests 26
CallEvaluatorTest::testApplyEffectsKeepsKnownByValueArgumentsAndOpensReferencescallsCallEvaluatorTest::testApplySinkHandsBackAHandleNamingThePreparingCallcallsCallEvaluatorTest::testApplySinkHandsBackWhatEachKindOfDatabaseCallHandsBackcallsCallEvaluatorTest::testArgumentsIsCalledWithTheCallItselfcallsCallEvaluatorTest::testCallKeyOfTellsOneCallApartFromEveryOthercallsCallEvaluatorTest::testDispatchReadsTheImplementationsTheSourceDeclarescallsCallEvaluatorTest::testEvaluateAppliesOnlyPossibleCallWritescallsCallEvaluatorTest::testEvaluateFunctionGivesUpOnAFunctionWhoseNameIsNotWrittencallsCallEvaluatorTest::testEvaluateFunctionHandsBackWhatADatabaseCallHandsBackcallsCallEvaluatorTest::testEvaluateFunctionNamesTheExternalInputItReadscallsCallEvaluatorTest::testEvaluateInstantiationNamesTheClassItCreatescallsCallEvaluatorTest::testEvaluateMethodFollowsAMethodDeclaredWithoutABodycallsCallEvaluatorTest::testEvaluateMethodFollowsIntoAClassNoExtensionModelscallsCallEvaluatorTest::testEvaluateMethodFollowsIntoAModelledClassOnlyFromItsOwnBodycallsCallEvaluatorTest::testEvaluateMethodGivesUpOnAMethodWhoseNameIsNotWrittencallsCallEvaluatorTest::testEvaluateOfAFirstClassCallableIsAClosurecallsCallEvaluatorTest::testEvaluateRetainsReferenceWritesForAModeledNamespacedFunctioncallsCallEvaluatorTest::testEvaluateStaticGivesUpWhenTheClassOrTheNameIsNotWrittencallsCallEvaluatorTest::testEvaluateStaticHandsBackWhatADatabaseCallHandsBackcallsCallEvaluatorTest::testEvaluateStaticResolvesTheSelfKeywordsToTheEnclosingClasscallsCallEvaluatorTest::testFollowWithoutReturnsToReadNamesTheCalleecallsCallEvaluatorTest::testFunctionNameUsesRegisteredNamespaceBeforeGlobalFallbackcallsCallEvaluatorTest::testInvalidateEscapesOpensAliasedObjectStatecallsCallEvaluatorTest::testIsOwnReceiverTellsACallOnItselfApartFromOneOnSomethingElsecallsCallEvaluatorTest::testSiteKeyOfNamesTheCallAndTheDatabaseCallcallsCallEvaluatorTest::testTheCallMethodsAreReachedDirectlycalls
Other tests reaching this symbol 23
CatalogCommandTestcallsConstantReaderTestcallsCalleeReturnsTestcallsCallersTestcallsDeriverTestcallsEntryBinderTestcallsCallbackEffectsTestcallsPropertyWritesTestcallsSliceExecutorTestcallsExpressionEvaluatorTestcallsRegistryTestcallsInterpreterTestcallsModelQueriesTestcallsReferenceEvaluatorTestcallsCallContextTestcallsQueryModelInterfaceTestcallsBuilderCallsTestcallsBuilderQueriesTestcallsCallbackModelTestcallsCallModelTestcallsAnalyzerTestcallsJsonReporterTestcallsTextReporterTestcalls