FIR DFA: exit delegate expression only after accessor completion
This commit fixes DFA problem (see test) when we accidentally try
to merge incoming flows from member property (val ... by cached ...) and
the following function. While completing lambda of buildList { ... }
inside by cached we accidentally assume that delegate is already left
and add the lambda into exitsFromCompletedPostponedAnonymousFunction.
This commit fixes the problem by exiting delegate later, after completion.
This commit is contained in:
committed by
teamcity
parent
c324bbfc37
commit
98cdc95cd0
+66
@@ -0,0 +1,66 @@
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
|
||||
interface ValidityToken {
|
||||
fun assertIsValid()
|
||||
}
|
||||
|
||||
interface ValidityTokenOwner {
|
||||
val token: ValidityToken
|
||||
}
|
||||
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun ValidityTokenOwner.assertIsValid() {
|
||||
token.assertIsValid()
|
||||
}
|
||||
|
||||
inline fun <R> ValidityTokenOwner.withValidityAssertion(action: () -> R): R {
|
||||
assertIsValid()
|
||||
return action()
|
||||
}
|
||||
|
||||
class ValidityAwareCachedValue<T>(
|
||||
private val token: ValidityToken,
|
||||
init: () -> T
|
||||
) : ReadOnlyProperty<Any, T> {
|
||||
private val lazyValue = lazy(LazyThreadSafetyMode.PUBLICATION, init)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun getValue(thisRef: Any, property: KProperty<*>): T {
|
||||
token.assertIsValid()
|
||||
return lazyValue.value
|
||||
}
|
||||
}
|
||||
|
||||
internal fun <T> ValidityTokenOwner.cached(init: () -> T) = ValidityAwareCachedValue(token, init)
|
||||
|
||||
public typealias KtScopeNameFilter = (String) -> Boolean
|
||||
|
||||
abstract class KtFirNonStarImportingScope(
|
||||
private val firScope: FirScope,
|
||||
private val builder: KtSymbolByFirBuilder,
|
||||
override val token: ValidityToken,
|
||||
) : ValidityTokenOwner {
|
||||
private val imports: List<String> by cached {
|
||||
buildList {
|
||||
getCallableNames().forEach {
|
||||
add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion {
|
||||
firScope.getCallableSymbols(getCallableNames().filter(nameFilter), builder)
|
||||
}
|
||||
|
||||
abstract fun getCallableNames(): Set<String>
|
||||
}
|
||||
|
||||
interface FirScope {
|
||||
fun getCallableSymbols(callableNames: Collection<String>, builder: KtSymbolByFirBuilder): Sequence<KtCallableSymbol>
|
||||
}
|
||||
|
||||
interface KtCallableSymbol
|
||||
|
||||
interface KtSymbolByFirBuilder
|
||||
|
||||
|
||||
Reference in New Issue
Block a user