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.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
|
import org.jetbrains.jet.utils.WrappedValues;
|
||||||
|
|
||||||
import java.util.*;
|
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>>() {
|
new Consumer<Collection<JetType>>() {
|
||||||
@Override
|
@Override
|
||||||
public void consume(@NotNull Collection<JetType> supertypes) {
|
public void consume(@NotNull Collection<JetType> supertypes) {
|
||||||
|
|||||||
+29
-3
@@ -67,8 +67,34 @@ public class LockBasedStorageManager implements StorageManager {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@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) {
|
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
|
@Override
|
||||||
protected void postCompute(@NotNull T value) {
|
protected void postCompute(@NotNull T value) {
|
||||||
postCompute.consume(value);
|
postCompute.consume(value);
|
||||||
@@ -84,11 +110,11 @@ public class LockBasedStorageManager implements StorageManager {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@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) {
|
return new LockBasedLazyValue<T>(lock, computable) {
|
||||||
@Override
|
@Override
|
||||||
protected Object recursionDetected() {
|
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.Consumer;
|
||||||
import com.intellij.util.Function;
|
import com.intellij.util.Function;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public interface StorageManager {
|
public interface StorageManager {
|
||||||
/**
|
/**
|
||||||
@@ -38,21 +39,29 @@ public interface StorageManager {
|
|||||||
@NotNull
|
@NotNull
|
||||||
<T> NotNullLazyValue<T> createLazyValue(@NotNull Computable<T> computable);
|
<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)
|
* see it in between)
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@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
|
@NotNull
|
||||||
<T> NullableLazyValue<T> createNullableLazyValue(@NotNull Computable<T> computable);
|
<T> NullableLazyValue<T> createNullableLazyValue(@NotNull Computable<T> computable);
|
||||||
|
|
||||||
/**
|
|
||||||
* If recursion is detected, respective calls to compute() simply return null
|
|
||||||
*/
|
|
||||||
@NotNull
|
@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
|
* {@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