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 075d61cb13b..2c543b20234 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -43,6 +43,7 @@ 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.StorageManager; import javax.inject.Inject; import java.util.*; @@ -53,7 +54,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.util.StorageUtil.createRecursionIntolerantLazyValueWithDefault; +import static org.jetbrains.jet.storage.LockBasedStorageManager.NO_LOCKS; public class DescriptorResolver { public static final Name COPY_METHOD_NAME = Name.identifier("copy"); @@ -67,6 +68,8 @@ public class DescriptorResolver { private ExpressionTypingServices expressionTypingServices; @NotNull private DelegatedPropertyResolver delegatedPropertyResolver; + @NotNull + private StorageManager storageManager; @Inject public void setTypeResolver(@NotNull TypeResolver typeResolver) { @@ -88,6 +91,11 @@ public class DescriptorResolver { this.delegatedPropertyResolver = delegatedPropertyResolver; } + @Inject + public void setStorageManager(@NotNull StorageManager storageManager) { + this.storageManager = storageManager; + } + public void resolveMutableClassDescriptor( @NotNull JetClass classElement, @NotNull MutableClassDescriptor descriptor, @@ -319,19 +327,17 @@ public class DescriptorResolver { JetExpression bodyExpression = function.getBodyExpression(); if (bodyExpression != null) { returnType = - DeferredType.create(trace, - createRecursionIntolerantLazyValueWithDefault( - ErrorUtils.createErrorType("Recursive dependency"), - new Function0() { - @Override - public JetType invoke() { - JetType type = expressionTypingServices - .getBodyExpressionType(trace, scope, dataFlowInfo, function, - functionDescriptor); - return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, - trace); - } - })); + DeferredType.createRecursionIntolerant( + storageManager, + trace, + new Function0() { + @Override + public JetType invoke() { + JetType type = expressionTypingServices + .getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor); + return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace); + } + }); } else { returnType = ErrorUtils.createErrorType("No type, no body"); @@ -924,17 +930,16 @@ public class DescriptorResolver { final JetProperty property = (JetProperty) variable; final JetExpression propertyDelegateExpression = property.getDelegateExpression(); if (propertyDelegateExpression != null) { - return DeferredType.create( + return DeferredType.createRecursionIntolerant( + storageManager, trace, - createRecursionIntolerantLazyValueWithDefault( - ErrorUtils.createErrorType("Recursive dependency"), - new Function0() { - @Override - public JetType invoke() { - return resolveDelegatedPropertyType(property, (PropertyDescriptor) variableDescriptor, scope, - propertyDelegateExpression, dataFlowInfo, trace); - } - })); + new Function0() { + @Override + public JetType invoke() { + return resolveDelegatedPropertyType(property, (PropertyDescriptor) variableDescriptor, scope, + propertyDelegateExpression, dataFlowInfo, trace); + } + }); } } if (!notLocal) { @@ -944,24 +949,20 @@ public class DescriptorResolver { } else { if (notLocal) { - return DeferredType.create(trace, - createRecursionIntolerantLazyValueWithDefault( - ErrorUtils.createErrorType("Recursive dependency"), - new Function0() { - @Override - public JetType invoke() { - JetType type = - resolveInitializerType(scope, initializer, dataFlowInfo, trace); + return DeferredType.createRecursionIntolerant( + storageManager, + trace, + new Function0() { + @Override + public JetType invoke() { + JetType type = resolveInitializerType(scope, initializer, dataFlowInfo, trace); - EvaluatePackage.recordCompileTimeValueForInitializerIfNeeded( - variableDescriptor, - initializer, type, - trace); - return transformAnonymousTypeIfNeeded(variableDescriptor, variable, type, - trace); - } - } - )); + EvaluatePackage.recordCompileTimeValueForInitializerIfNeeded( + variableDescriptor, initializer, type, trace); + return transformAnonymousTypeIfNeeded(variableDescriptor, variable, type, trace); + } + } + ); } else { return resolveInitializerType(scope, initializer, dataFlowInfo, trace); @@ -1283,7 +1284,7 @@ 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 Function0() { + .createEnumClassObjectValuesMethod(classObject, DeferredType.create(NO_LOCKS, trace, new Function0() { @Override public JetType invoke() { return KotlinBuiltIns.getInstance().getArrayType(enumClassDescriptor.getDefaultType()); @@ -1300,7 +1301,7 @@ 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 Function0() { + .createEnumClassObjectValueOfMethod(classObject, DeferredType.create(NO_LOCKS, trace, new Function0() { @Override public JetType invoke() { return enumClassDescriptor.getDefaultType(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java index 021560fde94..7c556860d20 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java @@ -378,14 +378,14 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope() { @Override public JetType invoke() { return thisDescriptor.getDefaultType(); } }) - )); + ); } @Override 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 4056ea6ab50..d1b63208dab 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java @@ -17,12 +17,13 @@ package org.jetbrains.jet.lang.types; import jet.Function0; +import jet.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; 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.StorageManager; import org.jetbrains.jet.util.Box; import org.jetbrains.jet.util.ReenteringLazyValueComputationException; @@ -31,20 +32,52 @@ import java.util.List; import static org.jetbrains.jet.lang.resolve.BindingContext.DEFERRED_TYPE; public class DeferredType implements LazyType { - - public static DeferredType create(BindingTrace trace, NotNullLazyValue lazyValue) { - DeferredType deferredType = new DeferredType(lazyValue); + + private static final Function1 EMPTY_CONSUMER = new Function1() { + @Override + public Void invoke(Object t) { + return null; + } + }; + + private static final Function1 RECURSION_PREVENTER = new Function1() { + @Override + public JetType invoke(Boolean firstTime) { + if (firstTime) throw new ReenteringLazyValueComputationException(); + return ErrorUtils.createErrorType("Recursive dependency"); + } + }; + + @NotNull + public static DeferredType create( + @NotNull StorageManager storageManager, + @NotNull BindingTrace trace, + @NotNull Function0 compute + ) { + DeferredType deferredType = new DeferredType(storageManager.createLazyValue(compute)); trace.record(DEFERRED_TYPE, new Box(deferredType)); return deferredType; } - public static DeferredType create(BindingTrace trace, Function0 compute) { - return create(trace, LockBasedStorageManager.NO_LOCKS.createLazyValue(compute)); + @NotNull + public static DeferredType createRecursionIntolerant( + @NotNull StorageManager storageManager, + @NotNull BindingTrace trace, + @NotNull Function0 compute + ) { + //noinspection unchecked + DeferredType deferredType = new DeferredType(storageManager.createLazyValueWithPostCompute( + compute, + RECURSION_PREVENTER, + EMPTY_CONSUMER + )); + trace.record(DEFERRED_TYPE, new Box(deferredType)); + return deferredType; } private final NotNullLazyValue lazyValue; - private DeferredType(NotNullLazyValue lazyValue) { + private DeferredType(@NotNull NotNullLazyValue lazyValue) { this.lazyValue = 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 b0eea36468d..ea29e34e261 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 @@ -31,9 +31,13 @@ import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.types.*; +import org.jetbrains.jet.lang.types.CommonSupertypes; +import org.jetbrains.jet.lang.types.DeferredType; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.JetTypeInfo; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.storage.StorageManager; import org.jetbrains.jet.util.slicedmap.WritableSlice; import java.util.Collection; @@ -45,11 +49,13 @@ 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.util.StorageUtil.createRecursionIntolerantLazyValueWithDefault; public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { - protected ClosureExpressionsTypingVisitor(@NotNull ExpressionTypingInternals facade) { + private final StorageManager storageManager; + + protected ClosureExpressionsTypingVisitor(@NotNull ExpressionTypingInternals facade, @NotNull StorageManager storageManager) { super(facade); + this.storageManager = storageManager; } @Override @@ -67,14 +73,13 @@ 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, createRecursionIntolerantLazyValueWithDefault( - ErrorUtils.createErrorType("Recursive dependency"), - new Function0() { - @Override - public JetType invoke() { - return descriptor.getDefaultType(); - } - })); + JetType defaultType = DeferredType.createRecursionIntolerant(storageManager, context.trace, + new Function0() { + @Override + public JetType invoke() { + return descriptor.getDefaultType(); + } + }); result[0] = defaultType; if (!context.trace.get(PROCESSED, expression)) { temporaryTrace.record(EXPRESSION_TYPE, expression, defaultType); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java index c813c8f2e22..84aeed8ea05 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java @@ -44,6 +44,7 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetTypeInfo; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.storage.StorageManager; import javax.inject.Inject; import java.util.Iterator; @@ -73,6 +74,8 @@ public class ExpressionTypingServices { private PlatformToKotlinClassMap platformToKotlinClassMap; @NotNull private CallResolverExtensionProvider extensionProvider; + @NotNull + private StorageManager storageManager; @NotNull public Project getProject() { @@ -137,7 +140,7 @@ public class ExpressionTypingServices { @Inject public void setPlatformToKotlinClassMap(@NotNull PlatformToKotlinClassMap platformToKotlinClassMap) { this.platformToKotlinClassMap = platformToKotlinClassMap; - this.expressionTypingFacade = ExpressionTypingVisitorDispatcher.create(platformToKotlinClassMap); + this.expressionTypingFacade = ExpressionTypingVisitorDispatcher.create(storageManager, platformToKotlinClassMap); } @NotNull @@ -150,6 +153,11 @@ public class ExpressionTypingServices { this.extensionProvider = extensionProvider; } + @Inject + public void setStorageManager(@NotNull StorageManager storageManager) { + this.storageManager = storageManager; + } + @NotNull public JetType safeGetType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace) { JetType type = getType(scope, expression, expectedType, dataFlowInfo, trace); @@ -276,7 +284,7 @@ public class ExpressionTypingServices { return JetTypeInfo.create(KotlinBuiltIns.getInstance().getUnitType(), context.dataFlowInfo); } - ExpressionTypingInternals blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(platformToKotlinClassMap, scope); + ExpressionTypingInternals blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(storageManager, platformToKotlinClassMap, scope); ExpressionTypingContext newContext = createContext(context, trace, scope, context.dataFlowInfo, NO_EXPECTED_TYPE); JetTypeInfo result = JetTypeInfo.create(null, context.dataFlowInfo); @@ -300,7 +308,7 @@ public class ExpressionTypingServices { if (newDataFlowInfo != context.dataFlowInfo) { newContext = newContext.replaceDataFlowInfo(newDataFlowInfo); } - blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(platformToKotlinClassMap, scope); + blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(storageManager, platformToKotlinClassMap, scope); } return result; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java index 00a10f09d8e..532f632418a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.types.DeferredType; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetTypeInfo; +import org.jetbrains.jet.storage.StorageManager; import org.jetbrains.jet.util.ReenteringLazyValueComputationException; import static org.jetbrains.jet.lang.diagnostics.Errors.TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM; @@ -34,25 +35,26 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.TYPECHECKER_HAS_RUN_INTO public class ExpressionTypingVisitorDispatcher extends JetVisitor implements ExpressionTypingInternals { @NotNull - public static ExpressionTypingFacade create(@NotNull PlatformToKotlinClassMap platformToKotlinClassMap) { - return new ExpressionTypingVisitorDispatcher(platformToKotlinClassMap, null); + public static ExpressionTypingFacade create(@NotNull StorageManager storageManager, @NotNull PlatformToKotlinClassMap platformToKotlinClassMap) { + return new ExpressionTypingVisitorDispatcher(storageManager, platformToKotlinClassMap, null); } @NotNull public static ExpressionTypingInternals createForBlock( + @NotNull StorageManager storageManager, @NotNull PlatformToKotlinClassMap platformToKotlinClassMap, @NotNull WritableScope writableScope ) { - return new ExpressionTypingVisitorDispatcher(platformToKotlinClassMap, writableScope); + return new ExpressionTypingVisitorDispatcher(storageManager, platformToKotlinClassMap, writableScope); } private final BasicExpressionTypingVisitor basic; private final ExpressionTypingVisitorForStatements statements; - private final ClosureExpressionsTypingVisitor closures = new ClosureExpressionsTypingVisitor(this); + private final ClosureExpressionsTypingVisitor closures; private final ControlStructureTypingVisitor controlStructures = new ControlStructureTypingVisitor(this); private final PatternMatchingTypingVisitor patterns = new PatternMatchingTypingVisitor(this); - private ExpressionTypingVisitorDispatcher(PlatformToKotlinClassMap platformToKotlinClassMap, WritableScope writableScope) { + private ExpressionTypingVisitorDispatcher(StorageManager storageManager, PlatformToKotlinClassMap platformToKotlinClassMap, WritableScope writableScope) { this.basic = new BasicExpressionTypingVisitor(this, platformToKotlinClassMap); if (writableScope != null) { this.statements = new ExpressionTypingVisitorForStatements(this, writableScope, basic, controlStructures, patterns); @@ -60,6 +62,7 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor() { - @Override - public Void invoke(Object t) { - return null; - } - }; - - - public static NotNullLazyValue createRecursionIntolerantLazyValueWithDefault( - @NotNull final T defaultValue, - @NotNull Function0 compute - ) { - //noinspection unchecked - return NO_LOCKS.createLazyValueWithPostCompute( - compute, - new Function1() { - @Override - public T invoke(Boolean firstTime) { - if (firstTime) throw new ReenteringLazyValueComputationException(); - return defaultValue; - } - }, - EMPTY_CONSUMER - ); - } -}