getExpectedArgumentsInfos(); self::$registeredArgumentsSet = $argumentsCollector->getRegisteredArgumentsSet(); $stubs = PhpStormStubsSingleton::getPhpStormStubs(); self::$functionsFqns = array_map(fn (PHPFunction $func) => self::toPresentableFqn($func->name), $stubs->getFunctions()); self::$methodsFqns = self::getMethodsFqns($stubs); self::$constantsFqns = self::getConstantsFqns($stubs); } private static function flatten(array $array): array { $return = []; array_walk_recursive($array, function ($a) use (&$return) { $return[$a] = $a; }); return $return; } public static function getConstantsFqns(StubsContainer $stubs): array { $constants = array_map(fn (PHPConst $constant) => self::toPresentableFqn($constant->name), $stubs->getConstants()); foreach ($stubs->getClasses() as $class) { foreach ($class->constants as $classConstant) { $name = self::getClassMemberFqn($class->name, $classConstant->name); $constants[$name] = $name; } } return $constants; } public static function getMethodsFqns(StubsContainer $stubs): array { return self::flatten( array_map(fn (PHPClass $class) => array_map(fn (PHPMethod $method) => self::getClassMemberFqn($class->name, $method->name), $class->methods), $stubs->getClasses()) ); } /** * @throws Exception */ public function testFunctionReferencesExists() { foreach (self::$expectedArguments as $argument) { $expr = $argument->getFunctionReference(); if ($expr instanceof FuncCall) { $fqn = self::toPresentableFqn($expr->name->toCodeString()); if (!str_starts_with($fqn, self::PSR_LOG_LOGGER_NAMESPACE_PREFIX)) { self::assertArrayHasKey($fqn, self::$functionsFqns, "Can't resolve function " . $fqn); } } elseif ($expr instanceof StaticCall) { if ((string)$expr->name !== '__construct') { $fqn = self::getClassMemberFqn($expr->class->toCodeString(), (string)$expr->name); if (!str_starts_with($fqn, self::PSR_LOG_LOGGER_NAMESPACE_PREFIX)) { self::assertArrayHasKey($fqn, self::$methodsFqns, "Can't resolve method " . $fqn); } } } elseif ($expr !== null) { self::fail('First argument should be function reference or method reference, got: ' . $expr::class); } } } /** * @throws Exception */ public function testConstantsExists() { foreach (self::$expectedArguments as $argument) { $expectedArguments = $argument->getExpectedArguments(); self::assertNotEmpty($expectedArguments, 'Expected arguments should not be empty for ' . $argument); foreach ($expectedArguments as $constantReference) { if ($constantReference instanceof ClassConstFetch) { $fqn = self::getClassMemberFqn($constantReference->class->toCodeString(), (string)$constantReference->name); if (!str_starts_with($fqn, self::PSR_LOG_LOGGER_NAMESPACE_PREFIX)) { self::assertArrayHasKey($fqn, self::$constantsFqns, "Can't resolve class constant " . $fqn); } } elseif ($constantReference instanceof ConstFetch) { $fqn = self::toPresentableFqn($constantReference->name->toCodeString()); self::assertArrayHasKey($fqn, self::$constantsFqns, "Can't resolve constant " . $fqn); } } } } /** * @throws Exception */ public function testRegisteredArgumentsSetExists() { foreach (self::$expectedArguments as $argument) { $usedArgumentsSet = []; foreach ($argument->getExpectedArguments() as $argumentsSet) { if ($argumentsSet instanceof FuncCall && (string)$argumentsSet->name === 'argumentsSet') { $args = $argumentsSet->args; self::assertGreaterThanOrEqual(1, count($args), 'argumentsSet call should provide set name'); if (property_exists($args[0]->value, 'value')) { $name = $args[0]->value->value; } else { self::fail("Couldn't read name of arguments set"); } self::assertContains($name, self::$registeredArgumentsSet, 'Can\'t find registered argument set: ' . $name); self::assertArrayNotHasKey( $name, $usedArgumentsSet, $name . ' argumentsSet used more then once for ' . self::getFqn($argument->getFunctionReference()) ); $usedArgumentsSet[$name] = $name; } } } } public function testStringLiteralsSingleQuoted() { foreach (self::$expectedArguments as $argument) { foreach ($argument->getExpectedArguments() as $literalArgument) { if ($literalArgument instanceof String_) { self::assertEquals( String_::KIND_SINGLE_QUOTED, $literalArgument->getAttribute('kind'), 'String literals as expectedArguments should be single-quoted' ); } } } } /** * @throws Exception */ public function testExpectedArgumentsAreUnique() { $functionsFqnsWithIndeces = []; foreach (self::$expectedArguments as $argument) { if ($argument->getIndex() < 0) { continue; } $functionReferenceFqn = self::getFqn($argument->getFunctionReference()); $index = $argument->getIndex(); if (array_key_exists($functionReferenceFqn, $functionsFqnsWithIndeces)) { self::assertNotContains($index, $functionsFqnsWithIndeces[$functionReferenceFqn], 'Expected arguments for ' . $functionReferenceFqn . ' with index ' . $index . ' already registered'); $functionsFqnsWithIndeces[$functionReferenceFqn][] = $index; } else { $functionsFqnsWithIndeces[$functionReferenceFqn] = [$index]; } } } /** * @throws Exception */ public function testExpectedReturnValuesAreUnique() { $expectedReturnValuesFunctionsFqns = []; foreach (self::$expectedArguments as $argument) { if ($argument->getIndex() >= 0 || $argument->getFunctionReference() === null) { continue; } $functionReferenceFqn = self::getFqn($argument->getFunctionReference()); self::assertArrayNotHasKey( $functionReferenceFqn, $expectedReturnValuesFunctionsFqns, 'Expected return values for ' . $functionReferenceFqn . ' already registered' ); $expectedReturnValuesFunctionsFqns[$functionReferenceFqn] = $functionReferenceFqn; } } /** * @throws Exception */ public static function testRegisteredArgumentsSetAreUnique() { $registeredArgumentsSet = []; foreach (self::$registeredArgumentsSet as $name) { self::assertArrayNotHasKey($name, $registeredArgumentsSet, 'Set with name ' . $name . ' already registered'); $registeredArgumentsSet[$name] = $name; } } /** * @throws Exception */ public function testReferencesAreAbsolute() { foreach (self::$expectedArguments as $argument) { $expr = $argument->getFunctionReference(); if ($expr !== null) { if ($expr instanceof StaticCall) { $name = $expr->class; } elseif (property_exists($expr, 'name')) { $name = $expr->name; } else { self::fail("Couldn't read name of expression"); } $originalName = $name->getAttribute('originalName'); if (method_exists($originalName, 'isFullyQualified')) { self::assertTrue( $originalName->isFullyQualified(), self::getFqn($expr) . ' should be fully qualified' ); } else { self::fail('Could not check if name is fully qualified'); } } } } #[Pure] private static function getClassMemberFqn(string $className, string $memberName): string { return self::toPresentableFqn($className) . '.' . $memberName; } private static function toPresentableFqn(string $name): string { if (str_starts_with($name, '\\')) { return substr($name, 1); } return $name; } /** * @throws Exception */ private static function getFqn(?Expr $expr): string { if ($expr instanceof StaticCall) { return self::getClassMemberFqn($expr->class->toCodeString(), (string)$expr->name); } elseif (property_exists($expr, 'name')) { return self::toPresentableFqn((string)$expr->name); } else { throw new Exception("Couldn't read a name of property with type {$expr->getType()}"); } } } __halt_compiler();----SIGNATURE:----UR2B15VBdgbXzxmbGL1VKF3pgl3wU33RU6cP4oW1uXoTyTdZ+uFNOD+ZSpNQIALuVLmDwmjRxNenVpx9ObnKV6t0qIKzIqONBH1pItVBKdD6h8U21me3aAGREtl7elQEvTetzDCh1+wU7Kxrjd6n9bZ173SMnL8376UOyNVsWPTu9NTZ7E8yZKYX7N+bTYeWzovsO2w5T18F/ey+98+aJuNm4FItS2ZV22WUbeiqC3t5iZxyNrK3jgZOBEcXuOrExB/N95ai4krZmVCKxOaVDfHojvhUlLibsVNzt4WaJfLrmKhEKjzflEyDt/X/5YoRg0x9OAjMoR+4F2fy8HrjWNs9qX7ybquc2R84xJAiW0Ee1gZ/FHdVl0RCtgvfoyN6oMrFJ+i7MQ11wDsT9+luM98pT48iRukIztdXNGXpEcfSDBAHiI9hEZCr31bcOAkstPqLUcrNAGfoQsUxUotCZK7LpsLCucCh7WsJSMlF+u2CnQfbMEWcrjPutwGPNUOYtlJTLpFpGVhxv8IVRN9Gk54lvq7W0Mp8hN+x2PWR0rR1BPoyMrGiyxXFUentv9Lo8lPFDI8emJsJDn3OeQcvs4ku7hy91R+9eDJIu6upnfSftUL0r2QJzGqvukPEyhTWcmvcM/PiJSwUFOcLlmrnm49GZOZAeDDcBeMuk8h6ECc=----ATTACHMENT:----MjgzMzEyMjAzMTczOTcwOCAxODQyMTk4MjQ5NDI3MDM4IDg5NzQzMzY0ODk3NTA4NTM=