classSinkMatcher
final class SinkMatcher
Decides whether a call in the source is one of the database calls to catalog.
Methods§
public function __construct(
list<SinkSpec> $sinks,
ProgramIndex $index,
private ?ModelSet $models = null,
)Parameters
$sinks | list<SinkSpec> | The calls the enabled extensions recognise |
$index | ProgramIndex | The declarations of the analyzed source, for subclass checks |
$models | ?ModelSet |
The call matching a method written on a receiver of the given domain.
Parameters
$receiver | Domain | |
$method | string |
Returns
Test cases 2
Called from 3
- method-call SqlCatalog\Core\Analysis\CallEvaluator::applyEffects() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:129
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateMethod() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:195
- method-call SqlCatalog\Core\Analysis\Interpreter::sinkOf() packages/sql-catalog/src/Core/Analysis/Interpreter.php:264
Calls 3
- method-call SinkMatcher::byName() line 41
- class-const SinkCallKind::Method() line 41
- method-call SinkMatcher::receiverMatches() line 42
public function matchStatic(string $className, string $method): ?SinkSpecThe call matching a static method written on the named class.
Parameters
$className | string | |
$method | string |
Returns
Test cases 1
Called from 2
Calls 3
- method-call SinkMatcher::byName() line 55
- class-const SinkCallKind::StaticCall() line 55
- method-call SinkMatcher::classMatches() line 56
public function matchFunction(string $name): ?SinkSpecThe call matching a free function of that name.
Parameters
$name | string |
Returns
Test cases 1
Called from 3
- method-call SqlCatalog\Core\Analysis\CallEvaluator::applyEffects() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:116
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateFunction() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:321
- method-call SqlCatalog\Core\Analysis\Interpreter::sinkOf() packages/sql-catalog/src/Core/Analysis/Interpreter.php:253
Calls 2
- method-call SinkMatcher::byName() line 69
- class-const SinkCallKind::FunctionCall() line 69
public function byName(SinkCallKind $callKind, string $name): list<SinkSpec>The calls written with that name, whatever they are written on.
Parameters
$callKind | SinkCallKind | |
$name | string |
Returns
list<SinkSpec>Test cases 2
Called from 4
- method-call SqlCatalog\Core\Analysis\Interpreter::unidentified() packages/sql-catalog/src/Core/Analysis/Interpreter.php:297
- method-call SqlCatalog\Core\Analysis\SinkMatcher::matchMethod() packages/sql-catalog/src/Core/Analysis/SinkMatcher.php:41
- method-call SqlCatalog\Core\Analysis\SinkMatcher::matchStatic() packages/sql-catalog/src/Core/Analysis/SinkMatcher.php:55
- method-call SqlCatalog\Core\Analysis\SinkMatcher::matchFunction() packages/sql-catalog/src/Core/Analysis/SinkMatcher.php:69
public function models(Domain $receiver): boolWhether an extension already models what the receiver is.
An extension that names a class's calls is the model of that class. Walking into that class's own implementation from every call site re-derives the statements it issues at the sites they are already read from, once per caller, which costs a great deal and adds nothing that reading the class itself does not give.
Parameters
$receiver | Domain |
Returns
boolCalled from 1
Calls 1
- method-call SinkMatcher::receiverMatches() line 103
public function receiverMatches(Domain $receiver, string $expected): boolWhether a receiver of the given domain can be of the expected class.
Parameters
$receiver | Domain | |
$expected | string |
Returns
boolTest cases 1
Called from 2
Calls 2
- method-call Domain::type() line 116
- method-call SinkMatcher::classMatches() line 117
public function classMatches(string $className, string $expected): boolWhether a class is, or inherits from, the expected one.
Inheritance is read from the analyzed source first, so a drop-in replacement declared in the project is recognised, and from the running process second, which is what resolves the built-in driver classes.
Parameters
$className | string | |
$expected | string |
Returns
boolTest cases 6
SinkMatcherTest::testClassMatchesFollowsInheritanceDeclaredInTheAnalyzedSourcecallsSinkMatcherTest::testClassMatchesFollowsInheritanceOfTheRunningProcesscallsSinkMatcherTest::testClassMatchesIgnoresALeadingBackslashAndTheCaseOfTheNamecallsSinkMatcherTest::testClassMatchesNeverLoadsAClassOfTheAnalyzedSourcecallsSinkMatcherTest::testClassMatchesReadsTheRunningProcessOnlyForAClassThatIsRelatedcallsSinkMatcherTest::testClassMatchesUsesRegisteredTypeRelationsOnlycalls
Called from 2
Private surface 3§
Implementation details, listed for orientation only.
private list<SinkSpec> $sinksprivate ProgramIndex $indexprivate ?ModelSet $models = nullTest cases 75§
Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.
Dedicated tests 14
SinkMatcherTest::testByNameCollectsEveryCallWrittenWithThatNamecallsSinkMatcherTest::testByNameKeepsEveryCallOfThatNamecallsSinkMatcherTest::testClassMatchesFollowsInheritanceDeclaredInTheAnalyzedSourcecallsSinkMatcherTest::testClassMatchesFollowsInheritanceOfTheRunningProcesscallsSinkMatcherTest::testClassMatchesIgnoresALeadingBackslashAndTheCaseOfTheNamecallsSinkMatcherTest::testClassMatchesNeverLoadsAClassOfTheAnalyzedSourcecallsSinkMatcherTest::testClassMatchesReadsTheRunningProcessOnlyForAClassThatIsRelatedcallsSinkMatcherTest::testClassMatchesUsesRegisteredTypeRelationsOnlycallsSinkMatcherTest::testMatchFunctionFindsTheFreeFunctioncallsSinkMatcherTest::testMatchMethodFindsTheCallOnAKnownReceivercallsSinkMatcherTest::testMatchMethodIgnoresAReceiverNothingIsKnownAboutcallsSinkMatcherTest::testMatchStaticFindsTheCallOnAKnownClasscallsSinkMatcherTest::testModelsSaysWhetherAnExtensionAlreadyStandsForTheReceivercallsSinkMatcherTest::testReceiverMatchesReadsTheClassOutOfTheDomaincalls
Other tests reaching this symbol 61
CatalogCommandTestcallsCallEvaluatorTest::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::testTheCallMethodsAreReachedDirectlycallsConstantReaderTestcallsCalleeReturnsTestcallsCallersTest::testOfFindsNoCallersOfAMethodWrittenOutsideAnyClasscallsCallersTest::testOfFindsTheInstantiationsOfAClassForItsConstructorcallsCallersTest::testOfKeepsTheCallsThatCanReachTheMethodInTheOrderWrittencallsCallersTest::testOfSkipsClassesAnExtensionModelscallsDeriverTestcallsEntryBinderTestcallsCallbackEffectsTestcallsPropertyWritesTestcallsSliceExecutorTestcallsExpressionEvaluatorTestcallsRegistryTestcallsInterpreterTest::testSinkOfReadsANullsafeCallAndAFunctionCallcallsInterpreterTest::testSinkOfResolvesAStaticCallOnTheEnclosingClasscallsInterpreterTest::testSinkOfTellsADatabaseCallFromAnotherCallOfTheSameNamecallsInterpreterTest::testUnidentifiedCoversANullsafeCallButNotAFunctionCallcallsInterpreterTest::testUnidentifiedIsTrueOnlyForATextCarryingCallOnSomethingUnknowncallsInterpreterTest::testVisitHandsBackNothingForABindingCallWrittenWithoutAReceivercallsInterpreterTest::testVisitHandsBackWhatAnExecuteBindscallsInterpreterTest::testVisitRecordsAStatementAndHandsBackNothingToBindLatercallsInterpreterTest::testVisitRecordsNothingForACallWithoutItsStatementcallsInterpreterTest::testVisitRecordsNothingForADatabaseCallThatTakesNoStatementcallsModelQueriesTestcallsReferenceEvaluatorTestcallsCallContextTestcallsQueryModelInterfaceTestcallsBuilderCallsTestcallsBuilderQueriesTestcallsCallbackModelTestcallsCallModelTestcallsAnalyzerTestcallsJsonReporterTestcallsTextReporterTestcalls
Relations§
Instantiated in 3
- new SqlCatalog\Core\Analysis\Interpreter::analyze() packages/sql-catalog/src/Core/Analysis/Interpreter.php:110
- new SqlCatalog\Core\Analysis\Interpreter::deriverFor() packages/sql-catalog/src/Core/Analysis/Interpreter.php:166
- new SqlCatalog\Core\Analysis\Interpreter::deriverFor() packages/sql-catalog/src/Core/Analysis/Interpreter.php:182
Method calls 10
- method-call SqlCatalog\Core\Analysis\CallEvaluator::applyEffects() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:116
- method-call SqlCatalog\Core\Analysis\CallEvaluator::applyEffects() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:129
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateMethod() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:195
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateMethod() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:204
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateStatic() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:281
- method-call SqlCatalog\Core\Analysis\CallEvaluator::evaluateFunction() packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:321
- method-call SqlCatalog\Core\Analysis\Interpreter::sinkOf() packages/sql-catalog/src/Core/Analysis/Interpreter.php:253
- method-call SqlCatalog\Core\Analysis\Interpreter::sinkOf() packages/sql-catalog/src/Core/Analysis/Interpreter.php:261
- method-call SqlCatalog\Core\Analysis\Interpreter::sinkOf() packages/sql-catalog/src/Core/Analysis/Interpreter.php:264
- method-call SqlCatalog\Core\Analysis\Interpreter::unidentified() packages/sql-catalog/src/Core/Analysis/Interpreter.php:297
Type declarations 7
- type SqlCatalog\Core\Analysis\CallEvaluator packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:41
- type SqlCatalog\Core\Analysis\CallEvaluator packages/sql-catalog/src/Core/Analysis/CallEvaluator.php:58
- type SqlCatalog\Core\Analysis\Derivation\Callers packages/sql-catalog/src/Core/Analysis/Derivation/Callers.php:47
- type SqlCatalog\Core\Analysis\Derivation\Callers packages/sql-catalog/src/Core/Analysis/Derivation/Callers.php:52
- type SqlCatalog\Core\Analysis\Interpreter packages/sql-catalog/src/Core/Analysis/Interpreter.php:201
- type SqlCatalog\Core\Analysis\Interpreter packages/sql-catalog/src/Core/Analysis/Interpreter.php:246
- type SqlCatalog\Core\Analysis\Interpreter packages/sql-catalog/src/Core/Analysis/Interpreter.php:290