From 5b67cf67eb1b261bcc8646f113f306a90a1af969 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 21 Feb 2014 20:53:45 +0400 Subject: [PATCH] Usages of expressionTypingServices from ExpressionTypingContext are replaced with injection The basic principle behind this change is that no context object should store components. Components should be injected instead, and contexts only carry parameters around. Particular changes: - resolveCallWithGivenName() and resolveBinaryCall() moved to CallResolver - ForLoopConventionsChecker introduced to confine checking conventions for Iterator and Iterable - ExpressionTypingComponents introduced to deliver necessary components to ExpressionTypingVisitor's - Some static methods became non-static to get access to injected components - ExpressionTypingUtils and ControlStructureTypingUtils became components (got state injected) to avoid passing parameters around --- .../di/InjectorForLazyResolveWithJava.java | 27 ++- .../di/InjectorForTopDownAnalyzerForJvm.java | 27 ++- .../jet/di/InjectorForBodyResolve.java | 27 ++- .../jet/di/InjectorForLazyResolve.java | 27 ++- .../jetbrains/jet/di/InjectorForMacros.java | 31 +++- .../di/InjectorForTopDownAnalyzerBasic.java | 27 ++- .../resolve/DelegatedPropertyResolver.java | 15 +- .../jet/lang/resolve/calls/CallResolver.java | 34 +++- .../BasicExpressionTypingVisitor.java | 88 ++++------ .../ClosureExpressionsTypingVisitor.java | 33 ++-- .../ControlStructureTypingUtils.java | 12 +- .../ControlStructureTypingVisitor.java | 106 ++---------- .../ExpressionTypingComponents.java | 104 ++++++++++++ .../expressions/ExpressionTypingContext.java | 38 +---- .../ExpressionTypingInternals.java | 3 + .../expressions/ExpressionTypingServices.java | 39 ++--- .../expressions/ExpressionTypingUtils.java | 45 ++--- .../expressions/ExpressionTypingVisitor.java | 2 + .../ExpressionTypingVisitorDispatcher.java | 37 +++-- .../ExpressionTypingVisitorForStatements.java | 39 ++--- .../ForLoopConventionsChecker.java | 156 ++++++++++++++++++ .../PatternMatchingTypingVisitor.java | 6 +- .../jetbrains/jet/di/InjectorForTests.java | 35 +++- .../resolve/JetExpectedResolveDataUtil.java | 6 +- .../generators/injectors/GenerateInjectors.kt | 7 +- .../macro/BaseJetVariableMacro.java | 15 +- .../macro/JetAnyVariableMacro.java | 4 +- .../macro/JetIterableVariableMacro.java | 12 +- .../macro/JetSuggestVariableNameMacro.java | 4 +- .../di/InjectorForTopDownAnalyzerForJs.java | 27 ++- 30 files changed, 713 insertions(+), 320 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingComponents.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ForLoopConventionsChecker.java diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java index 56a14cbbd36..704d3db2263 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java @@ -36,6 +36,10 @@ import org.jetbrains.jet.lang.resolve.AnnotationResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; +import org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ForLoopConventionsChecker; import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; @@ -76,6 +80,10 @@ public class InjectorForLazyResolveWithJava { private final CallResolver callResolver; private final ArgumentTypeResolver argumentTypeResolver; private final ExpressionTypingServices expressionTypingServices; + private final ExpressionTypingComponents expressionTypingComponents; + private final ControlStructureTypingUtils controlStructureTypingUtils; + private final ExpressionTypingUtils expressionTypingUtils; + private final ForLoopConventionsChecker forLoopConventionsChecker; private final CallExpressionResolver callExpressionResolver; private final DescriptorResolver descriptorResolver; private final DelegatedPropertyResolver delegatedPropertyResolver; @@ -118,7 +126,11 @@ public class InjectorForLazyResolveWithJava { this.annotationResolver = new AnnotationResolver(); this.callResolver = new CallResolver(); this.argumentTypeResolver = new ArgumentTypeResolver(); - this.expressionTypingServices = new ExpressionTypingServices(globalContext, platformToKotlinClassMap); + this.expressionTypingComponents = new ExpressionTypingComponents(); + this.expressionTypingServices = new ExpressionTypingServices(expressionTypingComponents); + this.controlStructureTypingUtils = new ControlStructureTypingUtils(expressionTypingServices); + this.expressionTypingUtils = new ExpressionTypingUtils(expressionTypingServices, callResolver); + this.forLoopConventionsChecker = new ForLoopConventionsChecker(); this.callExpressionResolver = new CallExpressionResolver(); this.descriptorResolver = new DescriptorResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver(); @@ -168,6 +180,18 @@ public class InjectorForLazyResolveWithJava { expressionTypingServices.setProject(project); expressionTypingServices.setTypeResolver(typeResolver); + expressionTypingComponents.setCallResolver(callResolver); + expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils); + expressionTypingComponents.setExpressionTypingServices(expressionTypingServices); + expressionTypingComponents.setExpressionTypingUtils(expressionTypingUtils); + expressionTypingComponents.setForLoopConventionsChecker(forLoopConventionsChecker); + expressionTypingComponents.setGlobalContext(globalContext); + expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap); + + forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices); + forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils); + forLoopConventionsChecker.setProject(project); + callExpressionResolver.setExpressionTypingServices(expressionTypingServices); descriptorResolver.setAnnotationResolver(annotationResolver); @@ -176,6 +200,7 @@ public class InjectorForLazyResolveWithJava { descriptorResolver.setStorageManager(lockBasedStorageManager); descriptorResolver.setTypeResolver(typeResolver); + delegatedPropertyResolver.setCallResolver(callResolver); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); typeResolver.setAnnotationResolver(annotationResolver); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java index 2ef4f347c8e..862b54a7587 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -38,6 +38,10 @@ import org.jetbrains.jet.lang.resolve.AnnotationResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; +import org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ForLoopConventionsChecker; import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; @@ -89,6 +93,10 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly private final CallResolver callResolver; private final ArgumentTypeResolver argumentTypeResolver; private final ExpressionTypingServices expressionTypingServices; + private final ExpressionTypingComponents expressionTypingComponents; + private final ControlStructureTypingUtils controlStructureTypingUtils; + private final ExpressionTypingUtils expressionTypingUtils; + private final ForLoopConventionsChecker forLoopConventionsChecker; private final CallExpressionResolver callExpressionResolver; private final DescriptorResolver descriptorResolver; private final DelegatedPropertyResolver delegatedPropertyResolver; @@ -142,7 +150,11 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly this.annotationResolver = new AnnotationResolver(); this.callResolver = new CallResolver(); this.argumentTypeResolver = new ArgumentTypeResolver(); - this.expressionTypingServices = new ExpressionTypingServices(getTopDownAnalysisContext(), platformToKotlinClassMap); + this.expressionTypingComponents = new ExpressionTypingComponents(); + this.expressionTypingServices = new ExpressionTypingServices(expressionTypingComponents); + this.controlStructureTypingUtils = new ControlStructureTypingUtils(expressionTypingServices); + this.expressionTypingUtils = new ExpressionTypingUtils(expressionTypingServices, callResolver); + this.forLoopConventionsChecker = new ForLoopConventionsChecker(); this.callExpressionResolver = new CallExpressionResolver(); this.descriptorResolver = new DescriptorResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver(); @@ -219,6 +231,18 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly expressionTypingServices.setProject(project); expressionTypingServices.setTypeResolver(typeResolver); + expressionTypingComponents.setCallResolver(callResolver); + expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils); + expressionTypingComponents.setExpressionTypingServices(expressionTypingServices); + expressionTypingComponents.setExpressionTypingUtils(expressionTypingUtils); + expressionTypingComponents.setForLoopConventionsChecker(forLoopConventionsChecker); + expressionTypingComponents.setGlobalContext(topDownAnalysisContext); + expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap); + + forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices); + forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils); + forLoopConventionsChecker.setProject(project); + callExpressionResolver.setExpressionTypingServices(expressionTypingServices); descriptorResolver.setAnnotationResolver(annotationResolver); @@ -227,6 +251,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly descriptorResolver.setStorageManager(storageManager); descriptorResolver.setTypeResolver(typeResolver); + delegatedPropertyResolver.setCallResolver(callResolver); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); typeResolver.setAnnotationResolver(annotationResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java index a1cd1547df1..7c53afe7fa6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java @@ -28,6 +28,10 @@ import org.jetbrains.jet.lang.resolve.AnnotationResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; +import org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ForLoopConventionsChecker; import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; @@ -59,6 +63,10 @@ public class InjectorForBodyResolve { private final CallResolver callResolver; private final ArgumentTypeResolver argumentTypeResolver; private final ExpressionTypingServices expressionTypingServices; + private final ExpressionTypingComponents expressionTypingComponents; + private final ControlStructureTypingUtils controlStructureTypingUtils; + private final ExpressionTypingUtils expressionTypingUtils; + private final ForLoopConventionsChecker forLoopConventionsChecker; private final CallExpressionResolver callExpressionResolver; private final DescriptorResolver descriptorResolver; private final DelegatedPropertyResolver delegatedPropertyResolver; @@ -90,7 +98,11 @@ public class InjectorForBodyResolve { this.annotationResolver = new AnnotationResolver(); this.callResolver = new CallResolver(); this.argumentTypeResolver = new ArgumentTypeResolver(); - this.expressionTypingServices = new ExpressionTypingServices(bodiesResolveContext, platformToKotlinClassMap); + this.expressionTypingComponents = new ExpressionTypingComponents(); + this.expressionTypingServices = new ExpressionTypingServices(expressionTypingComponents); + this.controlStructureTypingUtils = new ControlStructureTypingUtils(expressionTypingServices); + this.expressionTypingUtils = new ExpressionTypingUtils(expressionTypingServices, callResolver); + this.forLoopConventionsChecker = new ForLoopConventionsChecker(); this.callExpressionResolver = new CallExpressionResolver(); this.descriptorResolver = new DescriptorResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver(); @@ -135,6 +147,18 @@ public class InjectorForBodyResolve { expressionTypingServices.setProject(project); expressionTypingServices.setTypeResolver(typeResolver); + expressionTypingComponents.setCallResolver(callResolver); + expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils); + expressionTypingComponents.setExpressionTypingServices(expressionTypingServices); + expressionTypingComponents.setExpressionTypingUtils(expressionTypingUtils); + expressionTypingComponents.setForLoopConventionsChecker(forLoopConventionsChecker); + expressionTypingComponents.setGlobalContext(bodiesResolveContext); + expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap); + + forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices); + forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils); + forLoopConventionsChecker.setProject(project); + callExpressionResolver.setExpressionTypingServices(expressionTypingServices); descriptorResolver.setAnnotationResolver(annotationResolver); @@ -143,6 +167,7 @@ public class InjectorForBodyResolve { descriptorResolver.setStorageManager(storageManager); descriptorResolver.setTypeResolver(typeResolver); + delegatedPropertyResolver.setCallResolver(callResolver); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); typeResolver.setAnnotationResolver(annotationResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java index 5f94a7aa1e9..21a37509834 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java @@ -28,6 +28,10 @@ import org.jetbrains.jet.lang.resolve.AnnotationResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; +import org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ForLoopConventionsChecker; import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; @@ -56,6 +60,10 @@ public class InjectorForLazyResolve { private final CallResolver callResolver; private final ArgumentTypeResolver argumentTypeResolver; private final ExpressionTypingServices expressionTypingServices; + private final ExpressionTypingComponents expressionTypingComponents; + private final ControlStructureTypingUtils controlStructureTypingUtils; + private final ExpressionTypingUtils expressionTypingUtils; + private final ForLoopConventionsChecker forLoopConventionsChecker; private final CallExpressionResolver callExpressionResolver; private final DescriptorResolver descriptorResolver; private final DelegatedPropertyResolver delegatedPropertyResolver; @@ -84,7 +92,11 @@ public class InjectorForLazyResolve { this.annotationResolver = new AnnotationResolver(); this.callResolver = new CallResolver(); this.argumentTypeResolver = new ArgumentTypeResolver(); - this.expressionTypingServices = new ExpressionTypingServices(globalContext, platformToKotlinClassMap); + this.expressionTypingComponents = new ExpressionTypingComponents(); + this.expressionTypingServices = new ExpressionTypingServices(expressionTypingComponents); + this.controlStructureTypingUtils = new ControlStructureTypingUtils(expressionTypingServices); + this.expressionTypingUtils = new ExpressionTypingUtils(expressionTypingServices, callResolver); + this.forLoopConventionsChecker = new ForLoopConventionsChecker(); this.callExpressionResolver = new CallExpressionResolver(); this.descriptorResolver = new DescriptorResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver(); @@ -121,6 +133,18 @@ public class InjectorForLazyResolve { expressionTypingServices.setProject(project); expressionTypingServices.setTypeResolver(typeResolver); + expressionTypingComponents.setCallResolver(callResolver); + expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils); + expressionTypingComponents.setExpressionTypingServices(expressionTypingServices); + expressionTypingComponents.setExpressionTypingUtils(expressionTypingUtils); + expressionTypingComponents.setForLoopConventionsChecker(forLoopConventionsChecker); + expressionTypingComponents.setGlobalContext(globalContext); + expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap); + + forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices); + forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils); + forLoopConventionsChecker.setProject(project); + callExpressionResolver.setExpressionTypingServices(expressionTypingServices); descriptorResolver.setAnnotationResolver(annotationResolver); @@ -129,6 +153,7 @@ public class InjectorForLazyResolve { descriptorResolver.setStorageManager(lockBasedStorageManager); descriptorResolver.setTypeResolver(typeResolver); + delegatedPropertyResolver.setCallResolver(callResolver); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); typeResolver.setAnnotationResolver(annotationResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java index 9982fa3b8dc..e8129541668 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java @@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.PlatformToKotlinClassMap; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; import org.jetbrains.jet.context.GlobalContext; import org.jetbrains.jet.storage.StorageManager; import org.jetbrains.jet.lang.resolve.AnnotationResolver; @@ -32,6 +33,9 @@ import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider; +import org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ForLoopConventionsChecker; import org.jetbrains.annotations.NotNull; import javax.annotation.PreDestroy; @@ -43,6 +47,7 @@ public class InjectorForMacros { private final ModuleDescriptor moduleDescriptor; private final PlatformToKotlinClassMap platformToKotlinClassMap; private final ExpressionTypingServices expressionTypingServices; + private final ExpressionTypingComponents expressionTypingComponents; private final GlobalContext globalContext; private final StorageManager storageManager; private final AnnotationResolver annotationResolver; @@ -55,6 +60,9 @@ public class InjectorForMacros { private final DescriptorResolver descriptorResolver; private final DelegatedPropertyResolver delegatedPropertyResolver; private final CallResolverExtensionProvider callResolverExtensionProvider; + private final ControlStructureTypingUtils controlStructureTypingUtils; + private final ExpressionTypingUtils expressionTypingUtils; + private final ForLoopConventionsChecker forLoopConventionsChecker; public InjectorForMacros( @NotNull Project project, @@ -63,8 +71,9 @@ public class InjectorForMacros { this.project = project; this.moduleDescriptor = moduleDescriptor; this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap(); + this.expressionTypingComponents = new ExpressionTypingComponents(); + this.expressionTypingServices = new ExpressionTypingServices(getExpressionTypingComponents()); this.globalContext = org.jetbrains.jet.context.ContextPackage.GlobalContext(); - this.expressionTypingServices = new ExpressionTypingServices(globalContext, platformToKotlinClassMap); this.storageManager = globalContext.getStorageManager(); this.annotationResolver = new AnnotationResolver(); this.callResolver = new CallResolver(); @@ -76,6 +85,9 @@ public class InjectorForMacros { this.descriptorResolver = new DescriptorResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver(); this.callResolverExtensionProvider = new CallResolverExtensionProvider(); + this.controlStructureTypingUtils = new ControlStructureTypingUtils(getExpressionTypingServices()); + this.expressionTypingUtils = new ExpressionTypingUtils(getExpressionTypingServices(), callResolver); + this.forLoopConventionsChecker = new ForLoopConventionsChecker(); this.expressionTypingServices.setAnnotationResolver(annotationResolver); this.expressionTypingServices.setCallExpressionResolver(callExpressionResolver); @@ -85,6 +97,14 @@ public class InjectorForMacros { this.expressionTypingServices.setProject(project); this.expressionTypingServices.setTypeResolver(typeResolver); + this.expressionTypingComponents.setCallResolver(callResolver); + this.expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils); + this.expressionTypingComponents.setExpressionTypingServices(expressionTypingServices); + this.expressionTypingComponents.setExpressionTypingUtils(expressionTypingUtils); + this.expressionTypingComponents.setForLoopConventionsChecker(forLoopConventionsChecker); + this.expressionTypingComponents.setGlobalContext(globalContext); + this.expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap); + annotationResolver.setCallResolver(callResolver); annotationResolver.setExpressionTypingServices(expressionTypingServices); @@ -110,8 +130,13 @@ public class InjectorForMacros { descriptorResolver.setStorageManager(storageManager); descriptorResolver.setTypeResolver(typeResolver); + delegatedPropertyResolver.setCallResolver(callResolver); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); + forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices); + forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils); + forLoopConventionsChecker.setProject(project); + } @PreDestroy @@ -122,4 +147,8 @@ public class InjectorForMacros { return this.expressionTypingServices; } + public ExpressionTypingComponents getExpressionTypingComponents() { + return this.expressionTypingComponents; + } + } diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java index 102bf906215..fd4bda20c12 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java @@ -31,6 +31,10 @@ import org.jetbrains.jet.lang.resolve.AnnotationResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; +import org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ForLoopConventionsChecker; import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; @@ -71,6 +75,10 @@ public class InjectorForTopDownAnalyzerBasic { private final CallResolver callResolver; private final ArgumentTypeResolver argumentTypeResolver; private final ExpressionTypingServices expressionTypingServices; + private final ExpressionTypingComponents expressionTypingComponents; + private final ControlStructureTypingUtils controlStructureTypingUtils; + private final ExpressionTypingUtils expressionTypingUtils; + private final ForLoopConventionsChecker forLoopConventionsChecker; private final CallExpressionResolver callExpressionResolver; private final DescriptorResolver descriptorResolver; private final DelegatedPropertyResolver delegatedPropertyResolver; @@ -110,7 +118,11 @@ public class InjectorForTopDownAnalyzerBasic { this.annotationResolver = new AnnotationResolver(); this.callResolver = new CallResolver(); this.argumentTypeResolver = new ArgumentTypeResolver(); - this.expressionTypingServices = new ExpressionTypingServices(getTopDownAnalysisContext(), platformToKotlinClassMap); + this.expressionTypingComponents = new ExpressionTypingComponents(); + this.expressionTypingServices = new ExpressionTypingServices(expressionTypingComponents); + this.controlStructureTypingUtils = new ControlStructureTypingUtils(expressionTypingServices); + this.expressionTypingUtils = new ExpressionTypingUtils(expressionTypingServices, callResolver); + this.forLoopConventionsChecker = new ForLoopConventionsChecker(); this.callExpressionResolver = new CallExpressionResolver(); this.descriptorResolver = new DescriptorResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver(); @@ -174,6 +186,18 @@ public class InjectorForTopDownAnalyzerBasic { expressionTypingServices.setProject(project); expressionTypingServices.setTypeResolver(typeResolver); + expressionTypingComponents.setCallResolver(callResolver); + expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils); + expressionTypingComponents.setExpressionTypingServices(expressionTypingServices); + expressionTypingComponents.setExpressionTypingUtils(expressionTypingUtils); + expressionTypingComponents.setForLoopConventionsChecker(forLoopConventionsChecker); + expressionTypingComponents.setGlobalContext(topDownAnalysisContext); + expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap); + + forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices); + forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils); + forLoopConventionsChecker.setProject(project); + callExpressionResolver.setExpressionTypingServices(expressionTypingServices); descriptorResolver.setAnnotationResolver(annotationResolver); @@ -182,6 +206,7 @@ public class InjectorForTopDownAnalyzerBasic { descriptorResolver.setStorageManager(storageManager); descriptorResolver.setTypeResolver(typeResolver); + delegatedPropertyResolver.setCallResolver(callResolver); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); typeResolver.setAnnotationResolver(annotationResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatedPropertyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatedPropertyResolver.java index 33f90effc06..3cc288d0deb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatedPropertyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatedPropertyResolver.java @@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.diagnostics.rendering.Renderers; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; @@ -58,11 +59,19 @@ public class DelegatedPropertyResolver { @NotNull private ExpressionTypingServices expressionTypingServices; + @NotNull + private CallResolver callResolver; + @Inject public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) { this.expressionTypingServices = expressionTypingServices; } + @Inject + public void setCallResolver(@NotNull CallResolver callResolver) { + this.callResolver = callResolver; + } + @Nullable public JetType getDelegatedPropertyGetMethodReturnType( @NotNull PropertyDescriptor propertyDescriptor, @@ -164,7 +173,7 @@ public class DelegatedPropertyResolver { ExpressionTypingContext context = ExpressionTypingContext.newContext( expressionTypingServices, trace, scope, DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE); - Project project = context.expressionTypingServices.getProject(); + Project project = expressionTypingServices.getProject(); boolean hasThis = propertyDescriptor.getReceiverParameter() != null || propertyDescriptor.getExpectedThisObject() != null; @@ -174,7 +183,7 @@ public class DelegatedPropertyResolver { arguments.add(createExpression(project, KotlinBuiltIns.getInstance().getPropertyMetadataImpl().getName().asString() + "(\"" + propertyDescriptor.getName().asString() + "\")")); if (!isGet) { - JetReferenceExpression fakeArgument = (JetReferenceExpression) createFakeExpressionOfType(context.expressionTypingServices.getProject(), trace, + JetReferenceExpression fakeArgument = (JetReferenceExpression) createFakeExpressionOfType(expressionTypingServices.getProject(), trace, "fakeArgument" + arguments.size(), propertyDescriptor.getType()); arguments.add(fakeArgument); @@ -189,7 +198,7 @@ public class DelegatedPropertyResolver { Call call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT); trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, call); - return context.resolveCallWithGivenName(call, fakeCalleeExpression, functionName); + return callResolver.resolveCallWithGivenName(context, call, fakeCalleeExpression, functionName); } private String renderCall(@NotNull Call call, @NotNull BindingContext context) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index d7d3d14cb08..e808a104b71 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -36,13 +36,15 @@ import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImp import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionResultsHandler; import org.jetbrains.jet.lang.resolve.calls.tasks.*; +import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall; import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.resolve.calls.util.JetFakeReference; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingContext; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; import org.jetbrains.jet.lang.types.expressions.LabelResolver; @@ -62,7 +64,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLUTION_SCOPE; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS; import static org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults.Code.*; -import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; @SuppressWarnings("RedundantTypeArguments") @@ -116,6 +117,20 @@ public class CallResolver { context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, nameExpression); } + @NotNull + public OverloadResolutionResults resolveCallWithGivenName( + @NotNull ExpressionTypingContext context, + @NotNull Call call, + @NotNull JetReferenceExpression functionReference, + @NotNull Name name + ) { + return resolveCallWithGivenName( + BasicCallResolutionContext.create(context, call, CheckValueArgumentsMode.ENABLED), + functionReference, + name + ); + } + @NotNull public OverloadResolutionResults resolveCallWithGivenName( @NotNull BasicCallResolutionContext context, @@ -140,6 +155,21 @@ public class CallResolver { context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference); } + @NotNull + public OverloadResolutionResults resolveBinaryCall( + ExpressionTypingContext context, + ExpressionReceiver receiver, + JetBinaryExpression binaryExpression, + Name name + ) { + return resolveCallWithGivenName( + context, + CallMaker.makeCall(receiver, binaryExpression), + binaryExpression.getOperationReference(), + name + ); + } + @NotNull public OverloadResolutionResults resolveFunctionCall( @NotNull BindingTrace trace, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index b0f80d65c05..7921e8abda2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -22,7 +22,6 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.PlatformToKotlinClassMap; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor; @@ -77,7 +76,6 @@ import static org.jetbrains.jet.lang.resolve.calls.context.ContextDependency.IND import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER; import static org.jetbrains.jet.lang.types.TypeUtils.*; import static org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils.createCallForSpecialConstruction; -import static org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils.resolveSpecialConstructionAsCall; import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.*; import static org.jetbrains.jet.lang.types.expressions.TypeReconstructionUtil.reconstructBareType; import static org.jetbrains.jet.lexer.JetTokens.AS_KEYWORD; @@ -88,18 +86,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { private static final TokenSet BARE_TYPES_ALLOWED = TokenSet.create(AS_KEYWORD, AS_SAFE); - private final PlatformToKotlinClassMap platformToKotlinClassMap; - - protected BasicExpressionTypingVisitor(@NotNull ExpressionTypingInternals facade, @NotNull PlatformToKotlinClassMap platformToKotlinClassMap) { + protected BasicExpressionTypingVisitor(@NotNull ExpressionTypingInternals facade) { super(facade); - this.platformToKotlinClassMap = platformToKotlinClassMap; } @Override public JetTypeInfo visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression, ExpressionTypingContext context) { // TODO : other members // TODO : type substitutions??? - CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver(); + CallExpressionResolver callExpressionResolver = components.expressionTypingServices.getCallExpressionResolver(); JetTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, NO_RECEIVER, null, context); JetType type = DataFlowUtils.checkType(typeInfo.getType(), expression, context); ExpressionTypingUtils.checkCapturingInClosure(expression, context.trace, context.scope); @@ -151,7 +146,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { boolean allowBareTypes = BARE_TYPES_ALLOWED.contains(operationType); TypeResolutionContext typeResolutionContext = new TypeResolutionContext(context.scope, context.trace, true, allowBareTypes); - PossiblyBareType possiblyBareTarget = context.expressionTypingServices.getTypeResolver().resolvePossiblyBareType(typeResolutionContext, right); + PossiblyBareType possiblyBareTarget = components.expressionTypingServices.getTypeResolver().resolvePossiblyBareType(typeResolutionContext, right); if (operationType == JetTokens.COLON) { // We do not allow bare types on static assertions, because static assertions provide an expected type for their argument, @@ -210,7 +205,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ) { if (actualType == null || noExpectedType(targetType)) return; - if (!CastDiagnosticsUtil.isCastPossible(actualType, targetType, platformToKotlinClassMap)) { + if (!CastDiagnosticsUtil.isCastPossible(actualType, targetType, components.platformToKotlinClassMap)) { context.trace.report(CAST_NEVER_SUCCEEDS.on(expression.getOperationReference())); } else { @@ -278,15 +273,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { throw new IllegalStateException("Unknown code: " + resolutionResult.getCode()); } - private static JetTypeInfo errorInSuper(JetSuperExpression expression, ExpressionTypingContext context) { + private JetTypeInfo errorInSuper(JetSuperExpression expression, ExpressionTypingContext context) { JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier(); if (superTypeQualifier != null) { - context.expressionTypingServices.getTypeResolver().resolveType(context.scope, superTypeQualifier, context.trace, true); + components.expressionTypingServices.getTypeResolver().resolveType(context.scope, superTypeQualifier, context.trace, true); } return JetTypeInfo.create(null, context.dataFlowInfo); } - private static JetType checkPossiblyQualifiedSuper( + private JetType checkPossiblyQualifiedSuper( JetSuperExpression expression, ExpressionTypingContext context, ReceiverParameterDescriptor thisReceiver @@ -307,15 +302,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { JetUserType userType = (JetUserType) typeElement; // This may be just a superclass name even if the superclass is generic if (userType.getTypeArguments().isEmpty()) { - classifierCandidate = context.expressionTypingServices.getTypeResolver().resolveClass(context.scope, userType, context.trace); + classifierCandidate = components.expressionTypingServices.getTypeResolver().resolveClass(context.scope, userType, context.trace); } else { - supertype = context.expressionTypingServices.getTypeResolver().resolveType(context.scope, superTypeQualifier, context.trace, true); + supertype = components.expressionTypingServices.getTypeResolver().resolveType(context.scope, superTypeQualifier, context.trace, true); redundantTypeArguments = userType.getTypeArgumentList(); } } else { - supertype = context.expressionTypingServices.getTypeResolver().resolveType(context.scope, superTypeQualifier, context.trace, true); + supertype = components.expressionTypingServices.getTypeResolver().resolveType(context.scope, superTypeQualifier, context.trace, true); } if (supertype != null) { @@ -444,12 +439,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { @Override public JetTypeInfo visitBlockExpression(@NotNull JetBlockExpression expression, ExpressionTypingContext context) { - return visitBlockExpression(expression, context, false); - } - - public static JetTypeInfo visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context, boolean isStatement) { - return context.expressionTypingServices.getBlockReturnedType( - expression, isStatement ? CoercionStrategy.COERCION_TO_UNIT : CoercionStrategy.NO_COERCION, context); + return components.expressionTypingServices.getBlockReturnedType(expression, context, false); } @Override @@ -459,7 +449,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { JetType receiverType = typeReference == null ? null - : context.expressionTypingServices.getTypeResolver().resolveType(context.scope, typeReference, context.trace, false); + : components.expressionTypingServices.getTypeResolver().resolveType(context.scope, typeReference, context.trace, false); JetSimpleNameExpression callableReference = expression.getCallableReference(); if (callableReference.getReferencedName().isEmpty()) { @@ -473,7 +463,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Nullable - private static JetType getCallableReferenceType( + private JetType getCallableReferenceType( @NotNull JetCallableReferenceExpression expression, @Nullable JetType lhsType, @NotNull ExpressionTypingContext context @@ -525,7 +515,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Nullable - private static FunctionDescriptor resolveCallableReferenceTarget( + private FunctionDescriptor resolveCallableReferenceTarget( @Nullable JetType lhsType, @NotNull ExpressionTypingContext context, @NotNull JetCallableReferenceExpression expression, @@ -567,7 +557,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Nullable - private static FunctionDescriptor resolveCallableNotCheckingArguments( + private FunctionDescriptor resolveCallableNotCheckingArguments( @NotNull JetSimpleNameExpression reference, @NotNull ReceiverValue receiver, @NotNull ExpressionTypingContext context, @@ -578,7 +568,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { TemporaryBindingTrace trace = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", reference); ExpressionTypingContext contextForResolve = context.replaceBindingTrace(trace).replaceExpectedType(NO_EXPECTED_TYPE); - ResolvedCallWithTrace function = contextForResolve.expressionTypingServices.getCallExpressionResolver() + ResolvedCallWithTrace function = components.expressionTypingServices.getCallExpressionResolver() .getResolvedCallForFunction(call, reference, contextForResolve, CheckValueArgumentsMode.DISABLED, result); if (!result[0]) return null; @@ -595,13 +585,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { @Override public JetTypeInfo visitQualifiedExpression(@NotNull JetQualifiedExpression expression, ExpressionTypingContext context) { - CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver(); + CallExpressionResolver callExpressionResolver = components.expressionTypingServices.getCallExpressionResolver(); return callExpressionResolver.getQualifiedExpressionTypeInfo(expression, context); } @Override public JetTypeInfo visitCallExpression(@NotNull JetCallExpression expression, ExpressionTypingContext context) { - CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver(); + CallExpressionResolver callExpressionResolver = components.expressionTypingServices.getCallExpressionResolver(); return callExpressionResolver.getCallExpressionTypeInfo(expression, NO_RECEIVER, null, context); } @@ -659,7 +649,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ExpressionReceiver receiver = new ExpressionReceiver(baseExpression, type); // Resolve the operation reference - OverloadResolutionResults resolutionResults = context.resolveCallWithGivenName( + OverloadResolutionResults resolutionResults = components.callResolver.resolveCallWithGivenName( + context, CallMaker.makeCall(receiver, expression), expression.getOperationReference(), name); @@ -726,7 +717,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { assert operationSign.getReferencedNameElementType() == JetTokens.EXCLEXCL; Call call = createCallForSpecialConstruction(expression, Collections.singletonList(baseExpression)); - resolveSpecialConstructionAsCall( + components.controlStructureTypingUtils.resolveSpecialConstructionAsCall( call, "ExclExcl", Collections.singletonList("baseExpr"), Collections.singletonList(true), context, null); JetTypeInfo baseTypeInfo = BindingContextUtils.getRecordedTypeInfo(baseExpression, context.trace.getBindingContext()); assert baseTypeInfo != null : "Base expression was not processed: " + expression; @@ -893,7 +884,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { Call call = CallMaker.makeCallWithExpressions(operationSign, receiver, null, operationSign, Collections.singletonList(right)); ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny); OverloadResolutionResults resolutionResults = - newContext.resolveCallWithGivenName(call, operationSign, OperatorConventions.EQUALS); + components.callResolver.resolveCallWithGivenName(newContext, call, operationSign, OperatorConventions.EQUALS); traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() { @Override @@ -991,7 +982,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } Call call = createCallForSpecialConstruction(expression, Lists.newArrayList(left, right)); - ResolvedCall resolvedCall = resolveSpecialConstructionAsCall( + ResolvedCall resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall( call, "Elvis", Lists.newArrayList("left", "right"), Lists.newArrayList(true, false), contextWithExpectedType, null); JetTypeInfo leftTypeInfo = BindingContextUtils.getRecordedTypeInfo(left, context.trace.getBindingContext()); assert leftTypeInfo != null : "Left expression was not processed: " + expression; @@ -1029,7 +1020,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, contextWithNoExpectedType); ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo); - OverloadResolutionResults resolutionResult = contextWithDataFlow.resolveCallWithGivenName( + OverloadResolutionResults resolutionResult = components.callResolver.resolveCallWithGivenName( + contextWithDataFlow, CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)), operationSign, OperatorConventions.CONTAINS); @@ -1135,7 +1127,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { OverloadResolutionResults resolutionResults; if (left != null) { ExpressionReceiver receiver = safeGetExpressionReceiver(facade, left, context); - resolutionResults = getResolutionResultsForBinaryCall(context.scope, name, contextWithDataFlow, binaryExpression, receiver); + resolutionResults = components.callResolver.resolveBinaryCall( + contextWithDataFlow.replaceScope(context.scope), + receiver, binaryExpression, name + ); } else { resolutionResults = OverloadResolutionResultsImpl.nameNotFound(); @@ -1148,23 +1143,6 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { return JetTypeInfo.create(OverloadResolutionResultsUtil.getResultingType(resolutionResults, context.contextDependency), dataFlowInfo); } - @NotNull - static - /*package*/ OverloadResolutionResults getResolutionResultsForBinaryCall( - JetScope scope, - Name name, - ExpressionTypingContext context, - JetBinaryExpression binaryExpression, - ExpressionReceiver receiver - ) { -// ExpressionReceiver receiver = safeGetExpressionReceiver(facade, binaryExpression.getLeft(), context.replaceScope(scope)); - return context.replaceScope(scope).resolveCallWithGivenName( - CallMaker.makeCall(receiver, binaryExpression), - binaryExpression.getOperationReference(), - name - ); - } - @Override public JetTypeInfo visitDeclaration(@NotNull JetDeclaration dcl, ExpressionTypingContext context) { context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(dcl)); @@ -1217,7 +1195,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } public JetTypeInfo visitAnnotatedExpression(JetAnnotatedExpression expression, ExpressionTypingContext context, boolean isStatement) { - context.expressionTypingServices.getAnnotationResolver().resolveAnnotationsWithArguments( + components.expressionTypingServices.getAnnotationResolver().resolveAnnotationsWithArguments( context.scope, expression.getAnnotationEntries(), context.trace); JetExpression baseExpression = expression.getBaseExpression(); @@ -1262,12 +1240,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ExpressionReceiver receiver = new ExpressionReceiver(arrayExpression, arrayType); if (!isGet) assert rightHandSide != null; - OverloadResolutionResults functionResults = context.resolveCallWithGivenName( + OverloadResolutionResults functionResults = components.callResolver.resolveCallWithGivenName( + context, isGet ? CallMaker.makeArrayGetCall(receiver, arrayAccessExpression, Call.CallType.ARRAY_GET_METHOD) : CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide, Call.CallType.ARRAY_SET_METHOD), arrayAccessExpression, - Name.identifier(isGet ? "get" : "set")); + Name.identifier(isGet ? "get" : "set") + ); List indices = arrayAccessExpression.getIndexExpressions(); // The accumulated data flow info of all index expressions is saved on the last index 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 5a03840dac4..3d426889325 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 @@ -23,7 +23,6 @@ import com.intellij.util.containers.ContainerUtil; import jet.Function0; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.context.GlobalContext; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.impl.*; @@ -51,14 +50,9 @@ import static org.jetbrains.jet.lang.types.TypeUtils.*; import static org.jetbrains.jet.lang.types.expressions.CoercionStrategy.COERCION_TO_UNIT; public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { - private final GlobalContext globalContext; - protected ClosureExpressionsTypingVisitor( - @NotNull GlobalContext globalContext, - @NotNull ExpressionTypingInternals facade - ) { + protected ClosureExpressionsTypingVisitor(@NotNull ExpressionTypingInternals facade) { super(facade); - this.globalContext = globalContext; } @Override @@ -76,7 +70,8 @@ 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.createRecursionIntolerant(globalContext.getStorageManager(), context.trace, + JetType defaultType = DeferredType.createRecursionIntolerant(components.globalContext.getStorageManager(), + context.trace, new Function0() { @Override public JetType invoke() { @@ -93,7 +88,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { }; ObservableBindingTrace traceAdapter = new ObservableBindingTrace(temporaryTrace); traceAdapter.addHandler(CLASS, handler); - TopDownAnalyzer.processClassOrObject(globalContext, + TopDownAnalyzer.processClassOrObject(components.globalContext, null, // don't need to add classifier of object literal to any scope context.replaceBindingTrace(traceAdapter).replaceContextDependency(INDEPENDENT), context.scope.getContainingDeclaration(), @@ -177,7 +172,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { } @NotNull - private static AnonymousFunctionDescriptor createFunctionDescriptor( + private AnonymousFunctionDescriptor createFunctionDescriptor( @NotNull JetFunctionLiteralExpression expression, @NotNull ExpressionTypingContext context, boolean functionTypeExpected @@ -200,7 +195,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { } } else { - effectiveReceiverType = context.expressionTypingServices.getTypeResolver().resolveType(context.scope, receiverTypeRef, context.trace, true); + effectiveReceiverType = components.expressionTypingServices.getTypeResolver().resolveType(context.scope, receiverTypeRef, context.trace, true); } functionDescriptor.initialize(effectiveReceiverType, ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER, @@ -215,7 +210,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { } @NotNull - private static List createValueParameterDescriptors( + private List createValueParameterDescriptors( @NotNull ExpressionTypingContext context, @NotNull JetFunctionLiteral functionLiteral, @NotNull FunctionDescriptorImpl functionDescriptor, @@ -254,7 +249,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { } @NotNull - private static ValueParameterDescriptor createValueParameterDescriptor( + private ValueParameterDescriptor createValueParameterDescriptor( @NotNull ExpressionTypingContext context, @NotNull FunctionDescriptorImpl functionDescriptor, @NotNull List declaredValueParameters, @@ -273,7 +268,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { } JetType type; if (typeReference != null) { - type = context.expressionTypingServices.getTypeResolver().resolveType(context.scope, typeReference, context.trace, true); + type = components.expressionTypingServices.getTypeResolver().resolveType(context.scope, typeReference, context.trace, true); if (expectedType != null) { if (!JetTypeChecker.INSTANCE.isSubtypeOf(expectedType, type)) { context.trace.report(EXPECTED_PARAMETER_TYPE_MISMATCH.on(declaredParameter, expectedType)); @@ -291,12 +286,12 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { type = CANT_INFER_LAMBDA_PARAM_TYPE; } } - return context.expressionTypingServices.getDescriptorResolver().resolveValueParameterDescriptorWithAnnotationArguments( + return components.expressionTypingServices.getDescriptorResolver().resolveValueParameterDescriptorWithAnnotationArguments( context.scope, functionDescriptor, declaredParameter, index, type, context.trace); } @NotNull - private static JetType computeReturnType( + private JetType computeReturnType( @NotNull JetFunctionLiteralExpression expression, @NotNull ExpressionTypingContext context, @NotNull SimpleFunctionDescriptorImpl functionDescriptor, @@ -314,7 +309,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { } @Nullable - private static JetType computeUnsafeReturnType( + private JetType computeUnsafeReturnType( @NotNull JetFunctionLiteralExpression expression, @NotNull ExpressionTypingContext context, @NotNull SimpleFunctionDescriptorImpl functionDescriptor, @@ -328,7 +323,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef(); JetType declaredReturnType = null; if (returnTypeRef != null) { - declaredReturnType = context.expressionTypingServices.getTypeResolver().resolveType(context.scope, returnTypeRef, context.trace, true); + declaredReturnType = components.expressionTypingServices.getTypeResolver().resolveType(context.scope, returnTypeRef, context.trace, true); // This is needed for ControlStructureTypingVisitor#visitReturnExpression() to properly type-check returned expressions functionDescriptor.setReturnType(declaredReturnType); if (expectedReturnType != null) { @@ -344,7 +339,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { ? declaredReturnType : (expectedReturnType != null ? expectedReturnType : NO_EXPECTED_TYPE)); - JetType typeOfBodyExpression = context.expressionTypingServices.getBlockReturnedType(bodyExpression, COERCION_TO_UNIT, newContext).getType(); + JetType typeOfBodyExpression = components.expressionTypingServices.getBlockReturnedType(bodyExpression, COERCION_TO_UNIT, newContext).getType(); List returnedExpressionTypes = Lists.newArrayList(getTypesOfLocallyReturnedExpressions( functionLiteral, context.trace, collectReturns(bodyExpression))); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java index 7b6a78f30bc..ee7c0ac9fa1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java @@ -55,10 +55,14 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.CALL; import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL; public class ControlStructureTypingUtils { - private ControlStructureTypingUtils() { + + private final ExpressionTypingServices expressionTypingServices; + + public ControlStructureTypingUtils(@NotNull ExpressionTypingServices expressionTypingServices) { + this.expressionTypingServices = expressionTypingServices; } - /*package*/ static ResolvedCall resolveSpecialConstructionAsCall( + /*package*/ ResolvedCall resolveSpecialConstructionAsCall( @NotNull Call call, @NotNull String constructionName, @NotNull List argumentNames, @@ -69,10 +73,10 @@ public class ControlStructureTypingUtils { SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction( constructionName.toUpperCase(), argumentNames, isArgumentNullable); JetReferenceExpression reference = JetPsiFactory.createSimpleName( - context.expressionTypingServices.getProject(), "fake" + constructionName + "Call"); + expressionTypingServices.getProject(), "fake" + constructionName + "Call"); TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName); ResolutionCandidate resolutionCandidate = ResolutionCandidate.create(function, null); - CallResolver callResolver = context.expressionTypingServices.getCallResolver(); + CallResolver callResolver = expressionTypingServices.getCallResolver(); OverloadResolutionResults results = callResolver.resolveCallWithKnownCandidate( call, tracing, reference, context, resolutionCandidate, dataFlowInfoForArguments); assert results.isSingleResult() : "Not single result after resolving one known candidate"; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java index e54d57f2a42..a74c4e4b24a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.lang.types.expressions; import com.google.common.collect.Lists; -import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; @@ -26,7 +25,6 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; -import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -36,8 +34,6 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; -import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; -import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; @@ -46,7 +42,6 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver; 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.util.slicedmap.WritableSlice; import java.util.ArrayList; import java.util.Collections; @@ -122,7 +117,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { Call callForIf = createCallForSpecialConstruction(ifExpression, Lists.newArrayList(thenBlock, elseBlock)); MutableDataFlowInfoForArguments dataFlowInfoForArguments = createDataFlowInfoForArgumentsForIfCall(callForIf, thenInfo, elseInfo); - ResolvedCall resolvedCall = resolveSpecialConstructionAsCall( + ResolvedCall resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall( callForIf, "If", Lists.newArrayList("thenBranch", "elseBranch"), Lists.newArrayList(false, false), contextWithExpectedType, dataFlowInfoForArguments); @@ -158,7 +153,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } @NotNull - private static JetTypeInfo getTypeInfoWhenOnlyOneBranchIsPresent( + private JetTypeInfo getTypeInfoWhenOnlyOneBranchIsPresent( @NotNull JetExpression presentBranch, @NotNull WritableScopeImpl presentScope, @NotNull DataFlowInfo presentInfo, @@ -169,7 +164,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { ) { ExpressionTypingContext newContext = context.replaceDataFlowInfo(presentInfo).replaceExpectedType(NO_EXPECTED_TYPE) .replaceContextDependency(INDEPENDENT); - JetTypeInfo typeInfo = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope( + JetTypeInfo typeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope( presentScope, Collections.singletonList(presentBranch), CoercionStrategy.NO_COERCION, newContext, context.trace); JetType type = typeInfo.getType(); DataFlowInfo dataFlowInfo; @@ -199,7 +194,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (body != null) { WritableScopeImpl scopeToExtend = newWritableScopeImpl(context, "Scope extended in while's condition"); DataFlowInfo conditionInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo); - context.expressionTypingServices.getBlockReturnedTypeWithWritableScope( + components.expressionTypingServices.getBlockReturnedTypeWithWritableScope( scopeToExtend, Collections.singletonList(body), CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(conditionInfo), context.trace); } @@ -266,7 +261,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (!functionLiteral.hasParameterSpecification()) { WritableScope writableScope = newWritableScopeImpl(context, "do..while body scope"); conditionScope = writableScope; - context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(writableScope, functionLiteral.getBodyExpression().getStatements(), CoercionStrategy.NO_COERCION, context, context.trace); + components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(writableScope, functionLiteral.getBodyExpression().getStatements(), CoercionStrategy.NO_COERCION, context, context.trace); context.trace.record(BindingContext.BLOCK, function); } else { @@ -284,7 +279,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { else { block = Collections.singletonList(body); } - context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(writableScope, block, CoercionStrategy.NO_COERCION, context, context.trace); + components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(writableScope, block, CoercionStrategy.NO_COERCION, context, context.trace); } JetExpression condition = expression.getCondition(); DataFlowInfo conditionDataFlowInfo = checkCondition(conditionScope, condition, context); @@ -315,7 +310,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { ExpressionReceiver loopRangeReceiver = getExpressionReceiver(facade, loopRange, context.replaceScope(context.scope)); dataFlowInfo = facade.getTypeInfo(loopRange, context).getDataFlowInfo(); if (loopRangeReceiver != null) { - expectedParameterType = checkIterableConvention(loopRangeReceiver, context); + expectedParameterType = components.forLoopConventionsChecker.checkIterableConvention(loopRangeReceiver, context); } } @@ -332,20 +327,21 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (multiParameter != null && loopRange != null) { JetType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType; TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType); - ExpressionTypingUtils.defineLocalVariablesFromMultiDeclaration(loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context); + components.expressionTypingUtils.defineLocalVariablesFromMultiDeclaration(loopScope, multiParameter, iteratorNextAsReceiver, + loopRange, context); } } JetExpression body = expression.getBody(); if (body != null) { - context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(loopScope, Collections.singletonList(body), + components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(loopScope, Collections.singletonList(body), CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(dataFlowInfo), context.trace); } return DataFlowUtils.checkType(KotlinBuiltIns.getInstance().getUnitType(), expression, contextWithExpectedType, dataFlowInfo); } - private static VariableDescriptor createLoopParameterDescriptor( + private VariableDescriptor createLoopParameterDescriptor( JetParameter loopParameter, JetType expectedParameterType, ExpressionTypingContext context @@ -355,7 +351,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { JetTypeReference typeReference = loopParameter.getTypeReference(); VariableDescriptor variableDescriptor; if (typeReference != null) { - variableDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveLocalVariableDescriptor(context.scope, loopParameter, context.trace); + variableDescriptor = components.expressionTypingServices.getDescriptorResolver().resolveLocalVariableDescriptor(context.scope, loopParameter, context.trace); JetType actualParameterType = variableDescriptor.getType(); if (expectedParameterType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(expectedParameterType, actualParameterType)) { @@ -366,7 +362,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (expectedParameterType == null) { expectedParameterType = ErrorUtils.createErrorType("Error"); } - variableDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveLocalVariableDescriptor(loopParameter, expectedParameterType, context.trace, context.scope); + variableDescriptor = components.expressionTypingServices.getDescriptorResolver().resolveLocalVariableDescriptor(loopParameter, expectedParameterType, context.trace, context.scope); } { @@ -381,80 +377,6 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { return variableDescriptor; } - @Nullable - /*package*/ static JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) { - JetExpression loopRangeExpression = loopRange.getExpression(); - - // Make a fake call loopRange.iterator(), and try to resolve it - Name iterator = Name.identifier("iterator"); - Pair> calls = makeAndResolveFakeCall(loopRange, context, Collections.emptyList(), iterator); - Call iteratorCall = calls.getFirst(); - OverloadResolutionResults iteratorResolutionResults = calls.getSecond(); - - if (iteratorResolutionResults.isSuccess()) { - ResolvedCall iteratorResolvedCall = iteratorResolutionResults.getResultingCall(); - context.trace.record(LOOP_RANGE_ITERATOR_RESOLVED_CALL, loopRangeExpression, iteratorResolvedCall); - context.trace.record(LOOP_RANGE_ITERATOR_CALL, loopRangeExpression, iteratorCall); - - FunctionDescriptor iteratorFunction = iteratorResolvedCall.getResultingDescriptor(); - JetType iteratorType = iteratorFunction.getReturnType(); - JetType hasNextType = checkConventionForIterator(context, loopRangeExpression, iteratorType, "hasNext", - HAS_NEXT_FUNCTION_AMBIGUITY, HAS_NEXT_MISSING, HAS_NEXT_FUNCTION_NONE_APPLICABLE, - LOOP_RANGE_HAS_NEXT_RESOLVED_CALL); - if (hasNextType != null && !isBoolean(hasNextType)) { - context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRangeExpression, hasNextType)); - } - return checkConventionForIterator(context, loopRangeExpression, iteratorType, "next", - NEXT_AMBIGUITY, NEXT_MISSING, NEXT_NONE_APPLICABLE, - LOOP_RANGE_NEXT_RESOLVED_CALL); - } - else { - if (iteratorResolutionResults.isAmbiguity()) { -// StringBuffer stringBuffer = new StringBuffer("Method 'iterator()' is ambiguous for this expression: "); -// for (FunctionDescriptor functionDescriptor : iteratorResolutionResults.getResultingCalls()) { -// stringBuffer.append(DescriptorRendererImpl.TEXT.render(functionDescriptor)).append(" "); -// } -// errorMessage = stringBuffer.toString(); - context.trace.report(ITERATOR_AMBIGUITY.on(loopRangeExpression, iteratorResolutionResults.getResultingCalls())); - } - else { - context.trace.report(ITERATOR_MISSING.on(loopRangeExpression)); - } - } - return null; - } - - @Nullable - private static JetType checkConventionForIterator( - @NotNull ExpressionTypingContext context, - @NotNull JetExpression loopRangeExpression, - @NotNull JetType iteratorType, - @NotNull String name, - @NotNull DiagnosticFactory1 ambiguity, - @NotNull DiagnosticFactory1 missing, - @NotNull DiagnosticFactory1 noneApplicable, - @NotNull WritableSlice> resolvedCallKey - ) { - OverloadResolutionResults nextResolutionResults = resolveFakeCall( - context, new TransientReceiver(iteratorType), Name.identifier(name)); - if (nextResolutionResults.isAmbiguity()) { - context.trace.report(ambiguity.on(loopRangeExpression, iteratorType)); - } - else if (nextResolutionResults.isNothing()) { - context.trace.report(missing.on(loopRangeExpression, iteratorType)); - } - else if (!nextResolutionResults.isSuccess()) { - context.trace.report(noneApplicable.on(loopRangeExpression, iteratorType)); - } - else { - assert nextResolutionResults.isSuccess(); - ResolvedCall resolvedCall = nextResolutionResults.getResultingCall(); - context.trace.record(resolvedCallKey, loopRangeExpression, resolvedCall); - return resolvedCall.getResultingDescriptor().getReturnType(); - } - return null; - } - @Override public JetTypeInfo visitTryExpression(@NotNull JetTryExpression expression, ExpressionTypingContext typingContext) { ExpressionTypingContext context = typingContext.replaceContextDependency(INDEPENDENT); @@ -469,7 +391,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { DescriptorResolver.checkParameterHasNoValOrVar(context.trace, catchParameter, VAL_OR_VAR_ON_CATCH_PARAMETER); DescriptorResolver.checkParameterHasNoModifier(context.trace, catchParameter); - VariableDescriptor variableDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveLocalVariableDescriptor( + VariableDescriptor variableDescriptor = components.expressionTypingServices.getDescriptorResolver().resolveLocalVariableDescriptor( context.scope, catchParameter, context.trace); JetType throwableType = KotlinBuiltIns.getInstance().getThrowable().getDefaultType(); DataFlowUtils.checkType(variableDescriptor.getType(), catchParameter, context.replaceExpectedType(throwableType)); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingComponents.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingComponents.java new file mode 100644 index 00000000000..ce330e47031 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingComponents.java @@ -0,0 +1,104 @@ +/* + * Copyright 2010-2014 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.lang.types.expressions; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.context.GlobalContext; +import org.jetbrains.jet.lang.PlatformToKotlinClassMap; +import org.jetbrains.jet.lang.resolve.calls.CallResolver; + +import javax.inject.Inject; + +public class ExpressionTypingComponents { + /*package*/ GlobalContext globalContext; + /*package*/ ExpressionTypingServices expressionTypingServices; + /*package*/ CallResolver callResolver; + /*package*/ PlatformToKotlinClassMap platformToKotlinClassMap; + /*package*/ ExpressionTypingUtils expressionTypingUtils; + /*package*/ ControlStructureTypingUtils controlStructureTypingUtils; + /*package*/ ForLoopConventionsChecker forLoopConventionsChecker; + + @Inject + public void setGlobalContext(@NotNull GlobalContext globalContext) { + this.globalContext = globalContext; + } + + @Inject + public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) { + this.expressionTypingServices = expressionTypingServices; + } + + @Inject + public void setCallResolver(@NotNull CallResolver callResolver) { + this.callResolver = callResolver; + } + + @Inject + public void setPlatformToKotlinClassMap(@NotNull PlatformToKotlinClassMap platformToKotlinClassMap) { + this.platformToKotlinClassMap = platformToKotlinClassMap; + } + + @Inject + public void setExpressionTypingUtils(@NotNull ExpressionTypingUtils expressionTypingUtils) { + this.expressionTypingUtils = expressionTypingUtils; + } + + @Inject + public void setControlStructureTypingUtils(@NotNull ControlStructureTypingUtils controlStructureTypingUtils) { + this.controlStructureTypingUtils = controlStructureTypingUtils; + } + + @Inject + public void setForLoopConventionsChecker(@NotNull ForLoopConventionsChecker forLoopConventionsChecker) { + this.forLoopConventionsChecker = forLoopConventionsChecker; + } + + @NotNull + public GlobalContext getGlobalContext() { + return globalContext; + } + + @NotNull + public ExpressionTypingServices getExpressionTypingServices() { + return expressionTypingServices; + } + + @NotNull + public CallResolver getCallResolver() { + return callResolver; + } + + @NotNull + public PlatformToKotlinClassMap getPlatformToKotlinClassMap() { + return platformToKotlinClassMap; + } + + @NotNull + public ExpressionTypingUtils getExpressionTypingUtils() { + return expressionTypingUtils; + } + + @NotNull + public ControlStructureTypingUtils getControlStructureTypingUtils() { + return controlStructureTypingUtils; + } + + @NotNull + public ForLoopConventionsChecker getForLoopConventionsChecker() { + return forLoopConventionsChecker; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java index 44820b66aa4..8a1b01733e3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java @@ -18,16 +18,14 @@ package org.jetbrains.jet.lang.types.expressions; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; -import org.jetbrains.jet.lang.psi.Call; -import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.calls.CallResolverExtension; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.calls.context.*; -import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.calls.context.ContextDependency; +import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext; +import org.jetbrains.jet.lang.resolve.calls.context.ResolutionResultsCache; +import org.jetbrains.jet.lang.resolve.calls.context.ResolutionResultsCacheImpl; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantChecker; -import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; @@ -41,17 +39,14 @@ public class ExpressionTypingContext extends ResolutionContext resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull Name name) { - return expressionTypingServices.getCallResolver().resolveCallWithGivenName( - BasicCallResolutionContext.create(this, call, CheckValueArgumentsMode.ENABLED), - functionReference, - name - ); - } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java index 89b2253cfde..e6432ee9744 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java @@ -28,4 +28,7 @@ import org.jetbrains.jet.lang.types.JetTypeInfo; JetTypeInfo checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context); void checkStatementType(@NotNull JetExpression expression, ExpressionTypingContext context); + + @NotNull + ExpressionTypingComponents getComponents(); } 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 79fdb80a532..87450f40221 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 @@ -21,8 +21,6 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.context.GlobalContext; -import org.jetbrains.jet.lang.PlatformToKotlinClassMap; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; @@ -57,7 +55,10 @@ import static org.jetbrains.jet.lang.types.expressions.CoercionStrategy.COERCION public class ExpressionTypingServices { @NotNull - private ExpressionTypingFacade expressionTypingFacade; + private final ExpressionTypingFacade expressionTypingFacade; + @NotNull + private final ExpressionTypingComponents expressionTypingComponents; + @NotNull private Project project; @NotNull @@ -71,11 +72,7 @@ public class ExpressionTypingServices { @NotNull private AnnotationResolver annotationResolver; @NotNull - private PlatformToKotlinClassMap platformToKotlinClassMap; - @NotNull private CallResolverExtensionProvider extensionProvider; - @NotNull - private GlobalContext globalContext; @NotNull public Project getProject() { @@ -137,23 +134,14 @@ public class ExpressionTypingServices { this.annotationResolver = annotationResolver; } - @NotNull - public PlatformToKotlinClassMap getPlatformToKotlinClassMap() { - return platformToKotlinClassMap; - } - @Inject public void setExtensionProvider(@NotNull CallResolverExtensionProvider extensionProvider) { this.extensionProvider = extensionProvider; } - public ExpressionTypingServices( - @NotNull GlobalContext globalContext, - @NotNull PlatformToKotlinClassMap platformToKotlinClassMap - ) { - this.globalContext = globalContext; - this.platformToKotlinClassMap = platformToKotlinClassMap; - this.expressionTypingFacade = ExpressionTypingVisitorDispatcher.create(globalContext, platformToKotlinClassMap); + public ExpressionTypingServices(@NotNull ExpressionTypingComponents components) { + this.expressionTypingComponents = components; + this.expressionTypingFacade = ExpressionTypingVisitorDispatcher.create(components); } @NotNull @@ -173,7 +161,7 @@ public class ExpressionTypingServices { @NotNull public JetTypeInfo getTypeInfo(@NotNull JetExpression expression, @NotNull ResolutionContext resolutionContext) { - return expressionTypingFacade.getTypeInfo(expression, ExpressionTypingContext.newContext(this, resolutionContext)); + return expressionTypingFacade.getTypeInfo(expression, ExpressionTypingContext.newContext(resolutionContext)); } @Nullable @@ -208,6 +196,11 @@ public class ExpressionTypingServices { expressionTypingFacade.getTypeInfo(bodyExpression, newContext, blockBody); } + @NotNull + public JetTypeInfo getBlockReturnedType(JetBlockExpression expression, ExpressionTypingContext context, boolean isStatement) { + return getBlockReturnedType(expression, isStatement ? CoercionStrategy.COERCION_TO_UNIT : CoercionStrategy.NO_COERCION, context); + } + @NotNull public JetTypeInfo getBlockReturnedType( @NotNull JetBlockExpression expression, @@ -282,7 +275,7 @@ public class ExpressionTypingServices { return JetTypeInfo.create(KotlinBuiltIns.getInstance().getUnitType(), context.dataFlowInfo); } - ExpressionTypingInternals blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(globalContext, platformToKotlinClassMap, scope); + ExpressionTypingInternals blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(expressionTypingComponents, scope); ExpressionTypingContext newContext = createContext(context, trace, scope, context.dataFlowInfo, NO_EXPECTED_TYPE); JetTypeInfo result = JetTypeInfo.create(null, context.dataFlowInfo); @@ -306,7 +299,7 @@ public class ExpressionTypingServices { if (newDataFlowInfo != context.dataFlowInfo) { newContext = newContext.replaceDataFlowInfo(newDataFlowInfo); } - blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(globalContext, platformToKotlinClassMap, scope); + blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(expressionTypingComponents, scope); } return result; } @@ -353,7 +346,7 @@ public class ExpressionTypingServices { } private ExpressionTypingContext createContext(ExpressionTypingContext oldContext, BindingTrace trace, WritableScope scope, DataFlowInfo dataFlowInfo, JetType expectedType) { - return ExpressionTypingContext.newContext(this, trace, scope, dataFlowInfo, expectedType, oldContext.contextDependency, + return ExpressionTypingContext.newContext(trace, scope, dataFlowInfo, expectedType, oldContext.contextDependency, oldContext.resolutionResultsCache, oldContext.labelResolver, oldContext.callResolverExtension, oldContext.isAnnotationContext); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java index fe34c12117d..57a501a1d28 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -32,7 +32,7 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.*; -import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl; @@ -61,7 +61,12 @@ import static org.jetbrains.jet.lang.types.TypeUtils.noExpectedType; public class ExpressionTypingUtils { - private ExpressionTypingUtils() { + private final ExpressionTypingServices expressionTypingServices; + private final CallResolver callResolver; + + public ExpressionTypingUtils(@NotNull ExpressionTypingServices expressionTypingServices, @NotNull CallResolver resolver) { + this.expressionTypingServices = expressionTypingServices; + callResolver = resolver; } @Nullable @@ -198,20 +203,6 @@ public class ExpressionTypingUtils { } } - public static boolean isVariableIterable(@NotNull ExpressionTypingServices expressionTypingServices, - @NotNull Project project, @NotNull VariableDescriptor variableDescriptor, @NotNull JetScope scope) { - JetExpression expression = JetPsiFactory.createExpression(project, "fake"); - ExpressionReceiver expressionReceiver = new ExpressionReceiver(expression, variableDescriptor.getType()); - ExpressionTypingContext context = ExpressionTypingContext.newContext( - expressionTypingServices, - new BindingTraceContext(), - scope, - DataFlowInfo.EMPTY, - TypeUtils.NO_EXPECTED_TYPE - ); - return ControlStructureTypingVisitor.checkIterableConvention(expressionReceiver, context) != null; - } - /** * Check that function or property with the given qualified name can be resolved in given scope and called on given receiver * @@ -318,7 +309,7 @@ public class ExpressionTypingUtils { } @NotNull - public static OverloadResolutionResults resolveFakeCall( + public OverloadResolutionResults resolveFakeCall( @NotNull ExpressionTypingContext context, @NotNull ReceiverValue receiver, @NotNull Name name, @@ -328,7 +319,7 @@ public class ExpressionTypingUtils { name); List fakeArguments = Lists.newArrayList(); for (JetType type : argumentTypes) { - fakeArguments.add(createFakeExpressionOfType(context.expressionTypingServices.getProject(), traceWithFakeArgumentInfo, + fakeArguments.add(createFakeExpressionOfType(expressionTypingServices.getProject(), traceWithFakeArgumentInfo, "fakeArgument" + fakeArguments.size(), type)); } return makeAndResolveFakeCall(receiver, context.replaceBindingTrace(traceWithFakeArgumentInfo), fakeArguments, name).getSecond(); @@ -347,7 +338,7 @@ public class ExpressionTypingUtils { } @NotNull - public static OverloadResolutionResults resolveFakeCall( + public OverloadResolutionResults resolveFakeCall( @NotNull ExpressionTypingContext context, @NotNull ReceiverValue receiver, @NotNull Name name @@ -356,7 +347,7 @@ public class ExpressionTypingUtils { } @NotNull - public static OverloadResolutionResults resolveFakeCall( + public OverloadResolutionResults resolveFakeCall( @NotNull ReceiverValue receiver, @NotNull ExpressionTypingContext context, @NotNull List valueArguments, @@ -366,17 +357,17 @@ public class ExpressionTypingUtils { } @NotNull - public static Pair> makeAndResolveFakeCall( + public Pair> makeAndResolveFakeCall( @NotNull ReceiverValue receiver, @NotNull ExpressionTypingContext context, @NotNull List valueArguments, @NotNull Name name ) { - final JetReferenceExpression fake = JetPsiFactory.createSimpleName(context.expressionTypingServices.getProject(), "fake"); + final JetReferenceExpression fake = JetPsiFactory.createSimpleName(expressionTypingServices.getProject(), "fake"); TemporaryBindingTrace fakeTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve fake call for", name); Call call = CallMaker.makeCallWithExpressions(fake, receiver, null, fake, valueArguments); OverloadResolutionResults results = - context.replaceBindingTrace(fakeTrace).resolveCallWithGivenName(call, fake, name); + callResolver.resolveCallWithGivenName(context.replaceBindingTrace(fakeTrace), call, fake, name); if (results.isSuccess()) { fakeTrace.commit(new TraceEntryFilter() { @Override @@ -389,7 +380,7 @@ public class ExpressionTypingUtils { return Pair.create(call, results); } - public static void defineLocalVariablesFromMultiDeclaration( + public void defineLocalVariablesFromMultiDeclaration( @NotNull WritableScope writableScope, @NotNull JetMultiDeclaration multiDeclaration, @NotNull ReceiverValue receiver, @@ -425,7 +416,7 @@ public class ExpressionTypingUtils { if (componentType == null) { componentType = ErrorUtils.createErrorType(componentName + "() return type"); } - VariableDescriptor variableDescriptor = context.expressionTypingServices.getDescriptorResolver(). + VariableDescriptor variableDescriptor = expressionTypingServices.getDescriptorResolver(). resolveLocalVariableDescriptorWithType(writableScope, entry, componentType, context.trace); VariableDescriptor olderVariable = writableScope.getLocalVariable(variableDescriptor.getName()); @@ -445,10 +436,10 @@ public class ExpressionTypingUtils { } @NotNull - private static JetType getExpectedTypeForComponent(ExpressionTypingContext context, JetMultiDeclarationEntry entry) { + private JetType getExpectedTypeForComponent(ExpressionTypingContext context, JetMultiDeclarationEntry entry) { JetTypeReference entryTypeRef = entry.getTypeRef(); if (entryTypeRef != null) { - return context.expressionTypingServices.getTypeResolver().resolveType(context.scope, entryTypeRef, context.trace, true); + return expressionTypingServices.getTypeResolver().resolveType(context.scope, entryTypeRef, context.trace, true); } else { return TypeUtils.NO_EXPECTED_TYPE; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java index 5b209cd0f93..25f2b8d4bfd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java @@ -23,8 +23,10 @@ import org.jetbrains.jet.lang.types.JetTypeInfo; /*package*/ abstract class ExpressionTypingVisitor extends JetVisitor { protected final ExpressionTypingInternals facade; + protected final ExpressionTypingComponents components; protected ExpressionTypingVisitor(@NotNull ExpressionTypingInternals facade) { this.facade = facade; + this.components = facade.getComponents(); } } 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 d6967339126..03e65ad66bb 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 @@ -18,8 +18,6 @@ package org.jetbrains.jet.lang.types.expressions; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.context.GlobalContext; -import org.jetbrains.jet.lang.PlatformToKotlinClassMap; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; @@ -35,36 +33,43 @@ 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 GlobalContext globalContext, @NotNull PlatformToKotlinClassMap platformToKotlinClassMap) { - return new ExpressionTypingVisitorDispatcher(globalContext, platformToKotlinClassMap, null); + public static ExpressionTypingFacade create(@NotNull ExpressionTypingComponents components) { + return new ExpressionTypingVisitorDispatcher(components, null); } @NotNull public static ExpressionTypingInternals createForBlock( - @NotNull GlobalContext globalContext, - @NotNull PlatformToKotlinClassMap platformToKotlinClassMap, + @NotNull ExpressionTypingComponents components, @NotNull WritableScope writableScope ) { - return new ExpressionTypingVisitorDispatcher(globalContext, platformToKotlinClassMap, writableScope); + return new ExpressionTypingVisitorDispatcher(components, writableScope); } - private final GlobalContext globalContext; + private final ExpressionTypingComponents components; private final BasicExpressionTypingVisitor basic; private final ExpressionTypingVisitorForStatements statements; private final ClosureExpressionsTypingVisitor closures; - private final ControlStructureTypingVisitor controlStructures = new ControlStructureTypingVisitor(this); - private final PatternMatchingTypingVisitor patterns = new PatternMatchingTypingVisitor(this); + private final ControlStructureTypingVisitor controlStructures; + private final PatternMatchingTypingVisitor patterns; - private ExpressionTypingVisitorDispatcher(GlobalContext globalContext, PlatformToKotlinClassMap platformToKotlinClassMap, WritableScope writableScope) { - this.globalContext = globalContext; - this.basic = new BasicExpressionTypingVisitor(this, platformToKotlinClassMap); + private ExpressionTypingVisitorDispatcher(@NotNull ExpressionTypingComponents components, WritableScope writableScope) { + this.components = components; + this.basic = new BasicExpressionTypingVisitor(this); + controlStructures = new ControlStructureTypingVisitor(this); + patterns = new PatternMatchingTypingVisitor(this); if (writableScope != null) { - this.statements = new ExpressionTypingVisitorForStatements(globalContext, this, writableScope, basic, controlStructures, patterns); + this.statements = new ExpressionTypingVisitorForStatements(this, writableScope, basic, controlStructures, patterns); } else { this.statements = null; } - this.closures = new ClosureExpressionsTypingVisitor(globalContext, this); + this.closures = new ClosureExpressionsTypingVisitor(this); + } + + @Override + @NotNull + public ExpressionTypingComponents getComponents() { + return components; } @NotNull @@ -100,7 +105,7 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor binaryOperationDescriptors = BasicExpressionTypingVisitor.getResolutionResultsForBinaryCall( - scope, counterpartName, context.replaceTraceAndCache(temporaryForBinaryOperation), expression, receiver); + OverloadResolutionResults binaryOperationDescriptors = components.callResolver.resolveBinaryCall( + context.replaceTraceAndCache(temporaryForBinaryOperation).replaceScope(scope), + receiver, expression, counterpartName + ); JetType binaryOperationType = OverloadResolutionResultsUtil.getResultingType(binaryOperationDescriptors, context.contextDependency); JetType type = assignmentOperationType != null ? assignmentOperationType : binaryOperationType; @@ -308,7 +309,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(scope).replaceContextDependency(INDEPENDENT); JetExpression leftOperand = expression.getLeft(); - JetExpression left = context.expressionTypingServices.deparenthesizeWithTypeResolution(leftOperand, context); + JetExpression left = components.expressionTypingServices.deparenthesizeWithTypeResolution(leftOperand, context); JetExpression right = expression.getRight(); if (left instanceof JetArrayAccessExpression) { JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left; @@ -377,7 +378,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito @Override public JetTypeInfo visitBlockExpression(@NotNull JetBlockExpression expression, ExpressionTypingContext context) { - return BasicExpressionTypingVisitor.visitBlockExpression(expression, context, true); + return components.expressionTypingServices.getBlockReturnedType(expression, context, true); } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ForLoopConventionsChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ForLoopConventionsChecker.java new file mode 100644 index 00000000000..cc9fadd4407 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ForLoopConventionsChecker.java @@ -0,0 +1,156 @@ +/* + * Copyright 2010-2014 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.lang.types.expressions; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1; +import org.jetbrains.jet.lang.psi.Call; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.psi.JetPsiFactory; +import org.jetbrains.jet.lang.resolve.BindingTraceContext; +import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeUtils; +import org.jetbrains.jet.util.slicedmap.WritableSlice; + +import javax.inject.Inject; +import java.util.Collections; + +import static org.jetbrains.jet.lang.diagnostics.Errors.*; +import static org.jetbrains.jet.lang.resolve.BindingContext.*; +import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.isBoolean; + +public class ForLoopConventionsChecker { + + private Project project; + private ExpressionTypingServices expressionTypingServices; + private ExpressionTypingUtils expressionTypingUtils; + + @Inject + public void setProject(@NotNull Project project) { + this.project = project; + } + + @Inject + public void setExpressionTypingUtils(@NotNull ExpressionTypingUtils expressionTypingUtils) { + this.expressionTypingUtils = expressionTypingUtils; + } + + @Inject + public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) { + this.expressionTypingServices = expressionTypingServices; + } + + public boolean isVariableIterable(@NotNull VariableDescriptor variableDescriptor, @NotNull JetScope scope) { + JetExpression expression = JetPsiFactory.createExpression(project, "fake"); + ExpressionReceiver expressionReceiver = new ExpressionReceiver(expression, variableDescriptor.getType()); + ExpressionTypingContext context = ExpressionTypingContext.newContext( + expressionTypingServices, + new BindingTraceContext(), + scope, + DataFlowInfo.EMPTY, + TypeUtils.NO_EXPECTED_TYPE + ); + return checkIterableConvention(expressionReceiver, context) != null; + } + + @Nullable + /*package*/ JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) { + JetExpression loopRangeExpression = loopRange.getExpression(); + + // Make a fake call loopRange.iterator(), and try to resolve it + Name iterator = Name.identifier("iterator"); + Pair> calls = + expressionTypingUtils.makeAndResolveFakeCall(loopRange, context, Collections.emptyList(), iterator); + Call iteratorCall = calls.getFirst(); + OverloadResolutionResults iteratorResolutionResults = calls.getSecond(); + + if (iteratorResolutionResults.isSuccess()) { + ResolvedCall iteratorResolvedCall = iteratorResolutionResults.getResultingCall(); + context.trace.record(LOOP_RANGE_ITERATOR_RESOLVED_CALL, loopRangeExpression, iteratorResolvedCall); + context.trace.record(LOOP_RANGE_ITERATOR_CALL, loopRangeExpression, iteratorCall); + + FunctionDescriptor iteratorFunction = iteratorResolvedCall.getResultingDescriptor(); + JetType iteratorType = iteratorFunction.getReturnType(); + JetType hasNextType = checkConventionForIterator(context, loopRangeExpression, iteratorType, "hasNext", + HAS_NEXT_FUNCTION_AMBIGUITY, HAS_NEXT_MISSING, HAS_NEXT_FUNCTION_NONE_APPLICABLE, + LOOP_RANGE_HAS_NEXT_RESOLVED_CALL); + if (hasNextType != null && !isBoolean(hasNextType)) { + context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRangeExpression, hasNextType)); + } + return checkConventionForIterator(context, loopRangeExpression, iteratorType, "next", + NEXT_AMBIGUITY, NEXT_MISSING, NEXT_NONE_APPLICABLE, + LOOP_RANGE_NEXT_RESOLVED_CALL); + } + else { + if (iteratorResolutionResults.isAmbiguity()) { +// StringBuffer stringBuffer = new StringBuffer("Method 'iterator()' is ambiguous for this expression: "); +// for (FunctionDescriptor functionDescriptor : iteratorResolutionResults.getResultingCalls()) { +// stringBuffer.append(DescriptorRendererImpl.TEXT.render(functionDescriptor)).append(" "); +// } +// errorMessage = stringBuffer.toString(); + context.trace.report(ITERATOR_AMBIGUITY.on(loopRangeExpression, iteratorResolutionResults.getResultingCalls())); + } + else { + context.trace.report(ITERATOR_MISSING.on(loopRangeExpression)); + } + } + return null; + } + + @Nullable + private JetType checkConventionForIterator( + @NotNull ExpressionTypingContext context, + @NotNull JetExpression loopRangeExpression, + @NotNull JetType iteratorType, + @NotNull String name, + @NotNull DiagnosticFactory1 ambiguity, + @NotNull DiagnosticFactory1 missing, + @NotNull DiagnosticFactory1 noneApplicable, + @NotNull WritableSlice> resolvedCallKey + ) { + OverloadResolutionResults nextResolutionResults = expressionTypingUtils.resolveFakeCall( + context, new TransientReceiver(iteratorType), Name.identifier(name)); + if (nextResolutionResults.isAmbiguity()) { + context.trace.report(ambiguity.on(loopRangeExpression, iteratorType)); + } + else if (nextResolutionResults.isNothing()) { + context.trace.report(missing.on(loopRangeExpression, iteratorType)); + } + else if (!nextResolutionResults.isSuccess()) { + context.trace.report(noneApplicable.on(loopRangeExpression, iteratorType)); + } + else { + assert nextResolutionResults.isSuccess(); + ResolvedCall resolvedCall = nextResolutionResults.getResultingCall(); + context.trace.record(resolvedCallKey, loopRangeExpression, resolvedCall); + return resolvedCall.getResultingDescriptor().getReturnType(); + } + return null; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java index ace7291be8c..afbafb204a5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java @@ -142,7 +142,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { ExpressionTypingContext newContext = contextWithExpectedType .replaceScope(scopeToExtend).replaceDataFlowInfo(newDataFlowInfo).replaceContextDependency(INDEPENDENT); CoercionStrategy coercionStrategy = isStatement ? CoercionStrategy.COERCION_TO_UNIT : CoercionStrategy.NO_COERCION; - JetTypeInfo typeInfo = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope( + JetTypeInfo typeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope( scopeToExtend, Collections.singletonList(bodyExpression), coercionStrategy, newContext, context.trace); JetType type = typeInfo.getType(); if (type != null) { @@ -278,7 +278,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { return result; } - private static DataFlowInfos checkTypeForIs( + private DataFlowInfos checkTypeForIs( ExpressionTypingContext context, JetType subjectType, JetTypeReference typeReferenceAfterIs, @@ -288,7 +288,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { return noChange(context); } TypeResolutionContext typeResolutionContext = new TypeResolutionContext(context.scope, context.trace, true, /*allowBareTypes=*/ true); - PossiblyBareType possiblyBareTarget = context.expressionTypingServices.getTypeResolver().resolvePossiblyBareType(typeResolutionContext, typeReferenceAfterIs); + PossiblyBareType possiblyBareTarget = components.expressionTypingServices.getTypeResolver().resolvePossiblyBareType(typeResolutionContext, typeReferenceAfterIs); JetType type = TypeReconstructionUtil.reconstructBareType(typeReferenceAfterIs, possiblyBareTarget, subjectType, context.trace); if (!subjectType.isNullable() && type.isNullable()) { JetTypeElement element = typeReferenceAfterIs.getTypeElement(); diff --git a/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java b/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java index bd0fc3f6f5d..2ee4da2f44d 100644 --- a/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java +++ b/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java @@ -21,6 +21,7 @@ import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.PlatformToKotlinClassMap; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; import org.jetbrains.jet.lang.resolve.TypeResolver; import org.jetbrains.jet.context.GlobalContext; import org.jetbrains.jet.storage.StorageManager; @@ -29,6 +30,9 @@ import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.resolve.calls.CandidateResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; +import org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ForLoopConventionsChecker; import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider; import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; @@ -44,6 +48,7 @@ public class InjectorForTests { private final PlatformToKotlinClassMap platformToKotlinClassMap; private final DescriptorResolver descriptorResolver; private final ExpressionTypingServices expressionTypingServices; + private final ExpressionTypingUtils expressionTypingUtils; private final TypeResolver typeResolver; private final GlobalContext globalContext; private final StorageManager storageManager; @@ -52,6 +57,9 @@ public class InjectorForTests { private final ArgumentTypeResolver argumentTypeResolver; private final CandidateResolver candidateResolver; private final DelegatedPropertyResolver delegatedPropertyResolver; + private final ExpressionTypingComponents expressionTypingComponents; + private final ControlStructureTypingUtils controlStructureTypingUtils; + private final ForLoopConventionsChecker forLoopConventionsChecker; private final CallExpressionResolver callExpressionResolver; private final CallResolverExtensionProvider callResolverExtensionProvider; private final QualifiedExpressionResolver qualifiedExpressionResolver; @@ -64,15 +72,19 @@ public class InjectorForTests { this.moduleDescriptor = moduleDescriptor; this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap(); this.descriptorResolver = new DescriptorResolver(); - this.globalContext = org.jetbrains.jet.context.ContextPackage.GlobalContext(); - this.expressionTypingServices = new ExpressionTypingServices(globalContext, platformToKotlinClassMap); + this.expressionTypingComponents = new ExpressionTypingComponents(); + this.expressionTypingServices = new ExpressionTypingServices(expressionTypingComponents); + this.callResolver = new CallResolver(); + this.expressionTypingUtils = new ExpressionTypingUtils(getExpressionTypingServices(), callResolver); this.typeResolver = new TypeResolver(); + this.globalContext = org.jetbrains.jet.context.ContextPackage.GlobalContext(); this.storageManager = globalContext.getStorageManager(); this.annotationResolver = new AnnotationResolver(); - this.callResolver = new CallResolver(); this.argumentTypeResolver = new ArgumentTypeResolver(); this.candidateResolver = new CandidateResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver(); + this.controlStructureTypingUtils = new ControlStructureTypingUtils(getExpressionTypingServices()); + this.forLoopConventionsChecker = new ForLoopConventionsChecker(); this.callExpressionResolver = new CallExpressionResolver(); this.callResolverExtensionProvider = new CallResolverExtensionProvider(); this.qualifiedExpressionResolver = new QualifiedExpressionResolver(); @@ -108,8 +120,21 @@ public class InjectorForTests { candidateResolver.setArgumentTypeResolver(argumentTypeResolver); + delegatedPropertyResolver.setCallResolver(callResolver); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); + expressionTypingComponents.setCallResolver(callResolver); + expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils); + expressionTypingComponents.setExpressionTypingServices(expressionTypingServices); + expressionTypingComponents.setExpressionTypingUtils(expressionTypingUtils); + expressionTypingComponents.setForLoopConventionsChecker(forLoopConventionsChecker); + expressionTypingComponents.setGlobalContext(globalContext); + expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap); + + forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices); + forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils); + forLoopConventionsChecker.setProject(project); + callExpressionResolver.setExpressionTypingServices(expressionTypingServices); } @@ -126,6 +151,10 @@ public class InjectorForTests { return this.expressionTypingServices; } + public ExpressionTypingUtils getExpressionTypingUtils() { + return this.expressionTypingUtils; + } + public TypeResolver getTypeResolver() { return this.typeResolver; } diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetExpectedResolveDataUtil.java b/compiler/tests/org/jetbrains/jet/resolve/JetExpectedResolveDataUtil.java index fa48218abd6..1deea903b26 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetExpectedResolveDataUtil.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetExpectedResolveDataUtil.java @@ -46,7 +46,6 @@ import java.util.List; import java.util.Map; import static com.intellij.testFramework.UsefulTestCase.assertInstanceOf; -import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.resolveFakeCall; public class JetExpectedResolveDataUtil { private JetExpectedResolveDataUtil() { @@ -131,13 +130,14 @@ public class JetExpectedResolveDataUtil { JetType... parameterTypes ) { ModuleDescriptor emptyModule = JetTestUtils.createEmptyModule(); - ExpressionTypingServices expressionTypingServices = new InjectorForTests(project, emptyModule).getExpressionTypingServices(); + InjectorForTests injector = new InjectorForTests(project, emptyModule); + ExpressionTypingServices expressionTypingServices = injector.getExpressionTypingServices(); ExpressionTypingContext context = ExpressionTypingContext.newContext( expressionTypingServices, new BindingTraceContext(), classDescriptor.getDefaultType().getMemberScope(), DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE); - OverloadResolutionResults functions = resolveFakeCall( + OverloadResolutionResults functions = injector.getExpressionTypingUtils().resolveFakeCall( context, ReceiverValue.NO_RECEIVER, Name.identifier(name), parameterTypes); for (ResolvedCall resolvedCall : functions.getResultingCalls()) { diff --git a/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.kt b/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.kt index 8f95a18c2cd..154f37e76bf 100644 --- a/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.kt +++ b/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.kt @@ -19,13 +19,11 @@ package org.jetbrains.jet.generators.injectors import com.intellij.openapi.project.Project import org.jetbrains.jet.context.GlobalContext import org.jetbrains.jet.context.GlobalContextImpl -import org.jetbrains.jet.lang.PlatformToKotlinClassMap import org.jetbrains.jet.lang.descriptors.ModuleDescriptor import org.jetbrains.jet.lang.descriptors.ModuleDescriptorImpl import org.jetbrains.jet.lang.resolve.* import org.jetbrains.jet.lang.resolve.java.JavaClassFinderImpl import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver -import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap import org.jetbrains.jet.lang.resolve.java.resolver.* import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder import org.jetbrains.jet.lang.resolve.lazy.ResolveSession @@ -33,7 +31,8 @@ import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFacto import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolverDummyImpl import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices import org.jetbrains.jet.di.* -import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils // NOTE: After making changes, you need to re-generate the injectors. // To do that, you can run main in this file. @@ -168,6 +167,7 @@ private fun generatorForMacro() = parameter(javaClass(), useAsContext = true) publicField(javaClass()) + publicField(javaClass()) field(javaClass(), useAsContext = true, init = GivenExpression("org.jetbrains.jet.context.ContextPackage.GlobalContext()")) @@ -181,6 +181,7 @@ private fun generatorForTests() = publicFields( javaClass(), javaClass(), + javaClass(), javaClass() ) diff --git a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/BaseJetVariableMacro.java b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/BaseJetVariableMacro.java index 039f6aac769..898bac6bab3 100644 --- a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/BaseJetVariableMacro.java +++ b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/BaseJetVariableMacro.java @@ -36,7 +36,7 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; import org.jetbrains.jet.plugin.codeInsight.TipsManager; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.plugin.project.ResolveSessionForBodies; @@ -68,14 +68,14 @@ public abstract class BaseJetVariableMacro extends Macro { return null; } - ExpressionTypingServices callResolverContext = - new InjectorForMacros(project, resolveSession.getModuleDescriptor()).getExpressionTypingServices(); + ExpressionTypingComponents components = + new InjectorForMacros(project, resolveSession.getModuleDescriptor()).getExpressionTypingComponents(); List filteredDescriptors = new ArrayList(); for (DeclarationDescriptor declarationDescriptor : scope.getAllDescriptors()) { if (declarationDescriptor instanceof VariableDescriptor) { VariableDescriptor variableDescriptor = (VariableDescriptor) declarationDescriptor; - if (isSuitable(variableDescriptor, scope, project, callResolverContext)) { + if (isSuitable(variableDescriptor, scope, project, components)) { filteredDescriptors.add(variableDescriptor); } } @@ -94,7 +94,12 @@ public abstract class BaseJetVariableMacro extends Macro { return declarations.toArray(new JetNamedDeclaration[declarations.size()]); } - protected abstract boolean isSuitable(@NotNull VariableDescriptor variableDescriptor, @NotNull JetScope scope, @NotNull Project project, ExpressionTypingServices callResolverContext); + protected abstract boolean isSuitable( + @NotNull VariableDescriptor variableDescriptor, + @NotNull JetScope scope, + @NotNull Project project, + @NotNull ExpressionTypingComponents components + ); @Nullable private static JetExpression findContextExpression(PsiFile psiFile, int startOffset) { diff --git a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetAnyVariableMacro.java b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetAnyVariableMacro.java index 687ec256aea..6b436618abd 100644 --- a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetAnyVariableMacro.java +++ b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetAnyVariableMacro.java @@ -20,7 +20,7 @@ import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; import org.jetbrains.jet.plugin.JetBundle; public class JetAnyVariableMacro extends BaseJetVariableMacro { @@ -35,7 +35,7 @@ public class JetAnyVariableMacro extends BaseJetVariableMacro { } @Override - protected boolean isSuitable(@NotNull VariableDescriptor variableDescriptor, @NotNull JetScope scope, @NotNull Project project, ExpressionTypingServices callResolverContext) { + protected boolean isSuitable(@NotNull VariableDescriptor variableDescriptor, @NotNull JetScope scope, @NotNull Project project, @NotNull ExpressionTypingComponents components) { return true; } } diff --git a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetIterableVariableMacro.java b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetIterableVariableMacro.java index 5ab0cce9c0b..cb3a607c9ee 100644 --- a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetIterableVariableMacro.java +++ b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetIterableVariableMacro.java @@ -20,8 +20,7 @@ import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; -import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; import org.jetbrains.jet.plugin.JetBundle; public class JetIterableVariableMacro extends BaseJetVariableMacro { @@ -37,7 +36,12 @@ public class JetIterableVariableMacro extends BaseJetVariableMacro { } @Override - protected boolean isSuitable(@NotNull VariableDescriptor variableDescriptor, @NotNull JetScope scope, @NotNull Project project, ExpressionTypingServices callResolverContext) { - return ExpressionTypingUtils.isVariableIterable(callResolverContext, project, variableDescriptor, scope); + protected boolean isSuitable( + @NotNull VariableDescriptor variableDescriptor, + @NotNull JetScope scope, + @NotNull Project project, + @NotNull ExpressionTypingComponents components + ) { + return components.getForLoopConventionsChecker().isVariableIterable(variableDescriptor, scope); } } diff --git a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetSuggestVariableNameMacro.java b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetSuggestVariableNameMacro.java index 92a47c72d82..4b4c35ec32c 100644 --- a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetSuggestVariableNameMacro.java +++ b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetSuggestVariableNameMacro.java @@ -20,7 +20,7 @@ import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; import org.jetbrains.jet.plugin.JetBundle; public class JetSuggestVariableNameMacro extends BaseJetVariableMacro { @@ -39,7 +39,7 @@ public class JetSuggestVariableNameMacro extends BaseJetVariableMacro { @NotNull VariableDescriptor variableDescriptor, @NotNull JetScope scope, @NotNull Project project, - ExpressionTypingServices callResolverContext + @NotNull ExpressionTypingComponents components ) { return variableDescriptor.getType().isNullable(); } diff --git a/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java b/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java index d2841848125..1d98bd7bd2e 100644 --- a/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java +++ b/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java @@ -31,6 +31,10 @@ import org.jetbrains.jet.lang.resolve.AnnotationResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents; +import org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; +import org.jetbrains.jet.lang.types.expressions.ForLoopConventionsChecker; import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; @@ -71,6 +75,10 @@ public class InjectorForTopDownAnalyzerForJs { private final CallResolver callResolver; private final ArgumentTypeResolver argumentTypeResolver; private final ExpressionTypingServices expressionTypingServices; + private final ExpressionTypingComponents expressionTypingComponents; + private final ControlStructureTypingUtils controlStructureTypingUtils; + private final ExpressionTypingUtils expressionTypingUtils; + private final ForLoopConventionsChecker forLoopConventionsChecker; private final CallExpressionResolver callExpressionResolver; private final DescriptorResolver descriptorResolver; private final DelegatedPropertyResolver delegatedPropertyResolver; @@ -110,7 +118,11 @@ public class InjectorForTopDownAnalyzerForJs { this.annotationResolver = new AnnotationResolver(); this.callResolver = new CallResolver(); this.argumentTypeResolver = new ArgumentTypeResolver(); - this.expressionTypingServices = new ExpressionTypingServices(getTopDownAnalysisContext(), platformToKotlinClassMap); + this.expressionTypingComponents = new ExpressionTypingComponents(); + this.expressionTypingServices = new ExpressionTypingServices(expressionTypingComponents); + this.controlStructureTypingUtils = new ControlStructureTypingUtils(expressionTypingServices); + this.expressionTypingUtils = new ExpressionTypingUtils(expressionTypingServices, callResolver); + this.forLoopConventionsChecker = new ForLoopConventionsChecker(); this.callExpressionResolver = new CallExpressionResolver(); this.descriptorResolver = new DescriptorResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver(); @@ -174,6 +186,18 @@ public class InjectorForTopDownAnalyzerForJs { expressionTypingServices.setProject(project); expressionTypingServices.setTypeResolver(typeResolver); + expressionTypingComponents.setCallResolver(callResolver); + expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils); + expressionTypingComponents.setExpressionTypingServices(expressionTypingServices); + expressionTypingComponents.setExpressionTypingUtils(expressionTypingUtils); + expressionTypingComponents.setForLoopConventionsChecker(forLoopConventionsChecker); + expressionTypingComponents.setGlobalContext(topDownAnalysisContext); + expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap); + + forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices); + forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils); + forLoopConventionsChecker.setProject(project); + callExpressionResolver.setExpressionTypingServices(expressionTypingServices); descriptorResolver.setAnnotationResolver(annotationResolver); @@ -182,6 +206,7 @@ public class InjectorForTopDownAnalyzerForJs { descriptorResolver.setStorageManager(storageManager); descriptorResolver.setTypeResolver(typeResolver); + delegatedPropertyResolver.setCallResolver(callResolver); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); typeResolver.setAnnotationResolver(annotationResolver);