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);