expr, $context) === false) { return false; } if ($context->check_classes && isset($stmt->expr->inferredType) && !$stmt->expr->inferredType->hasMixed()) { $throw_type = $stmt->expr->inferredType; $exception_type = new Union([new TNamedObject('Exception'), new TNamedObject('Throwable')]); $file_analyzer = $statements_analyzer->getFileAnalyzer(); $codebase = $statements_analyzer->getCodebase(); foreach ($throw_type->getTypes() as $throw_type_part) { $throw_type_candidate = new Union([$throw_type_part]); if (!TypeAnalyzer::isContainedBy($codebase, $throw_type_candidate, $exception_type)) { if (IssueBuffer::accepts( new InvalidThrow( 'Cannot throw ' . $throw_type_part . ' as it does not extend Exception or implement Throwable', new CodeLocation($file_analyzer, $stmt), (string) $throw_type_part ), $statements_analyzer->getSuppressedIssues() )) { return false; } } elseif (!$context->isSuppressingExceptions($statements_analyzer)) { $codelocation = new CodeLocation($file_analyzer, $stmt); $hash = $codelocation->getHash(); foreach ($throw_type->getTypes() as $throw_atomic_type) { if ($throw_atomic_type instanceof TNamedObject) { $context->possibly_thrown_exceptions[$throw_atomic_type->value][$hash] = $codelocation; } } } } } } }