diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index 628b46ff8fb..9bc62b940a1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; @@ -42,8 +43,6 @@ import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetKeywordToken; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.storage.NotNullLazyValueImpl; -import org.jetbrains.jet.storage.NotNullLazyValueWithDefault; import javax.inject.Inject; import java.util.*; @@ -54,6 +53,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.resolve.ModifiersChecker.*; import static org.jetbrains.jet.lexer.JetTokens.OVERRIDE_KEYWORD; +import static org.jetbrains.jet.storage.StorageUtil.createRecursionIntolerantLazyValueWithDefault; public class DescriptorResolver { public static final Name COPY_METHOD_NAME = Name.identifier("copy"); @@ -313,14 +313,19 @@ public class DescriptorResolver { JetExpression bodyExpression = function.getBodyExpression(); if (bodyExpression != null) { returnType = - DeferredType.create(trace, new NotNullLazyValueWithDefault(ErrorUtils.createErrorType("Recursive dependency")) { - @NotNull - @Override - protected JetType doCompute() { - JetType type = expressionTypingServices.getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor); - return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace); - } - }); + DeferredType.create(trace, + createRecursionIntolerantLazyValueWithDefault( + ErrorUtils.createErrorType("Recursive dependency"), + new Computable() { + @Override + public JetType compute() { + JetType type = expressionTypingServices + .getBodyExpressionType(trace, scope, dataFlowInfo, function, + functionDescriptor); + return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, + trace); + } + })); } else { returnType = ErrorUtils.createErrorType("No type, no body"); @@ -1028,14 +1033,17 @@ public class DescriptorResolver { if (hasDelegate && variableDescriptor instanceof PropertyDescriptor) { final JetExpression propertyDelegateExpression = ((JetProperty) variable).getDelegateExpression(); if (propertyDelegateExpression != null) { - return DeferredType.create(trace, new NotNullLazyValueWithDefault(ErrorUtils.createErrorType("Recursive dependency")) { - @NotNull - @Override - protected JetType doCompute() { - return resolveDelegatedPropertyType((PropertyDescriptor) variableDescriptor, scope, - propertyDelegateExpression, dataFlowInfo, trace); - } - }); + return DeferredType.create( + trace, + createRecursionIntolerantLazyValueWithDefault( + ErrorUtils.createErrorType("Recursive dependency"), + new Computable() { + @Override + public JetType compute() { + return resolveDelegatedPropertyType((PropertyDescriptor) variableDescriptor, scope, + propertyDelegateExpression, dataFlowInfo, trace); + } + })); } } if (!notLocal) { @@ -1045,14 +1053,20 @@ public class DescriptorResolver { } else { if (notLocal) { - return DeferredType.create(trace, new NotNullLazyValueWithDefault(ErrorUtils.createErrorType("Recursive dependency")) { - @Override - protected JetType doCompute() { - JetType type = resolveInitializerType(scope, initializer, dataFlowInfo, trace); + return DeferredType.create(trace, + createRecursionIntolerantLazyValueWithDefault( + ErrorUtils.createErrorType("Recursive dependency"), + new Computable() { + @Override + public JetType compute() { + JetType type = + resolveInitializerType(scope, initializer, dataFlowInfo, trace); - return transformAnonymousTypeIfNeeded(variableDescriptor, variable, type, trace); - } - }); + return transformAnonymousTypeIfNeeded(variableDescriptor, variable, type, + trace); + } + } + )); } else { return resolveInitializerType(scope, initializer, dataFlowInfo, trace); @@ -1370,10 +1384,9 @@ public class DescriptorResolver { final ClassDescriptor enumClassDescriptor = (ClassDescriptor) classObject.getContainingDeclaration(); assert DescriptorUtils.isEnumClass(enumClassDescriptor) : "values should be created in enum class: " + enumClassDescriptor; return DescriptorFactory - .createEnumClassObjectValuesMethod(classObject, DeferredType.create(trace, new NotNullLazyValueImpl() { - @NotNull + .createEnumClassObjectValuesMethod(classObject, DeferredType.create(trace, new Computable() { @Override - protected JetType doCompute() { + public JetType compute() { return KotlinBuiltIns.getInstance().getArrayType(enumClassDescriptor.getDefaultType()); } })); @@ -1388,10 +1401,9 @@ public class DescriptorResolver { final ClassDescriptor enumClassDescriptor = (ClassDescriptor) classObject.getContainingDeclaration(); assert DescriptorUtils.isEnumClass(enumClassDescriptor) : "valueOf should be created in enum class: " + enumClassDescriptor; return DescriptorFactory - .createEnumClassObjectValueOfMethod(classObject, DeferredType.create(trace, new NotNullLazyValueImpl() { - @NotNull + .createEnumClassObjectValueOfMethod(classObject, DeferredType.create(trace, new Computable() { @Override - protected JetType doCompute() { + public JetType compute() { return enumClassDescriptor.getDefaultType(); } })); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index f65aa0c3767..0a72f632d41 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.lang.resolve; +import com.intellij.openapi.util.Computable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -25,7 +26,6 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -import org.jetbrains.jet.storage.NotNullLazyValueImpl; import javax.inject.Inject; import java.util.ArrayList; @@ -36,6 +36,7 @@ import java.util.List; import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.PossiblyBareType.type; import static org.jetbrains.jet.lang.types.Variance.*; +import static org.jetbrains.jet.storage.LockBasedStorageManager.NO_LOCKS; public class TypeResolver { @@ -239,13 +240,12 @@ public class TypeResolver { return typeParameterDescriptor.getUpperBoundsAsType().getMemberScope(); } else { - return new LazyScopeAdapter(new NotNullLazyValueImpl() { - @NotNull + return new LazyScopeAdapter(NO_LOCKS.createLazyValue(new Computable() { @Override - protected JetScope doCompute() { + public JetScope compute() { return typeParameterDescriptor.getUpperBoundsAsType().getMemberScope(); } - }); + })); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java index 3417597526a..f9db2e2ce69 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java @@ -16,10 +16,12 @@ package org.jetbrains.jet.lang.types; +import com.intellij.openapi.util.Computable; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.storage.LockBasedStorageManager; import org.jetbrains.jet.storage.NotNullLazyValue; import org.jetbrains.jet.storage.ReenteringLazyValueComputationException; import org.jetbrains.jet.util.Box; @@ -36,6 +38,10 @@ public class DeferredType implements JetType { return deferredType; } + public static DeferredType create(BindingTrace trace, Computable compute) { + return create(trace, LockBasedStorageManager.NO_LOCKS.createLazyValue(compute)); + } + private final NotNullLazyValue lazyValue; private DeferredType(NotNullLazyValue lazyValue) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java index 22451c374d8..6dead58bf02 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.types.expressions; import com.google.common.collect.Lists; +import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiElement; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; @@ -33,7 +34,6 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -import org.jetbrains.jet.storage.NotNullLazyValueWithDefault; import org.jetbrains.jet.util.slicedmap.WritableSlice; import java.util.Collection; @@ -45,6 +45,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.*; import static org.jetbrains.jet.lang.resolve.calls.context.ContextDependency.INDEPENDENT; import static org.jetbrains.jet.lang.types.TypeUtils.*; import static org.jetbrains.jet.lang.types.expressions.CoercionStrategy.COERCION_TO_UNIT; +import static org.jetbrains.jet.storage.StorageUtil.createRecursionIntolerantLazyValueWithDefault; public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { protected ClosureExpressionsTypingVisitor(@NotNull ExpressionTypingInternals facade) { @@ -66,13 +67,14 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { @Override public void handleRecord(WritableSlice slice, PsiElement declaration, final ClassDescriptor descriptor) { if (slice == CLASS && declaration == expression.getObjectDeclaration()) { - JetType defaultType = DeferredType.create(context.trace, new NotNullLazyValueWithDefault(ErrorUtils.createErrorType("Recursive dependency")) { - @NotNull - @Override - protected JetType doCompute() { - return descriptor.getDefaultType(); - } - }); + JetType defaultType = DeferredType.create(context.trace, createRecursionIntolerantLazyValueWithDefault( + ErrorUtils.createErrorType("Recursive dependency"), + new Computable() { + @Override + public JetType compute() { + return descriptor.getDefaultType(); + } + })); result[0] = defaultType; if (!context.trace.get(PROCESSED, expression)) { temporaryTrace.record(EXPRESSION_TYPE, expression, defaultType); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/TypeParameterDescriptorImpl.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/TypeParameterDescriptorImpl.java index 1565582d6f6..374d88cc069 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/TypeParameterDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/TypeParameterDescriptorImpl.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.descriptors.impl; import com.google.common.collect.Sets; +import com.intellij.openapi.util.Computable; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor; @@ -30,12 +31,13 @@ import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.renderer.DescriptorRenderer; -import org.jetbrains.jet.storage.NotNullLazyValueImpl; import java.util.Collections; import java.util.List; import java.util.Set; +import static org.jetbrains.jet.storage.LockBasedStorageManager.NO_LOCKS; + public class TypeParameterDescriptorImpl extends DeclarationDescriptorNonRootImpl implements TypeParameterDescriptor { public static TypeParameterDescriptor createWithDefaultBound( @NotNull DeclarationDescriptor containingDeclaration, @@ -222,13 +224,12 @@ public class TypeParameterDescriptorImpl extends DeclarationDescriptorNonRootImp getTypeConstructor(), TypeUtils.hasNullableLowerBound(this), Collections.emptyList(), - new LazyScopeAdapter(new NotNullLazyValueImpl() { - @NotNull + new LazyScopeAdapter(NO_LOCKS.createLazyValue(new Computable() { @Override - protected JetScope doCompute() { + public JetScope compute() { return getUpperBoundsAsType().getMemberScope(); } - })); + }))); } return defaultType; } diff --git a/core/util.runtime/src/org/jetbrains/jet/storage/MemoizedFunctionToNotNullImpl.java b/core/util.runtime/src/org/jetbrains/jet/storage/MemoizedFunctionToNotNullImpl.java deleted file mode 100644 index 42d54e0a5a4..00000000000 --- a/core/util.runtime/src/org/jetbrains/jet/storage/MemoizedFunctionToNotNullImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.storage; - -import org.jetbrains.annotations.NotNull; - -import java.util.Map; - -public abstract class MemoizedFunctionToNotNullImpl extends MemoizedFunctionToNullableImpl implements - MemoizedFunctionToNotNull { - - public MemoizedFunctionToNotNullImpl() { - } - - public MemoizedFunctionToNotNullImpl(@NotNull Map map) { - super(map); - } - - @NotNull - @Override - public V fun(K input) { - V result = super.fun(input); - assert result != null : "compute() returned null"; - return result; - } - - @NotNull - @Override - protected abstract V doCompute(K input); -} diff --git a/core/util.runtime/src/org/jetbrains/jet/storage/MemoizedFunctionToNullableImpl.java b/core/util.runtime/src/org/jetbrains/jet/storage/MemoizedFunctionToNullableImpl.java deleted file mode 100644 index 4b8e43aaaea..00000000000 --- a/core/util.runtime/src/org/jetbrains/jet/storage/MemoizedFunctionToNullableImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.storage; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.storage.MemoizedFunctionToNullable; -import org.jetbrains.jet.utils.WrappedValues; - -import java.util.HashMap; -import java.util.Map; - -public abstract class MemoizedFunctionToNullableImpl implements MemoizedFunctionToNullable { - private final Map cache; - - public MemoizedFunctionToNullableImpl() { - this(new HashMap()); - } - - public MemoizedFunctionToNullableImpl(@NotNull Map map) { - this.cache = map; - } - - @Nullable - @Override - public V fun(K input) { - Object value = cache.get(input); - if (value != null) return WrappedValues.unescapeNull(value); - - V typedValue = doCompute(input); - - Object oldValue = cache.put(input, WrappedValues.escapeNull(typedValue)); - assert oldValue == null : "Race condition detected"; - - return typedValue; - } - - @Nullable - protected abstract V doCompute(K input); -} diff --git a/core/util.runtime/src/org/jetbrains/jet/storage/NotNullLazyValueImpl.java b/core/util.runtime/src/org/jetbrains/jet/storage/NotNullLazyValueImpl.java deleted file mode 100644 index c8425fad8bd..00000000000 --- a/core/util.runtime/src/org/jetbrains/jet/storage/NotNullLazyValueImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.storage; - -import org.jetbrains.annotations.NotNull; - -public abstract class NotNullLazyValueImpl extends NullableLazyValueImpl implements NotNullLazyValue { - - @NotNull - @Override - public T compute() { - T result = super.compute(); - assert result != null : "compute() returned null"; - return result; - } - - @NotNull - @Override - protected abstract T doCompute(); -} diff --git a/core/util.runtime/src/org/jetbrains/jet/storage/NotNullLazyValueWithDefault.java b/core/util.runtime/src/org/jetbrains/jet/storage/NotNullLazyValueWithDefault.java deleted file mode 100644 index 5d00fe0f41c..00000000000 --- a/core/util.runtime/src/org/jetbrains/jet/storage/NotNullLazyValueWithDefault.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.jetbrains.jet.storage; - -import org.jetbrains.annotations.NotNull; - -public abstract class NotNullLazyValueWithDefault extends NotNullLazyValueImpl { - private final T defaultValue; - - protected NotNullLazyValueWithDefault(@NotNull T defaultValue) { - this.defaultValue = defaultValue; - } - - @Override - public Object recursionDetected(boolean firstTime) { - if (firstTime) return super.recursionDetected(firstTime); - return defaultValue; - } -} diff --git a/core/util.runtime/src/org/jetbrains/jet/storage/NullableLazyValueImpl.java b/core/util.runtime/src/org/jetbrains/jet/storage/NullableLazyValueImpl.java deleted file mode 100644 index 3c4db4f66d3..00000000000 --- a/core/util.runtime/src/org/jetbrains/jet/storage/NullableLazyValueImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.storage; - -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.utils.ExceptionUtils; -import org.jetbrains.jet.utils.WrappedValues; - -public abstract class NullableLazyValueImpl implements NullableLazyValue { - private enum State { - NOT_COMPUTED, - COMPUTING, - RECURSION_WAS_DETECTED - } - - @Nullable - private Object value = State.NOT_COMPUTED; - - @Override - public boolean isComputed() { - return value != State.NOT_COMPUTED && value != State.COMPUTING; - } - - @Override - public T compute() { - if (!(value instanceof State)) { - // Computed already - return WrappedValues.unescapeThrowable(value); - } - - if (value == State.COMPUTING) { - Object result = recursionDetected(true); - if (result != State.NOT_COMPUTED) { - value = State.RECURSION_WAS_DETECTED; - return WrappedValues.unescapeThrowable(result); - } - } - else if (value == State.RECURSION_WAS_DETECTED) { - Object result = recursionDetected(false); - if (result != State.NOT_COMPUTED) { - return WrappedValues.unescapeThrowable(result); - } - } - - value = State.COMPUTING; - try { - T typedValue = doCompute(); - value = typedValue; - postCompute(typedValue); - return typedValue; - } - catch (Throwable e) { - value = WrappedValues.escapeThrowable(e); - throw ExceptionUtils.rethrow(e); - } - } - - /** - * @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(boolean firstTime) { - return WrappedValues.escapeThrowable(new ReenteringLazyValueComputationException()); - } - - protected abstract T doCompute(); - - protected void postCompute(T value) { - // Doing something in post-compute helps prevent infinite recursion - } -} diff --git a/core/util.runtime/src/org/jetbrains/jet/storage/StorageUtil.java b/core/util.runtime/src/org/jetbrains/jet/storage/StorageUtil.java new file mode 100644 index 00000000000..26188e01ca4 --- /dev/null +++ b/core/util.runtime/src/org/jetbrains/jet/storage/StorageUtil.java @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.storage; + +import com.intellij.openapi.util.Computable; +import com.intellij.util.Consumer; +import com.intellij.util.Function; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.utils.WrappedValues; + +public class StorageUtil { + public static NotNullLazyValue createRecursionIntolerantLazyValueWithDefault( + @NotNull final T defaultValue, + @NotNull Computable compute + ) { + //noinspection unchecked + return LockBasedStorageManager.NO_LOCKS.createLazyValueWithPostCompute( + compute, + new Function() { + @Override + public Object fun(Boolean firstTime) { + if (firstTime) return WrappedValues.escapeThrowable(new ReenteringLazyValueComputationException()); + return defaultValue; + } + }, + Consumer.EMPTY_CONSUMER + ); + } +}