Recursion-tolerant notnull lazy values
This commit is contained in:
+7
@@ -49,6 +49,7 @@ import org.jetbrains.jet.lang.resolve.scopes.*;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.utils.WrappedValues;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -395,6 +396,12 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
||||
}
|
||||
}
|
||||
},
|
||||
new Computable<Object>() {
|
||||
@Override
|
||||
public Object compute() {
|
||||
return WrappedValues.unescapeExceptionOrNull(Collections.emptyList());
|
||||
}
|
||||
},
|
||||
new Consumer<Collection<JetType>>() {
|
||||
@Override
|
||||
public void consume(@NotNull Collection<JetType> supertypes) {
|
||||
|
||||
+29
-3
@@ -67,8 +67,34 @@ public class LockBasedStorageManager implements StorageManager {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> NotNullLazyValue<T> createLazyValueWithPostCompute(@NotNull Computable<T> computable, @NotNull final Consumer<T> postCompute) {
|
||||
public <T> NotNullLazyValue<T> createRecursionTolerantLazyValue(
|
||||
@NotNull Computable<T> computable, @NotNull final T onRecursiveCall
|
||||
) {
|
||||
return new LockBasedNotNullLazyValue<T>(lock, computable) {
|
||||
@Override
|
||||
protected Object recursionDetected() {
|
||||
return onRecursiveCall;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> NotNullLazyValue<T> createLazyValueWithPostCompute(
|
||||
@NotNull Computable<T> computable,
|
||||
final Computable<Object> onRecursiveCall,
|
||||
@NotNull final Consumer<T> postCompute
|
||||
) {
|
||||
return new LockBasedNotNullLazyValue<T>(lock, computable) {
|
||||
@Nullable
|
||||
@Override
|
||||
protected Object recursionDetected() {
|
||||
if (onRecursiveCall == null) {
|
||||
return super.recursionDetected();
|
||||
}
|
||||
return onRecursiveCall.compute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postCompute(@NotNull T value) {
|
||||
postCompute.consume(value);
|
||||
@@ -84,11 +110,11 @@ public class LockBasedStorageManager implements StorageManager {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(@NotNull Computable<T> computable) {
|
||||
public <T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(@NotNull Computable<T> computable, final T onRecursiveCall) {
|
||||
return new LockBasedLazyValue<T>(lock, computable) {
|
||||
@Override
|
||||
protected Object recursionDetected() {
|
||||
return WrappedValues.escapeNull(null);
|
||||
return WrappedValues.escapeNull(onRecursiveCall);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+15
-6
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface StorageManager {
|
||||
/**
|
||||
@@ -38,21 +39,29 @@ public interface StorageManager {
|
||||
@NotNull
|
||||
<T> NotNullLazyValue<T> createLazyValue(@NotNull Computable<T> computable);
|
||||
|
||||
@NotNull
|
||||
<T> NotNullLazyValue<T> createRecursionTolerantLazyValue(@NotNull Computable<T> computable, @NotNull T onRecursiveCall);
|
||||
|
||||
/**
|
||||
* {@code postCompute} is called after the value is computed, but before any other thread sees it (the current thread may
|
||||
* @param onRecursiveCall is called if the computation calls itself recursively.
|
||||
* If this parameter is null, an exception will be thrown on a recursive call.
|
||||
* If this function returns null, the computation proceeds recursively,
|
||||
* otherwise it should return a result of WrappedValues.escape*() method
|
||||
* @param postCompute is called after the value is computed, but before any other thread sees it (the current thread may
|
||||
* see it in between)
|
||||
*/
|
||||
@NotNull
|
||||
<T> NotNullLazyValue<T> createLazyValueWithPostCompute(@NotNull Computable<T> computable, @NotNull Consumer<T> postCompute);
|
||||
<T> NotNullLazyValue<T> createLazyValueWithPostCompute(
|
||||
@NotNull Computable<T> computable,
|
||||
@Nullable Computable<Object> onRecursiveCall,
|
||||
@NotNull Consumer<T> postCompute
|
||||
);
|
||||
|
||||
@NotNull
|
||||
<T> NullableLazyValue<T> createNullableLazyValue(@NotNull Computable<T> computable);
|
||||
|
||||
/**
|
||||
* If recursion is detected, respective calls to compute() simply return null
|
||||
*/
|
||||
@NotNull
|
||||
<T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(@NotNull Computable<T> computable);
|
||||
<T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(@NotNull Computable<T> computable, @Nullable T onRecursiveCall);
|
||||
|
||||
/**
|
||||
* {@code postCompute} is called after the value is computed, but before any other thread sees it (the current thread may
|
||||
|
||||
Reference in New Issue
Block a user