Clear computable when value is calculated and CallOnceFunction is added

Relates to #KT-35256
This commit is contained in:
Vladimir Dolzhenko
2020-01-23 22:57:39 +01:00
parent 62f9e7a810
commit 00c71dd098
4 changed files with 37 additions and 17 deletions
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.BaseImportingScope
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.utils.CallOnceFunction
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -32,7 +33,7 @@ class LazyExplicitImportScope(
private val packageFragmentForVisibilityCheck: PackageFragmentDescriptor?,
private val declaredName: Name,
private val aliasName: Name,
private val storeReferences: (Collection<DeclarationDescriptor>) -> Unit
private val storeReferences: CallOnceFunction<Collection<DeclarationDescriptor>, Unit>
) : BaseImportingScope(null) {
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
import org.jetbrains.kotlin.types.expressions.isWithoutValueArguments
import org.jetbrains.kotlin.utils.CallOnceFunction
class QualifiedExpressionResolver(val languageVersionSettings: LanguageVersionSettings) {
fun resolvePackageHeader(
@@ -310,22 +311,22 @@ class QualifiedExpressionResolver(val languageVersionSettings: LanguageVersionSe
packageOrClassDescriptor,
packageFragmentForVisibilityCheck,
lastPart.name,
aliasName
) { candidates ->
if (candidates.isNotEmpty()) {
storeResult(
trace,
lastPart.expression,
candidates,
packageFragmentForVisibilityCheck,
position = QualifierPosition.IMPORT,
isQualifier = false
)
} else {
tryResolveDescriptorsWhichCannotBeImported(trace, moduleDescriptor, packageOrClassDescriptor, lastPart)
aliasName,
CallOnceFunction(Unit) { candidates ->
if (candidates.isNotEmpty()) {
storeResult(
trace,
lastPart.expression,
candidates,
packageFragmentForVisibilityCheck,
position = QualifierPosition.IMPORT,
isQualifier = false
)
} else {
tryResolveDescriptorsWhichCannotBeImported(trace, moduleDescriptor, packageOrClassDescriptor, lastPart)
}
}
}
)
}
private fun tryResolveDescriptorsWhichCannotBeImported(
@@ -305,7 +305,10 @@ public class LockBasedStorageManager implements StorageManager {
private static class LockBasedLazyValue<T> implements NullableLazyValue<T> {
private final LockBasedStorageManager storageManager;
private final Function0<? extends T> computable;
/**
* Computable function is <code>null</code> when value has been calculated
*/
private Function0<? extends T> computable;
@Nullable
private volatile Object value = NotValue.NOT_COMPUTED;
@@ -359,6 +362,7 @@ public class LockBasedStorageManager implements StorageManager {
postCompute(typedValue);
value = typedValue;
computable = null;
return typedValue;
}
catch (Throwable throwable) {
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.utils
import java.util.concurrent.atomic.AtomicReference
class CallOnceFunction<F, T>(private val defaultValue: T, delegate: Function1<F, T>) : Function1<F, T> {
private val functionRef: AtomicReference<Function1<F, T>?> = AtomicReference(delegate)
override fun invoke(p1: F): T = functionRef.getAndSet(null)?.invoke(p1) ?: defaultValue
}