Repository: InsertKoinIO/koin
File: projects/core/koin-core/src/commonMain/kotlin/org/koin/core/resolution/CoreResolver.kt (Kotlin)

Code before:

    private inline fun <T> resolveFromScopeSource(scope: Scope, ctx: ResolutionContext): T? {
        if (scope.isRoot || scope.sourceValue == null || !(ctx.clazz.isInstance(scope.sourceValue) && ctx.qualifier == null)) return null
        ctx.logger.debug("|- ? ${ctx.debugTag} look at scope source")
        return if (ctx.clazz.isInstance(scope.sourceValue)) { scope.sourceValue as? T } else null
    }

    @KoinExperimentalAPI
    private inline fun <T> resolveFromScopeArchetype(scope: Scope, ctx: ResolutionContext): T? {
        if (scope.isRoot || scope.scopeQualifier !is TypeQualifier) return null
        ctx.logger.debug("|- ? ${ctx.debugTag} look at scope archetype")
        return _koin.instanceRegistry.resolveScopeArchetypeInstance<T>(ctx.qualifier, ctx.clazz, ctx)
    }

    private fun <T> resolveFromParentScopes(scope: Scope, ctx: ResolutionContext): T? {
        if (scope.isRoot) return null
        ctx.logger.debug("|- ? ${ctx.debugTag} look in other scopes")
        return findInOtherScope(scope,ctx)
    }

    private fun <T> findInOtherScope(
        scope: Scope,
        ctx: ResolutionContext,
    ): T? {
        val parentScopes = if (scope.linkedScopes.size > 1) flatten(scope.linkedScopes) else scope.linkedScopes
        return parentScopes.firstNotNullOfOrNull {
            ctx.logger.debug("|- ? ${ctx.debugTag} look in scope '${it.id}'")
            val instanceContext = if (!it.isRoot) ctx.newContextForScope(it) else ctx
            resolveFromContextOrNull(it, instanceContext, lookupParent = false)
        }
    }

    private inline fun <T> throwNoDefinitionFound(ctx: ResolutionContext): T {
        val qualifierString = ctx.qualifier?.let { " and qualifier '$it'" } ?: ""
        throw NoDefinitionFoundException(
            "No definition found for type '${ctx.clazz.getFullName()}'$qualifierString. Check your Modules configuration and add missing type and/or qualifier!",
        )
    }

    private fun <T> resolveInExtensions(
        scope: Scope,
        ctx: ResolutionContext
    ) : T?{
        return extendedResolution.firstNotNullOfOrNull {
            ctx.logger.debug("|- ['${it.name}'] ?")
            it.resolve(scope,ctx) as T?
        }
    }
}

@KoinInternalApi

Review comment (bug):
[nitpick] Redundant condition in the if statement. The condition `!hasSingleLink && scope.linkedScopes.size > 1` is redundant because `hasSingleLink` is defined as `scope.linkedScopes.size == 1`, so `!hasSingleLink` already implies `scope.linkedScopes.size != 1`. The additional check `&& scope.linkedScopes.size > 1` is unnecessary when `hasSingleLink` is false (except for the edge case of size 0).

Consider simplifying to: `val parentScopes = if (scope.linkedScopes.size > 1) flatten(scope.linkedScopes) else scope.linkedScopes`
```suggestion
        val parentScopes = if (scope.linkedScopes.size > 1) flatten(scope.linkedScopes) else scope.linkedScopes
```

Code after:

    private inline fun <T> resolveFromScopeSource(scope: Scope, ctx: ResolutionContext): T? {
        if (scope.isRoot || scope.sourceValue == null || !(ctx.clazz.isInstance(scope.sourceValue) && ctx.qualifier == null)) return null
        ctx.logger.debug("|- ? ${ctx.debugTag} look at scope source")
        return if (ctx.clazz.isInstance(scope.sourceValue)) { scope.sourceValue as? T } else null
    }

    @KoinExperimentalAPI
    private inline fun <T> resolveFromScopeArchetype(scope: Scope, ctx: ResolutionContext): T? {
        if (scope.isRoot || scope.scopeArchetype == null) return null
        ctx.logger.debug("|- ? ${ctx.debugTag} look at scope archetype")
        return _koin.instanceRegistry.resolveScopeArchetypeInstance<T>(ctx.qualifier, ctx.clazz, ctx)
    }

    private fun <T> resolveFromParentScopes(scope: Scope, ctx: ResolutionContext): T? {
        if (scope.isRoot) return null
        ctx.logger.debug("|- ? ${ctx.debugTag} look in other scopes")
        return findInOtherScope(scope,ctx)
    }

    private fun <T> findInOtherScope(
        scope: Scope,
        ctx: ResolutionContext,
    ): T? {
        val hasSingleLink = scope.linkedScopes.size == 1
        val parentScopes = if (!hasSingleLink && scope.linkedScopes.size > 1) flatten(scope.linkedScopes) else scope.linkedScopes
        return parentScopes.firstNotNullOfOrNull {
            ctx.logger.debug("|- ? ${ctx.debugTag} look in scope '${it.id}'")
            val instanceContext = if (!it.isRoot) ctx.newContextForScope(it) else ctx
            // If there is exactly one linked scope, allow traversal into its own parents (chained lookup)
            resolveFromContextOrNull(it, instanceContext, lookupParent = hasSingleLink)
        }
    }

    private inline fun <T> throwNoDefinitionFound(ctx: ResolutionContext): T {
        val qualifierString = ctx.qualifier?.let { " and qualifier '$it'" } ?: ""
        throw NoDefinitionFoundException(
            "No definition found for type '${ctx.clazz.getFullName()}'$qualifierString. Check your Modules configuration and add missing type and/or qualifier!",
        )
    }

    private fun <T> resolveInExtensions(
        scope: Scope,
        ctx: ResolutionContext
    ) : T?{
        return extendedResolution.firstNotNullOfOrNull {
            ctx.logger.debug("|- ['${it.name}'] ?")
            it.resolve(scope,ctx) as T?
        }
    }
}