Support recursion detection in lazy values

This commit is contained in:
Andrey Breslav
2013-10-01 21:07:59 +04:00
parent 98dc11bd1b
commit 36ce914613
@@ -18,19 +18,29 @@ package org.jetbrains.jet.storage;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.utils.ExceptionUtils;
import org.jetbrains.jet.utils.ReenteringLazyValueComputationException;
import org.jetbrains.jet.utils.WrappedValues;
public abstract class NullableLazyValueImpl<T> implements NullableLazyValue<T> {
private static final Object NOT_COMPUTED = new Object();
private static final Object COMPUTING = new Object();
@Nullable
private Object value = NOT_COMPUTED;
@Override
public T compute() {
Object _value = value;
if (_value != NOT_COMPUTED) return WrappedValues.unescapeThrowable(_value);
if (value == COMPUTING) {
Object result = recursionDetected();
if (result != NOT_COMPUTED) {
return WrappedValues.unescapeThrowable(result);
}
}
else if (value != NOT_COMPUTED) {
return WrappedValues.unescapeThrowable(value);
}
value = COMPUTING;
try {
T typedValue = doCompute();
value = typedValue;
@@ -43,6 +53,14 @@ public abstract class NullableLazyValueImpl<T> implements NullableLazyValue<T> {
}
}
/**
* @return {@code NOT_COMPUTED} to proceed, a value or wrapped exception otherwise, see WrappedValues
* @throws DO NOT throw exceptions from implementations of this method, instead return WrappedValues.escapeThrowable(exception)
*/
public Object recursionDetected() {
return WrappedValues.escapeThrowable(new ReenteringLazyValueComputationException());
}
protected abstract T doCompute();
protected void postCompute(T value) {