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

Code before:
            // parent scopes
            else {
                var lastScope : Scope? = null
                val scopes = listOf(scope) + flatten(scope.linkedScopes)
                factory = scopes.firstNotNullOfOrNull {
                    val foundDefinition = it.scopeArchetype?.let {
                        _koin.instanceRegistry.resolveDefinition(
                            ctx.clazz,
                            ctx.qualifier,
                            it
                        )
                    } ?:
                    _koin.instanceRegistry.resolveDefinition(
                        ctx.clazz,
                        ctx.qualifier,
                        it.scopeQualifier
                    )
                    if (foundDefinition != null){
                        lastScope = it
                    }
                    foundDefinition
                }
                if (factory != null && lastScope != null && !lastScope.isRoot){
                    newCtx = ctx.newContextForScope(lastScope)
                    if (scope.scopeArchetype != null){
                        newCtx.scopeArchetype = lastScope.scopeArchetype
                    }
                }
                factory?.get(newCtx) as T?
            }
        }
    }

    private inline fun <T> resolveFromInjectedParameters(ctx: ResolutionContext): T? {
        return if (ctx.parameters == null || ctx.parameters.isEmpty()) null
        else {
            ctx.logger.debug("|- ? ${ctx.debugTag} look in injected parameters")
            ctx.parameters.getOrNull(clazz = ctx.clazz)
        }
    }

    private inline fun <T> resolveFromStackedParameters(scope: Scope, ctx: ResolutionContext): T? {
        val current = scope.parameterStack?.get()
        return if (current.isNullOrEmpty()) null
        else {
            ctx.logger.debug("|- ? ${ctx.debugTag} look in stack parameters")
            val parameters = current.firstOrNull()
            parameters?.getOrNull(ctx.clazz)
        }
    }


Review comment (suggestion):
The null check for `factory` is redundant. If `factory` is null, then `resolvedScope` will also be null (since `resolvedScope` is only assigned when definition is not null). The check on line 93 already handles this case by returning null when `foundScope` is null.

Code after:
        if (scope.isRoot) return null
        return scope.scopeArchetype?.let { archetype ->
            ctx.scopeArchetype = archetype
            _koin.instanceRegistry.resolveDefinition(ctx.clazz, ctx.qualifier, archetype)
        }
    }

    private fun <T> resolveFromScopeSource(scope: Scope, ctx: ResolutionContext): T? {
        if (scope.isRoot || ctx.qualifier != null) return null
        return if (ctx.clazz.isInstance(scope.sourceValue)) scope.sourceValue as? T else null
    }

    private fun <T> resolveFromLinkedScopes(scope: Scope, ctx: ResolutionContext): T? {
        val scopes = listOf(scope) + flatten(scope.linkedScopes)
        var resolvedScope: Scope? = null

        val factory = scopes.firstNotNullOfOrNull { linkedScope ->
            val definition = findDefinitionInScope(linkedScope, ctx)
            if (definition != null) {
                resolvedScope = linkedScope
            }
            definition
        }

        val foundScope = resolvedScope ?: return null
        if (factory == null) return null

        val newCtx = ctx.newContextForScope(foundScope)
        if (foundScope.scopeArchetype != null && !foundScope.isRoot) {
            newCtx.scopeArchetype = foundScope.scopeArchetype
        }
        return factory.get(newCtx) as T?
    }

    private fun findDefinitionInScope(scope: Scope, ctx: ResolutionContext): InstanceFactory<*>? {
        return scope.scopeArchetype?.let { archetype ->
            _koin.instanceRegistry.resolveDefinition(ctx.clazz, ctx.qualifier, archetype)
        } ?: _koin.instanceRegistry.resolveDefinition(ctx.clazz, ctx.qualifier, scope.scopeQualifier)
    }

    private inline fun <T> resolveFromInjectedParameters(ctx: ResolutionContext): T? {
        return if (ctx.parameters == null || ctx.parameters.isEmpty()) null
        else {
            ctx.logger.debug("|- ? ${ctx.debugTag} look in injected parameters")
            ctx.parameters.getOrNull(clazz = ctx.clazz)
        }
    }

    private inline fun <T> resolveFromStackedParameters(scope: Scope, ctx: ResolutionContext): T? {
        val current = scope.parameterStack?.get()
        return if (current.isNullOrEmpty()) null