Usages of expressionTypingServices from ExpressionTypingContext are replaced with injection

The basic principle behind this change is that no context object should store components.
Components should be injected instead, and contexts only carry parameters around.

Particular changes:
- resolveCallWithGivenName() and resolveBinaryCall() moved to CallResolver
- ForLoopConventionsChecker introduced to confine checking conventions for Iterator and Iterable
- ExpressionTypingComponents introduced to deliver necessary components to ExpressionTypingVisitor's
- Some static methods became non-static to get access to injected components
- ExpressionTypingUtils and ControlStructureTypingUtils became components (got state injected) to avoid passing parameters around
This commit is contained in:
Andrey Breslav
2014-02-21 20:53:45 +04:00
parent 7b89af320c
commit 5b67cf67eb
30 changed files with 713 additions and 320 deletions
@@ -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.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; 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.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
@@ -76,6 +80,10 @@ public class InjectorForLazyResolveWithJava {
private final CallResolver callResolver; private final CallResolver callResolver;
private final ArgumentTypeResolver argumentTypeResolver; private final ArgumentTypeResolver argumentTypeResolver;
private final ExpressionTypingServices expressionTypingServices; 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 CallExpressionResolver callExpressionResolver;
private final DescriptorResolver descriptorResolver; private final DescriptorResolver descriptorResolver;
private final DelegatedPropertyResolver delegatedPropertyResolver; private final DelegatedPropertyResolver delegatedPropertyResolver;
@@ -118,7 +126,11 @@ public class InjectorForLazyResolveWithJava {
this.annotationResolver = new AnnotationResolver(); this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver(); this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver(); 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.callExpressionResolver = new CallExpressionResolver();
this.descriptorResolver = new DescriptorResolver(); this.descriptorResolver = new DescriptorResolver();
this.delegatedPropertyResolver = new DelegatedPropertyResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver();
@@ -168,6 +180,18 @@ public class InjectorForLazyResolveWithJava {
expressionTypingServices.setProject(project); expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver); 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); callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setAnnotationResolver(annotationResolver); descriptorResolver.setAnnotationResolver(annotationResolver);
@@ -176,6 +200,7 @@ public class InjectorForLazyResolveWithJava {
descriptorResolver.setStorageManager(lockBasedStorageManager); descriptorResolver.setStorageManager(lockBasedStorageManager);
descriptorResolver.setTypeResolver(typeResolver); descriptorResolver.setTypeResolver(typeResolver);
delegatedPropertyResolver.setCallResolver(callResolver);
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver); typeResolver.setAnnotationResolver(annotationResolver);
@@ -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.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; 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.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
@@ -89,6 +93,10 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
private final CallResolver callResolver; private final CallResolver callResolver;
private final ArgumentTypeResolver argumentTypeResolver; private final ArgumentTypeResolver argumentTypeResolver;
private final ExpressionTypingServices expressionTypingServices; 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 CallExpressionResolver callExpressionResolver;
private final DescriptorResolver descriptorResolver; private final DescriptorResolver descriptorResolver;
private final DelegatedPropertyResolver delegatedPropertyResolver; private final DelegatedPropertyResolver delegatedPropertyResolver;
@@ -142,7 +150,11 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.annotationResolver = new AnnotationResolver(); this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver(); this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver(); 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.callExpressionResolver = new CallExpressionResolver();
this.descriptorResolver = new DescriptorResolver(); this.descriptorResolver = new DescriptorResolver();
this.delegatedPropertyResolver = new DelegatedPropertyResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver();
@@ -219,6 +231,18 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
expressionTypingServices.setProject(project); expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver); 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); callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setAnnotationResolver(annotationResolver); descriptorResolver.setAnnotationResolver(annotationResolver);
@@ -227,6 +251,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
descriptorResolver.setStorageManager(storageManager); descriptorResolver.setStorageManager(storageManager);
descriptorResolver.setTypeResolver(typeResolver); descriptorResolver.setTypeResolver(typeResolver);
delegatedPropertyResolver.setCallResolver(callResolver);
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver); typeResolver.setAnnotationResolver(annotationResolver);
@@ -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.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; 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.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
@@ -59,6 +63,10 @@ public class InjectorForBodyResolve {
private final CallResolver callResolver; private final CallResolver callResolver;
private final ArgumentTypeResolver argumentTypeResolver; private final ArgumentTypeResolver argumentTypeResolver;
private final ExpressionTypingServices expressionTypingServices; 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 CallExpressionResolver callExpressionResolver;
private final DescriptorResolver descriptorResolver; private final DescriptorResolver descriptorResolver;
private final DelegatedPropertyResolver delegatedPropertyResolver; private final DelegatedPropertyResolver delegatedPropertyResolver;
@@ -90,7 +98,11 @@ public class InjectorForBodyResolve {
this.annotationResolver = new AnnotationResolver(); this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver(); this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver(); 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.callExpressionResolver = new CallExpressionResolver();
this.descriptorResolver = new DescriptorResolver(); this.descriptorResolver = new DescriptorResolver();
this.delegatedPropertyResolver = new DelegatedPropertyResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver();
@@ -135,6 +147,18 @@ public class InjectorForBodyResolve {
expressionTypingServices.setProject(project); expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver); 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); callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setAnnotationResolver(annotationResolver); descriptorResolver.setAnnotationResolver(annotationResolver);
@@ -143,6 +167,7 @@ public class InjectorForBodyResolve {
descriptorResolver.setStorageManager(storageManager); descriptorResolver.setStorageManager(storageManager);
descriptorResolver.setTypeResolver(typeResolver); descriptorResolver.setTypeResolver(typeResolver);
delegatedPropertyResolver.setCallResolver(callResolver);
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver); typeResolver.setAnnotationResolver(annotationResolver);
@@ -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.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; 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.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
@@ -56,6 +60,10 @@ public class InjectorForLazyResolve {
private final CallResolver callResolver; private final CallResolver callResolver;
private final ArgumentTypeResolver argumentTypeResolver; private final ArgumentTypeResolver argumentTypeResolver;
private final ExpressionTypingServices expressionTypingServices; 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 CallExpressionResolver callExpressionResolver;
private final DescriptorResolver descriptorResolver; private final DescriptorResolver descriptorResolver;
private final DelegatedPropertyResolver delegatedPropertyResolver; private final DelegatedPropertyResolver delegatedPropertyResolver;
@@ -84,7 +92,11 @@ public class InjectorForLazyResolve {
this.annotationResolver = new AnnotationResolver(); this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver(); this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver(); 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.callExpressionResolver = new CallExpressionResolver();
this.descriptorResolver = new DescriptorResolver(); this.descriptorResolver = new DescriptorResolver();
this.delegatedPropertyResolver = new DelegatedPropertyResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver();
@@ -121,6 +133,18 @@ public class InjectorForLazyResolve {
expressionTypingServices.setProject(project); expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver); 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); callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setAnnotationResolver(annotationResolver); descriptorResolver.setAnnotationResolver(annotationResolver);
@@ -129,6 +153,7 @@ public class InjectorForLazyResolve {
descriptorResolver.setStorageManager(lockBasedStorageManager); descriptorResolver.setStorageManager(lockBasedStorageManager);
descriptorResolver.setTypeResolver(typeResolver); descriptorResolver.setTypeResolver(typeResolver);
delegatedPropertyResolver.setCallResolver(callResolver);
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver); typeResolver.setAnnotationResolver(annotationResolver);
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap; import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; 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.context.GlobalContext;
import org.jetbrains.jet.storage.StorageManager; import org.jetbrains.jet.storage.StorageManager;
import org.jetbrains.jet.lang.resolve.AnnotationResolver; 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.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider; 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 org.jetbrains.annotations.NotNull;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
@@ -43,6 +47,7 @@ public class InjectorForMacros {
private final ModuleDescriptor moduleDescriptor; private final ModuleDescriptor moduleDescriptor;
private final PlatformToKotlinClassMap platformToKotlinClassMap; private final PlatformToKotlinClassMap platformToKotlinClassMap;
private final ExpressionTypingServices expressionTypingServices; private final ExpressionTypingServices expressionTypingServices;
private final ExpressionTypingComponents expressionTypingComponents;
private final GlobalContext globalContext; private final GlobalContext globalContext;
private final StorageManager storageManager; private final StorageManager storageManager;
private final AnnotationResolver annotationResolver; private final AnnotationResolver annotationResolver;
@@ -55,6 +60,9 @@ public class InjectorForMacros {
private final DescriptorResolver descriptorResolver; private final DescriptorResolver descriptorResolver;
private final DelegatedPropertyResolver delegatedPropertyResolver; private final DelegatedPropertyResolver delegatedPropertyResolver;
private final CallResolverExtensionProvider callResolverExtensionProvider; private final CallResolverExtensionProvider callResolverExtensionProvider;
private final ControlStructureTypingUtils controlStructureTypingUtils;
private final ExpressionTypingUtils expressionTypingUtils;
private final ForLoopConventionsChecker forLoopConventionsChecker;
public InjectorForMacros( public InjectorForMacros(
@NotNull Project project, @NotNull Project project,
@@ -63,8 +71,9 @@ public class InjectorForMacros {
this.project = project; this.project = project;
this.moduleDescriptor = moduleDescriptor; this.moduleDescriptor = moduleDescriptor;
this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap(); this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap();
this.expressionTypingComponents = new ExpressionTypingComponents();
this.expressionTypingServices = new ExpressionTypingServices(getExpressionTypingComponents());
this.globalContext = org.jetbrains.jet.context.ContextPackage.GlobalContext(); this.globalContext = org.jetbrains.jet.context.ContextPackage.GlobalContext();
this.expressionTypingServices = new ExpressionTypingServices(globalContext, platformToKotlinClassMap);
this.storageManager = globalContext.getStorageManager(); this.storageManager = globalContext.getStorageManager();
this.annotationResolver = new AnnotationResolver(); this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver(); this.callResolver = new CallResolver();
@@ -76,6 +85,9 @@ public class InjectorForMacros {
this.descriptorResolver = new DescriptorResolver(); this.descriptorResolver = new DescriptorResolver();
this.delegatedPropertyResolver = new DelegatedPropertyResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver();
this.callResolverExtensionProvider = new CallResolverExtensionProvider(); 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.setAnnotationResolver(annotationResolver);
this.expressionTypingServices.setCallExpressionResolver(callExpressionResolver); this.expressionTypingServices.setCallExpressionResolver(callExpressionResolver);
@@ -85,6 +97,14 @@ public class InjectorForMacros {
this.expressionTypingServices.setProject(project); this.expressionTypingServices.setProject(project);
this.expressionTypingServices.setTypeResolver(typeResolver); 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.setCallResolver(callResolver);
annotationResolver.setExpressionTypingServices(expressionTypingServices); annotationResolver.setExpressionTypingServices(expressionTypingServices);
@@ -110,8 +130,13 @@ public class InjectorForMacros {
descriptorResolver.setStorageManager(storageManager); descriptorResolver.setStorageManager(storageManager);
descriptorResolver.setTypeResolver(typeResolver); descriptorResolver.setTypeResolver(typeResolver);
delegatedPropertyResolver.setCallResolver(callResolver);
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices);
forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils);
forLoopConventionsChecker.setProject(project);
} }
@PreDestroy @PreDestroy
@@ -122,4 +147,8 @@ public class InjectorForMacros {
return this.expressionTypingServices; return this.expressionTypingServices;
} }
public ExpressionTypingComponents getExpressionTypingComponents() {
return this.expressionTypingComponents;
}
} }
@@ -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.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; 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.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
@@ -71,6 +75,10 @@ public class InjectorForTopDownAnalyzerBasic {
private final CallResolver callResolver; private final CallResolver callResolver;
private final ArgumentTypeResolver argumentTypeResolver; private final ArgumentTypeResolver argumentTypeResolver;
private final ExpressionTypingServices expressionTypingServices; 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 CallExpressionResolver callExpressionResolver;
private final DescriptorResolver descriptorResolver; private final DescriptorResolver descriptorResolver;
private final DelegatedPropertyResolver delegatedPropertyResolver; private final DelegatedPropertyResolver delegatedPropertyResolver;
@@ -110,7 +118,11 @@ public class InjectorForTopDownAnalyzerBasic {
this.annotationResolver = new AnnotationResolver(); this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver(); this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver(); 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.callExpressionResolver = new CallExpressionResolver();
this.descriptorResolver = new DescriptorResolver(); this.descriptorResolver = new DescriptorResolver();
this.delegatedPropertyResolver = new DelegatedPropertyResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver();
@@ -174,6 +186,18 @@ public class InjectorForTopDownAnalyzerBasic {
expressionTypingServices.setProject(project); expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver); 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); callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setAnnotationResolver(annotationResolver); descriptorResolver.setAnnotationResolver(annotationResolver);
@@ -182,6 +206,7 @@ public class InjectorForTopDownAnalyzerBasic {
descriptorResolver.setStorageManager(storageManager); descriptorResolver.setStorageManager(storageManager);
descriptorResolver.setTypeResolver(typeResolver); descriptorResolver.setTypeResolver(typeResolver);
delegatedPropertyResolver.setCallResolver(callResolver);
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver); typeResolver.setAnnotationResolver(annotationResolver);
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.rendering.Renderers; import org.jetbrains.jet.lang.diagnostics.rendering.Renderers;
import org.jetbrains.jet.lang.psi.*; 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.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition; 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.ConstraintSystem;
@@ -58,11 +59,19 @@ public class DelegatedPropertyResolver {
@NotNull @NotNull
private ExpressionTypingServices expressionTypingServices; private ExpressionTypingServices expressionTypingServices;
@NotNull
private CallResolver callResolver;
@Inject @Inject
public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) { public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) {
this.expressionTypingServices = expressionTypingServices; this.expressionTypingServices = expressionTypingServices;
} }
@Inject
public void setCallResolver(@NotNull CallResolver callResolver) {
this.callResolver = callResolver;
}
@Nullable @Nullable
public JetType getDelegatedPropertyGetMethodReturnType( public JetType getDelegatedPropertyGetMethodReturnType(
@NotNull PropertyDescriptor propertyDescriptor, @NotNull PropertyDescriptor propertyDescriptor,
@@ -164,7 +173,7 @@ public class DelegatedPropertyResolver {
ExpressionTypingContext context = ExpressionTypingContext.newContext( ExpressionTypingContext context = ExpressionTypingContext.newContext(
expressionTypingServices, trace, scope, expressionTypingServices, trace, scope,
DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE); DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE);
Project project = context.expressionTypingServices.getProject(); Project project = expressionTypingServices.getProject();
boolean hasThis = propertyDescriptor.getReceiverParameter() != null || propertyDescriptor.getExpectedThisObject() != null; 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() + "\")")); arguments.add(createExpression(project, KotlinBuiltIns.getInstance().getPropertyMetadataImpl().getName().asString() + "(\"" + propertyDescriptor.getName().asString() + "\")"));
if (!isGet) { if (!isGet) {
JetReferenceExpression fakeArgument = (JetReferenceExpression) createFakeExpressionOfType(context.expressionTypingServices.getProject(), trace, JetReferenceExpression fakeArgument = (JetReferenceExpression) createFakeExpressionOfType(expressionTypingServices.getProject(), trace,
"fakeArgument" + arguments.size(), "fakeArgument" + arguments.size(),
propertyDescriptor.getType()); propertyDescriptor.getType());
arguments.add(fakeArgument); arguments.add(fakeArgument);
@@ -189,7 +198,7 @@ public class DelegatedPropertyResolver {
Call call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT); Call call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT);
trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, call); 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) { private String renderCall(@NotNull Call call, @NotNull BindingContext context) {
@@ -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.ResolutionDebugInfo;
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionResultsHandler; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionResultsHandler;
import org.jetbrains.jet.lang.resolve.calls.tasks.*; 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.DelegatingCall;
import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor;
import org.jetbrains.jet.lang.resolve.calls.util.JetFakeReference; import org.jetbrains.jet.lang.resolve.calls.util.JetFakeReference;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; 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.JetType;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingContext;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.lang.types.expressions.LabelResolver; 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.RESOLVE_FUNCTION_ARGUMENTS;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.SHAPE_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.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; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
@SuppressWarnings("RedundantTypeArguments") @SuppressWarnings("RedundantTypeArguments")
@@ -116,6 +117,20 @@ public class CallResolver {
context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, nameExpression); context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, nameExpression);
} }
@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(
@NotNull ExpressionTypingContext context,
@NotNull Call call,
@NotNull JetReferenceExpression functionReference,
@NotNull Name name
) {
return resolveCallWithGivenName(
BasicCallResolutionContext.create(context, call, CheckValueArgumentsMode.ENABLED),
functionReference,
name
);
}
@NotNull @NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName( public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@@ -140,6 +155,21 @@ public class CallResolver {
context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference); context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference);
} }
@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveBinaryCall(
ExpressionTypingContext context,
ExpressionReceiver receiver,
JetBinaryExpression binaryExpression,
Name name
) {
return resolveCallWithGivenName(
context,
CallMaker.makeCall(receiver, binaryExpression),
binaryExpression.getOperationReference(),
name
);
}
@NotNull @NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall( public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@@ -22,7 +22,6 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet; import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor; 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.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
import static org.jetbrains.jet.lang.types.TypeUtils.*; 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.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.ExpressionTypingUtils.*;
import static org.jetbrains.jet.lang.types.expressions.TypeReconstructionUtil.reconstructBareType; import static org.jetbrains.jet.lang.types.expressions.TypeReconstructionUtil.reconstructBareType;
import static org.jetbrains.jet.lexer.JetTokens.AS_KEYWORD; 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 static final TokenSet BARE_TYPES_ALLOWED = TokenSet.create(AS_KEYWORD, AS_SAFE);
private final PlatformToKotlinClassMap platformToKotlinClassMap; protected BasicExpressionTypingVisitor(@NotNull ExpressionTypingInternals facade) {
protected BasicExpressionTypingVisitor(@NotNull ExpressionTypingInternals facade, @NotNull PlatformToKotlinClassMap platformToKotlinClassMap) {
super(facade); super(facade);
this.platformToKotlinClassMap = platformToKotlinClassMap;
} }
@Override @Override
public JetTypeInfo visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression, ExpressionTypingContext context) { public JetTypeInfo visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression, ExpressionTypingContext context) {
// TODO : other members // TODO : other members
// TODO : type substitutions??? // TODO : type substitutions???
CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver(); CallExpressionResolver callExpressionResolver = components.expressionTypingServices.getCallExpressionResolver();
JetTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, NO_RECEIVER, null, context); JetTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, NO_RECEIVER, null, context);
JetType type = DataFlowUtils.checkType(typeInfo.getType(), expression, context); JetType type = DataFlowUtils.checkType(typeInfo.getType(), expression, context);
ExpressionTypingUtils.checkCapturingInClosure(expression, context.trace, context.scope); ExpressionTypingUtils.checkCapturingInClosure(expression, context.trace, context.scope);
@@ -151,7 +146,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
boolean allowBareTypes = BARE_TYPES_ALLOWED.contains(operationType); boolean allowBareTypes = BARE_TYPES_ALLOWED.contains(operationType);
TypeResolutionContext typeResolutionContext = new TypeResolutionContext(context.scope, context.trace, true, allowBareTypes); 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) { if (operationType == JetTokens.COLON) {
// We do not allow bare types on static assertions, because static assertions provide an expected type for their argument, // 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 (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())); context.trace.report(CAST_NEVER_SUCCEEDS.on(expression.getOperationReference()));
} }
else { else {
@@ -278,15 +273,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
throw new IllegalStateException("Unknown code: " + resolutionResult.getCode()); 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(); JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier();
if (superTypeQualifier != null) { 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); return JetTypeInfo.create(null, context.dataFlowInfo);
} }
private static JetType checkPossiblyQualifiedSuper( private JetType checkPossiblyQualifiedSuper(
JetSuperExpression expression, JetSuperExpression expression,
ExpressionTypingContext context, ExpressionTypingContext context,
ReceiverParameterDescriptor thisReceiver ReceiverParameterDescriptor thisReceiver
@@ -307,15 +302,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetUserType userType = (JetUserType) typeElement; JetUserType userType = (JetUserType) typeElement;
// This may be just a superclass name even if the superclass is generic // This may be just a superclass name even if the superclass is generic
if (userType.getTypeArguments().isEmpty()) { 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 { 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(); redundantTypeArguments = userType.getTypeArgumentList();
} }
} }
else { 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) { if (supertype != null) {
@@ -444,12 +439,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Override @Override
public JetTypeInfo visitBlockExpression(@NotNull JetBlockExpression expression, ExpressionTypingContext context) { public JetTypeInfo visitBlockExpression(@NotNull JetBlockExpression expression, ExpressionTypingContext context) {
return visitBlockExpression(expression, context, false); return components.expressionTypingServices.getBlockReturnedType(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);
} }
@Override @Override
@@ -459,7 +449,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetType receiverType = JetType receiverType =
typeReference == null typeReference == null
? 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(); JetSimpleNameExpression callableReference = expression.getCallableReference();
if (callableReference.getReferencedName().isEmpty()) { if (callableReference.getReferencedName().isEmpty()) {
@@ -473,7 +463,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
@Nullable @Nullable
private static JetType getCallableReferenceType( private JetType getCallableReferenceType(
@NotNull JetCallableReferenceExpression expression, @NotNull JetCallableReferenceExpression expression,
@Nullable JetType lhsType, @Nullable JetType lhsType,
@NotNull ExpressionTypingContext context @NotNull ExpressionTypingContext context
@@ -525,7 +515,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
@Nullable @Nullable
private static FunctionDescriptor resolveCallableReferenceTarget( private FunctionDescriptor resolveCallableReferenceTarget(
@Nullable JetType lhsType, @Nullable JetType lhsType,
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull JetCallableReferenceExpression expression, @NotNull JetCallableReferenceExpression expression,
@@ -567,7 +557,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
@Nullable @Nullable
private static FunctionDescriptor resolveCallableNotCheckingArguments( private FunctionDescriptor resolveCallableNotCheckingArguments(
@NotNull JetSimpleNameExpression reference, @NotNull JetSimpleNameExpression reference,
@NotNull ReceiverValue receiver, @NotNull ReceiverValue receiver,
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@@ -578,7 +568,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
TemporaryBindingTrace trace = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", reference); TemporaryBindingTrace trace = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", reference);
ExpressionTypingContext contextForResolve = context.replaceBindingTrace(trace).replaceExpectedType(NO_EXPECTED_TYPE); ExpressionTypingContext contextForResolve = context.replaceBindingTrace(trace).replaceExpectedType(NO_EXPECTED_TYPE);
ResolvedCallWithTrace<FunctionDescriptor> function = contextForResolve.expressionTypingServices.getCallExpressionResolver() ResolvedCallWithTrace<FunctionDescriptor> function = components.expressionTypingServices.getCallExpressionResolver()
.getResolvedCallForFunction(call, reference, contextForResolve, CheckValueArgumentsMode.DISABLED, result); .getResolvedCallForFunction(call, reference, contextForResolve, CheckValueArgumentsMode.DISABLED, result);
if (!result[0]) return null; if (!result[0]) return null;
@@ -595,13 +585,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Override @Override
public JetTypeInfo visitQualifiedExpression(@NotNull JetQualifiedExpression expression, ExpressionTypingContext context) { public JetTypeInfo visitQualifiedExpression(@NotNull JetQualifiedExpression expression, ExpressionTypingContext context) {
CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver(); CallExpressionResolver callExpressionResolver = components.expressionTypingServices.getCallExpressionResolver();
return callExpressionResolver.getQualifiedExpressionTypeInfo(expression, context); return callExpressionResolver.getQualifiedExpressionTypeInfo(expression, context);
} }
@Override @Override
public JetTypeInfo visitCallExpression(@NotNull JetCallExpression expression, ExpressionTypingContext context) { 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); return callExpressionResolver.getCallExpressionTypeInfo(expression, NO_RECEIVER, null, context);
} }
@@ -659,7 +649,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ExpressionReceiver receiver = new ExpressionReceiver(baseExpression, type); ExpressionReceiver receiver = new ExpressionReceiver(baseExpression, type);
// Resolve the operation reference // Resolve the operation reference
OverloadResolutionResults<FunctionDescriptor> resolutionResults = context.resolveCallWithGivenName( OverloadResolutionResults<FunctionDescriptor> resolutionResults = components.callResolver.resolveCallWithGivenName(
context,
CallMaker.makeCall(receiver, expression), CallMaker.makeCall(receiver, expression),
expression.getOperationReference(), expression.getOperationReference(),
name); name);
@@ -726,7 +717,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
assert operationSign.getReferencedNameElementType() == JetTokens.EXCLEXCL; assert operationSign.getReferencedNameElementType() == JetTokens.EXCLEXCL;
Call call = createCallForSpecialConstruction(expression, Collections.singletonList(baseExpression)); Call call = createCallForSpecialConstruction(expression, Collections.singletonList(baseExpression));
resolveSpecialConstructionAsCall( components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(
call, "ExclExcl", Collections.singletonList("baseExpr"), Collections.singletonList(true), context, null); call, "ExclExcl", Collections.singletonList("baseExpr"), Collections.singletonList(true), context, null);
JetTypeInfo baseTypeInfo = BindingContextUtils.getRecordedTypeInfo(baseExpression, context.trace.getBindingContext()); JetTypeInfo baseTypeInfo = BindingContextUtils.getRecordedTypeInfo(baseExpression, context.trace.getBindingContext());
assert baseTypeInfo != null : "Base expression was not processed: " + expression; 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)); Call call = CallMaker.makeCallWithExpressions(operationSign, receiver, null, operationSign, Collections.singletonList(right));
ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny); ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny);
OverloadResolutionResults<FunctionDescriptor> resolutionResults = OverloadResolutionResults<FunctionDescriptor> resolutionResults =
newContext.resolveCallWithGivenName(call, operationSign, OperatorConventions.EQUALS); components.callResolver.resolveCallWithGivenName(newContext, call, operationSign, OperatorConventions.EQUALS);
traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() { traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {
@Override @Override
@@ -991,7 +982,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
Call call = createCallForSpecialConstruction(expression, Lists.newArrayList(left, right)); Call call = createCallForSpecialConstruction(expression, Lists.newArrayList(left, right));
ResolvedCall<FunctionDescriptor> resolvedCall = resolveSpecialConstructionAsCall( ResolvedCall<FunctionDescriptor> resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(
call, "Elvis", Lists.newArrayList("left", "right"), Lists.newArrayList(true, false), contextWithExpectedType, null); call, "Elvis", Lists.newArrayList("left", "right"), Lists.newArrayList(true, false), contextWithExpectedType, null);
JetTypeInfo leftTypeInfo = BindingContextUtils.getRecordedTypeInfo(left, context.trace.getBindingContext()); JetTypeInfo leftTypeInfo = BindingContextUtils.getRecordedTypeInfo(left, context.trace.getBindingContext());
assert leftTypeInfo != null : "Left expression was not processed: " + expression; assert leftTypeInfo != null : "Left expression was not processed: " + expression;
@@ -1029,7 +1020,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, contextWithNoExpectedType); ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, contextWithNoExpectedType);
ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo); ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
OverloadResolutionResults<FunctionDescriptor> resolutionResult = contextWithDataFlow.resolveCallWithGivenName( OverloadResolutionResults<FunctionDescriptor> resolutionResult = components.callResolver.resolveCallWithGivenName(
contextWithDataFlow,
CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)), CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)),
operationSign, operationSign,
OperatorConventions.CONTAINS); OperatorConventions.CONTAINS);
@@ -1135,7 +1127,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
OverloadResolutionResults<FunctionDescriptor> resolutionResults; OverloadResolutionResults<FunctionDescriptor> resolutionResults;
if (left != null) { if (left != null) {
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, left, context); 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 { else {
resolutionResults = OverloadResolutionResultsImpl.nameNotFound(); resolutionResults = OverloadResolutionResultsImpl.nameNotFound();
@@ -1148,23 +1143,6 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
return JetTypeInfo.create(OverloadResolutionResultsUtil.getResultingType(resolutionResults, context.contextDependency), dataFlowInfo); return JetTypeInfo.create(OverloadResolutionResultsUtil.getResultingType(resolutionResults, context.contextDependency), dataFlowInfo);
} }
@NotNull
static
/*package*/ OverloadResolutionResults<FunctionDescriptor> 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 @Override
public JetTypeInfo visitDeclaration(@NotNull JetDeclaration dcl, ExpressionTypingContext context) { public JetTypeInfo visitDeclaration(@NotNull JetDeclaration dcl, ExpressionTypingContext context) {
context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(dcl)); 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) { public JetTypeInfo visitAnnotatedExpression(JetAnnotatedExpression expression, ExpressionTypingContext context, boolean isStatement) {
context.expressionTypingServices.getAnnotationResolver().resolveAnnotationsWithArguments( components.expressionTypingServices.getAnnotationResolver().resolveAnnotationsWithArguments(
context.scope, expression.getAnnotationEntries(), context.trace); context.scope, expression.getAnnotationEntries(), context.trace);
JetExpression baseExpression = expression.getBaseExpression(); JetExpression baseExpression = expression.getBaseExpression();
@@ -1262,12 +1240,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ExpressionReceiver receiver = new ExpressionReceiver(arrayExpression, arrayType); ExpressionReceiver receiver = new ExpressionReceiver(arrayExpression, arrayType);
if (!isGet) assert rightHandSide != null; if (!isGet) assert rightHandSide != null;
OverloadResolutionResults<FunctionDescriptor> functionResults = context.resolveCallWithGivenName( OverloadResolutionResults<FunctionDescriptor> functionResults = components.callResolver.resolveCallWithGivenName(
context,
isGet isGet
? CallMaker.makeArrayGetCall(receiver, arrayAccessExpression, Call.CallType.ARRAY_GET_METHOD) ? CallMaker.makeArrayGetCall(receiver, arrayAccessExpression, Call.CallType.ARRAY_GET_METHOD)
: CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide, Call.CallType.ARRAY_SET_METHOD), : CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide, Call.CallType.ARRAY_SET_METHOD),
arrayAccessExpression, arrayAccessExpression,
Name.identifier(isGet ? "get" : "set")); Name.identifier(isGet ? "get" : "set")
);
List<JetExpression> indices = arrayAccessExpression.getIndexExpressions(); List<JetExpression> indices = arrayAccessExpression.getIndexExpressions();
// The accumulated data flow info of all index expressions is saved on the last index // The accumulated data flow info of all index expressions is saved on the last index
@@ -23,7 +23,6 @@ import com.intellij.util.containers.ContainerUtil;
import jet.Function0; import jet.Function0;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.*; 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; import static org.jetbrains.jet.lang.types.expressions.CoercionStrategy.COERCION_TO_UNIT;
public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
private final GlobalContext globalContext;
protected ClosureExpressionsTypingVisitor( protected ClosureExpressionsTypingVisitor(@NotNull ExpressionTypingInternals facade) {
@NotNull GlobalContext globalContext,
@NotNull ExpressionTypingInternals facade
) {
super(facade); super(facade);
this.globalContext = globalContext;
} }
@Override @Override
@@ -76,7 +70,8 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
@Override @Override
public void handleRecord(WritableSlice<PsiElement, ClassDescriptor> slice, PsiElement declaration, final ClassDescriptor descriptor) { public void handleRecord(WritableSlice<PsiElement, ClassDescriptor> slice, PsiElement declaration, final ClassDescriptor descriptor) {
if (slice == CLASS && declaration == expression.getObjectDeclaration()) { 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<JetType>() { new Function0<JetType>() {
@Override @Override
public JetType invoke() { public JetType invoke() {
@@ -93,7 +88,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
}; };
ObservableBindingTrace traceAdapter = new ObservableBindingTrace(temporaryTrace); ObservableBindingTrace traceAdapter = new ObservableBindingTrace(temporaryTrace);
traceAdapter.addHandler(CLASS, handler); traceAdapter.addHandler(CLASS, handler);
TopDownAnalyzer.processClassOrObject(globalContext, TopDownAnalyzer.processClassOrObject(components.globalContext,
null, // don't need to add classifier of object literal to any scope null, // don't need to add classifier of object literal to any scope
context.replaceBindingTrace(traceAdapter).replaceContextDependency(INDEPENDENT), context.replaceBindingTrace(traceAdapter).replaceContextDependency(INDEPENDENT),
context.scope.getContainingDeclaration(), context.scope.getContainingDeclaration(),
@@ -177,7 +172,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
} }
@NotNull @NotNull
private static AnonymousFunctionDescriptor createFunctionDescriptor( private AnonymousFunctionDescriptor createFunctionDescriptor(
@NotNull JetFunctionLiteralExpression expression, @NotNull JetFunctionLiteralExpression expression,
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
boolean functionTypeExpected boolean functionTypeExpected
@@ -200,7 +195,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
} }
} }
else { 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, functionDescriptor.initialize(effectiveReceiverType,
ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER, ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER,
@@ -215,7 +210,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
} }
@NotNull @NotNull
private static List<ValueParameterDescriptor> createValueParameterDescriptors( private List<ValueParameterDescriptor> createValueParameterDescriptors(
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull JetFunctionLiteral functionLiteral, @NotNull JetFunctionLiteral functionLiteral,
@NotNull FunctionDescriptorImpl functionDescriptor, @NotNull FunctionDescriptorImpl functionDescriptor,
@@ -254,7 +249,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
} }
@NotNull @NotNull
private static ValueParameterDescriptor createValueParameterDescriptor( private ValueParameterDescriptor createValueParameterDescriptor(
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull FunctionDescriptorImpl functionDescriptor, @NotNull FunctionDescriptorImpl functionDescriptor,
@NotNull List<JetParameter> declaredValueParameters, @NotNull List<JetParameter> declaredValueParameters,
@@ -273,7 +268,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
} }
JetType type; JetType type;
if (typeReference != null) { 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 (expectedType != null) {
if (!JetTypeChecker.INSTANCE.isSubtypeOf(expectedType, type)) { if (!JetTypeChecker.INSTANCE.isSubtypeOf(expectedType, type)) {
context.trace.report(EXPECTED_PARAMETER_TYPE_MISMATCH.on(declaredParameter, expectedType)); 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; type = CANT_INFER_LAMBDA_PARAM_TYPE;
} }
} }
return context.expressionTypingServices.getDescriptorResolver().resolveValueParameterDescriptorWithAnnotationArguments( return components.expressionTypingServices.getDescriptorResolver().resolveValueParameterDescriptorWithAnnotationArguments(
context.scope, functionDescriptor, declaredParameter, index, type, context.trace); context.scope, functionDescriptor, declaredParameter, index, type, context.trace);
} }
@NotNull @NotNull
private static JetType computeReturnType( private JetType computeReturnType(
@NotNull JetFunctionLiteralExpression expression, @NotNull JetFunctionLiteralExpression expression,
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull SimpleFunctionDescriptorImpl functionDescriptor, @NotNull SimpleFunctionDescriptorImpl functionDescriptor,
@@ -314,7 +309,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
} }
@Nullable @Nullable
private static JetType computeUnsafeReturnType( private JetType computeUnsafeReturnType(
@NotNull JetFunctionLiteralExpression expression, @NotNull JetFunctionLiteralExpression expression,
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull SimpleFunctionDescriptorImpl functionDescriptor, @NotNull SimpleFunctionDescriptorImpl functionDescriptor,
@@ -328,7 +323,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef(); JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef();
JetType declaredReturnType = null; JetType declaredReturnType = null;
if (returnTypeRef != 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 // This is needed for ControlStructureTypingVisitor#visitReturnExpression() to properly type-check returned expressions
functionDescriptor.setReturnType(declaredReturnType); functionDescriptor.setReturnType(declaredReturnType);
if (expectedReturnType != null) { if (expectedReturnType != null) {
@@ -344,7 +339,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
? declaredReturnType ? declaredReturnType
: (expectedReturnType != null ? expectedReturnType : NO_EXPECTED_TYPE)); : (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<JetType> returnedExpressionTypes = Lists.newArrayList(getTypesOfLocallyReturnedExpressions( List<JetType> returnedExpressionTypes = Lists.newArrayList(getTypesOfLocallyReturnedExpressions(
functionLiteral, context.trace, collectReturns(bodyExpression))); functionLiteral, context.trace, collectReturns(bodyExpression)));
@@ -55,10 +55,14 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.CALL;
import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL; import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL;
public class ControlStructureTypingUtils { public class ControlStructureTypingUtils {
private ControlStructureTypingUtils() {
private final ExpressionTypingServices expressionTypingServices;
public ControlStructureTypingUtils(@NotNull ExpressionTypingServices expressionTypingServices) {
this.expressionTypingServices = expressionTypingServices;
} }
/*package*/ static ResolvedCall<FunctionDescriptor> resolveSpecialConstructionAsCall( /*package*/ ResolvedCall<FunctionDescriptor> resolveSpecialConstructionAsCall(
@NotNull Call call, @NotNull Call call,
@NotNull String constructionName, @NotNull String constructionName,
@NotNull List<String> argumentNames, @NotNull List<String> argumentNames,
@@ -69,10 +73,10 @@ public class ControlStructureTypingUtils {
SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction( SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction(
constructionName.toUpperCase(), argumentNames, isArgumentNullable); constructionName.toUpperCase(), argumentNames, isArgumentNullable);
JetReferenceExpression reference = JetPsiFactory.createSimpleName( JetReferenceExpression reference = JetPsiFactory.createSimpleName(
context.expressionTypingServices.getProject(), "fake" + constructionName + "Call"); expressionTypingServices.getProject(), "fake" + constructionName + "Call");
TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName); TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName);
ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create(function, null); ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create(function, null);
CallResolver callResolver = context.expressionTypingServices.getCallResolver(); CallResolver callResolver = expressionTypingServices.getCallResolver();
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallWithKnownCandidate( OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallWithKnownCandidate(
call, tracing, reference, context, resolutionCandidate, dataFlowInfoForArguments); call, tracing, reference, context, resolutionCandidate, dataFlowInfoForArguments);
assert results.isSingleResult() : "Not single result after resolving one known candidate"; assert results.isSingleResult() : "Not single result after resolving one known candidate";
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.types.expressions; package org.jetbrains.jet.lang.types.expressions;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull; 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.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; 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.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; 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.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments; 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.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.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; 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.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -122,7 +117,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
Call callForIf = createCallForSpecialConstruction(ifExpression, Lists.newArrayList(thenBlock, elseBlock)); Call callForIf = createCallForSpecialConstruction(ifExpression, Lists.newArrayList(thenBlock, elseBlock));
MutableDataFlowInfoForArguments dataFlowInfoForArguments = MutableDataFlowInfoForArguments dataFlowInfoForArguments =
createDataFlowInfoForArgumentsForIfCall(callForIf, thenInfo, elseInfo); createDataFlowInfoForArgumentsForIfCall(callForIf, thenInfo, elseInfo);
ResolvedCall<FunctionDescriptor> resolvedCall = resolveSpecialConstructionAsCall( ResolvedCall<FunctionDescriptor> resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(
callForIf, "If", Lists.newArrayList("thenBranch", "elseBranch"), callForIf, "If", Lists.newArrayList("thenBranch", "elseBranch"),
Lists.newArrayList(false, false), Lists.newArrayList(false, false),
contextWithExpectedType, dataFlowInfoForArguments); contextWithExpectedType, dataFlowInfoForArguments);
@@ -158,7 +153,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
} }
@NotNull @NotNull
private static JetTypeInfo getTypeInfoWhenOnlyOneBranchIsPresent( private JetTypeInfo getTypeInfoWhenOnlyOneBranchIsPresent(
@NotNull JetExpression presentBranch, @NotNull JetExpression presentBranch,
@NotNull WritableScopeImpl presentScope, @NotNull WritableScopeImpl presentScope,
@NotNull DataFlowInfo presentInfo, @NotNull DataFlowInfo presentInfo,
@@ -169,7 +164,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
) { ) {
ExpressionTypingContext newContext = context.replaceDataFlowInfo(presentInfo).replaceExpectedType(NO_EXPECTED_TYPE) ExpressionTypingContext newContext = context.replaceDataFlowInfo(presentInfo).replaceExpectedType(NO_EXPECTED_TYPE)
.replaceContextDependency(INDEPENDENT); .replaceContextDependency(INDEPENDENT);
JetTypeInfo typeInfo = context.expressionTypingServices.getBlockReturnedTypeWithWritableScope( JetTypeInfo typeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
presentScope, Collections.singletonList(presentBranch), CoercionStrategy.NO_COERCION, newContext, context.trace); presentScope, Collections.singletonList(presentBranch), CoercionStrategy.NO_COERCION, newContext, context.trace);
JetType type = typeInfo.getType(); JetType type = typeInfo.getType();
DataFlowInfo dataFlowInfo; DataFlowInfo dataFlowInfo;
@@ -199,7 +194,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
if (body != null) { if (body != null) {
WritableScopeImpl scopeToExtend = newWritableScopeImpl(context, "Scope extended in while's condition"); WritableScopeImpl scopeToExtend = newWritableScopeImpl(context, "Scope extended in while's condition");
DataFlowInfo conditionInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo); DataFlowInfo conditionInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo);
context.expressionTypingServices.getBlockReturnedTypeWithWritableScope( components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
scopeToExtend, Collections.singletonList(body), scopeToExtend, Collections.singletonList(body),
CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(conditionInfo), context.trace); CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(conditionInfo), context.trace);
} }
@@ -266,7 +261,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
if (!functionLiteral.hasParameterSpecification()) { if (!functionLiteral.hasParameterSpecification()) {
WritableScope writableScope = newWritableScopeImpl(context, "do..while body scope"); WritableScope writableScope = newWritableScopeImpl(context, "do..while body scope");
conditionScope = writableScope; 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); context.trace.record(BindingContext.BLOCK, function);
} }
else { else {
@@ -284,7 +279,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
else { else {
block = Collections.<JetElement>singletonList(body); block = Collections.<JetElement>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(); JetExpression condition = expression.getCondition();
DataFlowInfo conditionDataFlowInfo = checkCondition(conditionScope, condition, context); DataFlowInfo conditionDataFlowInfo = checkCondition(conditionScope, condition, context);
@@ -315,7 +310,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
ExpressionReceiver loopRangeReceiver = getExpressionReceiver(facade, loopRange, context.replaceScope(context.scope)); ExpressionReceiver loopRangeReceiver = getExpressionReceiver(facade, loopRange, context.replaceScope(context.scope));
dataFlowInfo = facade.getTypeInfo(loopRange, context).getDataFlowInfo(); dataFlowInfo = facade.getTypeInfo(loopRange, context).getDataFlowInfo();
if (loopRangeReceiver != null) { 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) { if (multiParameter != null && loopRange != null) {
JetType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType; JetType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType;
TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType); TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType);
ExpressionTypingUtils.defineLocalVariablesFromMultiDeclaration(loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context); components.expressionTypingUtils.defineLocalVariablesFromMultiDeclaration(loopScope, multiParameter, iteratorNextAsReceiver,
loopRange, context);
} }
} }
JetExpression body = expression.getBody(); JetExpression body = expression.getBody();
if (body != null) { 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); CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(dataFlowInfo), context.trace);
} }
return DataFlowUtils.checkType(KotlinBuiltIns.getInstance().getUnitType(), expression, contextWithExpectedType, dataFlowInfo); return DataFlowUtils.checkType(KotlinBuiltIns.getInstance().getUnitType(), expression, contextWithExpectedType, dataFlowInfo);
} }
private static VariableDescriptor createLoopParameterDescriptor( private VariableDescriptor createLoopParameterDescriptor(
JetParameter loopParameter, JetParameter loopParameter,
JetType expectedParameterType, JetType expectedParameterType,
ExpressionTypingContext context ExpressionTypingContext context
@@ -355,7 +351,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
JetTypeReference typeReference = loopParameter.getTypeReference(); JetTypeReference typeReference = loopParameter.getTypeReference();
VariableDescriptor variableDescriptor; VariableDescriptor variableDescriptor;
if (typeReference != null) { 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(); JetType actualParameterType = variableDescriptor.getType();
if (expectedParameterType != null && if (expectedParameterType != null &&
!JetTypeChecker.INSTANCE.isSubtypeOf(expectedParameterType, actualParameterType)) { !JetTypeChecker.INSTANCE.isSubtypeOf(expectedParameterType, actualParameterType)) {
@@ -366,7 +362,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
if (expectedParameterType == null) { if (expectedParameterType == null) {
expectedParameterType = ErrorUtils.createErrorType("Error"); 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; 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<Call, OverloadResolutionResults<FunctionDescriptor>> calls = makeAndResolveFakeCall(loopRange, context, Collections.<JetExpression>emptyList(), iterator);
Call iteratorCall = calls.getFirst();
OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResults = calls.getSecond();
if (iteratorResolutionResults.isSuccess()) {
ResolvedCall<FunctionDescriptor> 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<JetExpression, JetType> ambiguity,
@NotNull DiagnosticFactory1<JetExpression, JetType> missing,
@NotNull DiagnosticFactory1<JetExpression, JetType> noneApplicable,
@NotNull WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> resolvedCallKey
) {
OverloadResolutionResults<FunctionDescriptor> 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<FunctionDescriptor> resolvedCall = nextResolutionResults.getResultingCall();
context.trace.record(resolvedCallKey, loopRangeExpression, resolvedCall);
return resolvedCall.getResultingDescriptor().getReturnType();
}
return null;
}
@Override @Override
public JetTypeInfo visitTryExpression(@NotNull JetTryExpression expression, ExpressionTypingContext typingContext) { public JetTypeInfo visitTryExpression(@NotNull JetTryExpression expression, ExpressionTypingContext typingContext) {
ExpressionTypingContext context = typingContext.replaceContextDependency(INDEPENDENT); 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.checkParameterHasNoValOrVar(context.trace, catchParameter, VAL_OR_VAR_ON_CATCH_PARAMETER);
DescriptorResolver.checkParameterHasNoModifier(context.trace, catchParameter); DescriptorResolver.checkParameterHasNoModifier(context.trace, catchParameter);
VariableDescriptor variableDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveLocalVariableDescriptor( VariableDescriptor variableDescriptor = components.expressionTypingServices.getDescriptorResolver().resolveLocalVariableDescriptor(
context.scope, catchParameter, context.trace); context.scope, catchParameter, context.trace);
JetType throwableType = KotlinBuiltIns.getInstance().getThrowable().getDefaultType(); JetType throwableType = KotlinBuiltIns.getInstance().getThrowable().getDefaultType();
DataFlowUtils.checkType(variableDescriptor.getType(), catchParameter, context.replaceExpectedType(throwableType)); DataFlowUtils.checkType(variableDescriptor.getType(), catchParameter, context.replaceExpectedType(throwableType));
@@ -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;
}
}
@@ -18,16 +18,14 @@ package org.jetbrains.jet.lang.types.expressions;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; 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.BindingTrace;
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtension; import org.jetbrains.jet.lang.resolve.calls.CallResolverExtension;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.context.*; import org.jetbrains.jet.lang.resolve.calls.context.ContextDependency;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; 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.constants.CompileTimeConstantChecker;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
@@ -41,17 +39,14 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType @NotNull JetType expectedType
) { ) {
return newContext(expressionTypingServices, trace, scope, dataFlowInfo, expectedType, return newContext(trace, scope, dataFlowInfo, expectedType,
ContextDependency.INDEPENDENT, ResolutionResultsCacheImpl.create(), LabelResolver.create(), ContextDependency.INDEPENDENT, ResolutionResultsCacheImpl.create(), LabelResolver.create(),
expressionTypingServices.createExtension(scope, false), false); expressionTypingServices.createExtension(scope, false), false);
} }
@NotNull @NotNull
public static ExpressionTypingContext newContext( public static ExpressionTypingContext newContext(@NotNull ResolutionContext resolutionContext) {
@NotNull ExpressionTypingServices expressionTypingServices, return newContext(resolutionContext.trace, resolutionContext.scope, resolutionContext.dataFlowInfo,
@NotNull ResolutionContext resolutionContext
) {
return newContext(expressionTypingServices, resolutionContext.trace, resolutionContext.scope, resolutionContext.dataFlowInfo,
resolutionContext.expectedType, resolutionContext.contextDependency, resolutionContext.expectedType, resolutionContext.contextDependency,
resolutionContext.resolutionResultsCache, resolutionContext.labelResolver, resolutionContext.resolutionResultsCache, resolutionContext.labelResolver,
resolutionContext.callResolverExtension, resolutionContext.isAnnotationContext); resolutionContext.callResolverExtension, resolutionContext.isAnnotationContext);
@@ -59,7 +54,6 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull @NotNull
public static ExpressionTypingContext newContext( public static ExpressionTypingContext newContext(
@NotNull ExpressionTypingServices expressionTypingServices,
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@@ -70,16 +64,14 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull CallResolverExtension callResolverExtension, @NotNull CallResolverExtension callResolverExtension,
boolean isAnnotationContext boolean isAnnotationContext
) { ) {
return new ExpressionTypingContext(expressionTypingServices, labelResolver, trace, scope, scope.getContainingDeclaration(), dataFlowInfo, return new ExpressionTypingContext(labelResolver, trace, scope, scope.getContainingDeclaration(), dataFlowInfo,
expectedType, contextDependency, resolutionResultsCache, callResolverExtension, isAnnotationContext); expectedType, contextDependency, resolutionResultsCache, callResolverExtension, isAnnotationContext);
} }
public final ExpressionTypingServices expressionTypingServices;
public final DeclarationDescriptor containingDeclaration; public final DeclarationDescriptor containingDeclaration;
private CompileTimeConstantChecker compileTimeConstantChecker; private CompileTimeConstantChecker compileTimeConstantChecker;
private ExpressionTypingContext( private ExpressionTypingContext(
@NotNull ExpressionTypingServices expressionTypingServices,
@NotNull LabelResolver labelResolver, @NotNull LabelResolver labelResolver,
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
@@ -93,7 +85,6 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
) { ) {
super(trace, scope, expectedType, dataFlowInfo, contextDependency, resolutionResultsCache, labelResolver, callResolverExtension, super(trace, scope, expectedType, dataFlowInfo, contextDependency, resolutionResultsCache, labelResolver, callResolverExtension,
isAnnotationContext); isAnnotationContext);
this.expressionTypingServices = expressionTypingServices;
this.containingDeclaration = containingDeclaration; this.containingDeclaration = containingDeclaration;
} }
@@ -107,7 +98,7 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull ResolutionResultsCache resolutionResultsCache, @NotNull ResolutionResultsCache resolutionResultsCache,
@NotNull LabelResolver labelResolver @NotNull LabelResolver labelResolver
) { ) {
return new ExpressionTypingContext(expressionTypingServices, this.labelResolver, trace, scope, containingDeclaration, dataFlowInfo, return new ExpressionTypingContext(this.labelResolver, trace, scope, containingDeclaration, dataFlowInfo,
expectedType, contextDependency, resolutionResultsCache, callResolverExtension, expectedType, contextDependency, resolutionResultsCache, callResolverExtension,
isAnnotationContext); isAnnotationContext);
} }
@@ -120,15 +111,4 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
} }
return compileTimeConstantChecker; return compileTimeConstantChecker;
} }
////////// Call resolution utilities
@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull Name name) {
return expressionTypingServices.getCallResolver().resolveCallWithGivenName(
BasicCallResolutionContext.create(this, call, CheckValueArgumentsMode.ENABLED),
functionReference,
name
);
}
} }
@@ -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); JetTypeInfo checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context);
void checkStatementType(@NotNull JetExpression expression, ExpressionTypingContext context); void checkStatementType(@NotNull JetExpression expression, ExpressionTypingContext context);
@NotNull
ExpressionTypingComponents getComponents();
} }
@@ -21,8 +21,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
@@ -57,7 +55,10 @@ import static org.jetbrains.jet.lang.types.expressions.CoercionStrategy.COERCION
public class ExpressionTypingServices { public class ExpressionTypingServices {
@NotNull @NotNull
private ExpressionTypingFacade expressionTypingFacade; private final ExpressionTypingFacade expressionTypingFacade;
@NotNull
private final ExpressionTypingComponents expressionTypingComponents;
@NotNull @NotNull
private Project project; private Project project;
@NotNull @NotNull
@@ -71,11 +72,7 @@ public class ExpressionTypingServices {
@NotNull @NotNull
private AnnotationResolver annotationResolver; private AnnotationResolver annotationResolver;
@NotNull @NotNull
private PlatformToKotlinClassMap platformToKotlinClassMap;
@NotNull
private CallResolverExtensionProvider extensionProvider; private CallResolverExtensionProvider extensionProvider;
@NotNull
private GlobalContext globalContext;
@NotNull @NotNull
public Project getProject() { public Project getProject() {
@@ -137,23 +134,14 @@ public class ExpressionTypingServices {
this.annotationResolver = annotationResolver; this.annotationResolver = annotationResolver;
} }
@NotNull
public PlatformToKotlinClassMap getPlatformToKotlinClassMap() {
return platformToKotlinClassMap;
}
@Inject @Inject
public void setExtensionProvider(@NotNull CallResolverExtensionProvider extensionProvider) { public void setExtensionProvider(@NotNull CallResolverExtensionProvider extensionProvider) {
this.extensionProvider = extensionProvider; this.extensionProvider = extensionProvider;
} }
public ExpressionTypingServices( public ExpressionTypingServices(@NotNull ExpressionTypingComponents components) {
@NotNull GlobalContext globalContext, this.expressionTypingComponents = components;
@NotNull PlatformToKotlinClassMap platformToKotlinClassMap this.expressionTypingFacade = ExpressionTypingVisitorDispatcher.create(components);
) {
this.globalContext = globalContext;
this.platformToKotlinClassMap = platformToKotlinClassMap;
this.expressionTypingFacade = ExpressionTypingVisitorDispatcher.create(globalContext, platformToKotlinClassMap);
} }
@NotNull @NotNull
@@ -173,7 +161,7 @@ public class ExpressionTypingServices {
@NotNull @NotNull
public JetTypeInfo getTypeInfo(@NotNull JetExpression expression, @NotNull ResolutionContext resolutionContext) { 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 @Nullable
@@ -208,6 +196,11 @@ public class ExpressionTypingServices {
expressionTypingFacade.getTypeInfo(bodyExpression, newContext, blockBody); 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 @NotNull
public JetTypeInfo getBlockReturnedType( public JetTypeInfo getBlockReturnedType(
@NotNull JetBlockExpression expression, @NotNull JetBlockExpression expression,
@@ -282,7 +275,7 @@ public class ExpressionTypingServices {
return JetTypeInfo.create(KotlinBuiltIns.getInstance().getUnitType(), context.dataFlowInfo); 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); ExpressionTypingContext newContext = createContext(context, trace, scope, context.dataFlowInfo, NO_EXPECTED_TYPE);
JetTypeInfo result = JetTypeInfo.create(null, context.dataFlowInfo); JetTypeInfo result = JetTypeInfo.create(null, context.dataFlowInfo);
@@ -306,7 +299,7 @@ public class ExpressionTypingServices {
if (newDataFlowInfo != context.dataFlowInfo) { if (newDataFlowInfo != context.dataFlowInfo) {
newContext = newContext.replaceDataFlowInfo(newDataFlowInfo); newContext = newContext.replaceDataFlowInfo(newDataFlowInfo);
} }
blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(globalContext, platformToKotlinClassMap, scope); blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(expressionTypingComponents, scope);
} }
return result; return result;
} }
@@ -353,7 +346,7 @@ public class ExpressionTypingServices {
} }
private ExpressionTypingContext createContext(ExpressionTypingContext oldContext, BindingTrace trace, WritableScope scope, DataFlowInfo dataFlowInfo, JetType expectedType) { 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.resolutionResultsCache, oldContext.labelResolver,
oldContext.callResolverExtension, oldContext.isAnnotationContext); oldContext.callResolverExtension, oldContext.isAnnotationContext);
} }
@@ -32,7 +32,7 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*; 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.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl; 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 { 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 @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 * 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 @NotNull
public static OverloadResolutionResults<FunctionDescriptor> resolveFakeCall( public OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull ReceiverValue receiver, @NotNull ReceiverValue receiver,
@NotNull Name name, @NotNull Name name,
@@ -328,7 +319,7 @@ public class ExpressionTypingUtils {
name); name);
List<JetExpression> fakeArguments = Lists.newArrayList(); List<JetExpression> fakeArguments = Lists.newArrayList();
for (JetType type : argumentTypes) { for (JetType type : argumentTypes) {
fakeArguments.add(createFakeExpressionOfType(context.expressionTypingServices.getProject(), traceWithFakeArgumentInfo, fakeArguments.add(createFakeExpressionOfType(expressionTypingServices.getProject(), traceWithFakeArgumentInfo,
"fakeArgument" + fakeArguments.size(), type)); "fakeArgument" + fakeArguments.size(), type));
} }
return makeAndResolveFakeCall(receiver, context.replaceBindingTrace(traceWithFakeArgumentInfo), fakeArguments, name).getSecond(); return makeAndResolveFakeCall(receiver, context.replaceBindingTrace(traceWithFakeArgumentInfo), fakeArguments, name).getSecond();
@@ -347,7 +338,7 @@ public class ExpressionTypingUtils {
} }
@NotNull @NotNull
public static OverloadResolutionResults<FunctionDescriptor> resolveFakeCall( public OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull ReceiverValue receiver, @NotNull ReceiverValue receiver,
@NotNull Name name @NotNull Name name
@@ -356,7 +347,7 @@ public class ExpressionTypingUtils {
} }
@NotNull @NotNull
public static OverloadResolutionResults<FunctionDescriptor> resolveFakeCall( public OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(
@NotNull ReceiverValue receiver, @NotNull ReceiverValue receiver,
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull List<JetExpression> valueArguments, @NotNull List<JetExpression> valueArguments,
@@ -366,17 +357,17 @@ public class ExpressionTypingUtils {
} }
@NotNull @NotNull
public static Pair<Call, OverloadResolutionResults<FunctionDescriptor>> makeAndResolveFakeCall( public Pair<Call, OverloadResolutionResults<FunctionDescriptor>> makeAndResolveFakeCall(
@NotNull ReceiverValue receiver, @NotNull ReceiverValue receiver,
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull List<JetExpression> valueArguments, @NotNull List<JetExpression> valueArguments,
@NotNull Name name @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); TemporaryBindingTrace fakeTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve fake call for", name);
Call call = CallMaker.makeCallWithExpressions(fake, receiver, null, fake, valueArguments); Call call = CallMaker.makeCallWithExpressions(fake, receiver, null, fake, valueArguments);
OverloadResolutionResults<FunctionDescriptor> results = OverloadResolutionResults<FunctionDescriptor> results =
context.replaceBindingTrace(fakeTrace).resolveCallWithGivenName(call, fake, name); callResolver.resolveCallWithGivenName(context.replaceBindingTrace(fakeTrace), call, fake, name);
if (results.isSuccess()) { if (results.isSuccess()) {
fakeTrace.commit(new TraceEntryFilter() { fakeTrace.commit(new TraceEntryFilter() {
@Override @Override
@@ -389,7 +380,7 @@ public class ExpressionTypingUtils {
return Pair.create(call, results); return Pair.create(call, results);
} }
public static void defineLocalVariablesFromMultiDeclaration( public void defineLocalVariablesFromMultiDeclaration(
@NotNull WritableScope writableScope, @NotNull WritableScope writableScope,
@NotNull JetMultiDeclaration multiDeclaration, @NotNull JetMultiDeclaration multiDeclaration,
@NotNull ReceiverValue receiver, @NotNull ReceiverValue receiver,
@@ -425,7 +416,7 @@ public class ExpressionTypingUtils {
if (componentType == null) { if (componentType == null) {
componentType = ErrorUtils.createErrorType(componentName + "() return type"); componentType = ErrorUtils.createErrorType(componentName + "() return type");
} }
VariableDescriptor variableDescriptor = context.expressionTypingServices.getDescriptorResolver(). VariableDescriptor variableDescriptor = expressionTypingServices.getDescriptorResolver().
resolveLocalVariableDescriptorWithType(writableScope, entry, componentType, context.trace); resolveLocalVariableDescriptorWithType(writableScope, entry, componentType, context.trace);
VariableDescriptor olderVariable = writableScope.getLocalVariable(variableDescriptor.getName()); VariableDescriptor olderVariable = writableScope.getLocalVariable(variableDescriptor.getName());
@@ -445,10 +436,10 @@ public class ExpressionTypingUtils {
} }
@NotNull @NotNull
private static JetType getExpectedTypeForComponent(ExpressionTypingContext context, JetMultiDeclarationEntry entry) { private JetType getExpectedTypeForComponent(ExpressionTypingContext context, JetMultiDeclarationEntry entry) {
JetTypeReference entryTypeRef = entry.getTypeRef(); JetTypeReference entryTypeRef = entry.getTypeRef();
if (entryTypeRef != null) { 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 { else {
return TypeUtils.NO_EXPECTED_TYPE; return TypeUtils.NO_EXPECTED_TYPE;
@@ -23,8 +23,10 @@ import org.jetbrains.jet.lang.types.JetTypeInfo;
/*package*/ abstract class ExpressionTypingVisitor extends JetVisitor<JetTypeInfo, ExpressionTypingContext> { /*package*/ abstract class ExpressionTypingVisitor extends JetVisitor<JetTypeInfo, ExpressionTypingContext> {
protected final ExpressionTypingInternals facade; protected final ExpressionTypingInternals facade;
protected final ExpressionTypingComponents components;
protected ExpressionTypingVisitor(@NotNull ExpressionTypingInternals facade) { protected ExpressionTypingVisitor(@NotNull ExpressionTypingInternals facade) {
this.facade = facade; this.facade = facade;
this.components = facade.getComponents();
} }
} }
@@ -18,8 +18,6 @@ package org.jetbrains.jet.lang.types.expressions;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; 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<JetTypeInfo, ExpressionTypingContext> implements ExpressionTypingInternals { public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, ExpressionTypingContext> implements ExpressionTypingInternals {
@NotNull @NotNull
public static ExpressionTypingFacade create(@NotNull GlobalContext globalContext, @NotNull PlatformToKotlinClassMap platformToKotlinClassMap) { public static ExpressionTypingFacade create(@NotNull ExpressionTypingComponents components) {
return new ExpressionTypingVisitorDispatcher(globalContext, platformToKotlinClassMap, null); return new ExpressionTypingVisitorDispatcher(components, null);
} }
@NotNull @NotNull
public static ExpressionTypingInternals createForBlock( public static ExpressionTypingInternals createForBlock(
@NotNull GlobalContext globalContext, @NotNull ExpressionTypingComponents components,
@NotNull PlatformToKotlinClassMap platformToKotlinClassMap,
@NotNull WritableScope writableScope @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 BasicExpressionTypingVisitor basic;
private final ExpressionTypingVisitorForStatements statements; private final ExpressionTypingVisitorForStatements statements;
private final ClosureExpressionsTypingVisitor closures; private final ClosureExpressionsTypingVisitor closures;
private final ControlStructureTypingVisitor controlStructures = new ControlStructureTypingVisitor(this); private final ControlStructureTypingVisitor controlStructures;
private final PatternMatchingTypingVisitor patterns = new PatternMatchingTypingVisitor(this); private final PatternMatchingTypingVisitor patterns;
private ExpressionTypingVisitorDispatcher(GlobalContext globalContext, PlatformToKotlinClassMap platformToKotlinClassMap, WritableScope writableScope) { private ExpressionTypingVisitorDispatcher(@NotNull ExpressionTypingComponents components, WritableScope writableScope) {
this.globalContext = globalContext; this.components = components;
this.basic = new BasicExpressionTypingVisitor(this, platformToKotlinClassMap); this.basic = new BasicExpressionTypingVisitor(this);
controlStructures = new ControlStructureTypingVisitor(this);
patterns = new PatternMatchingTypingVisitor(this);
if (writableScope != null) { if (writableScope != null) {
this.statements = new ExpressionTypingVisitorForStatements(globalContext, this, writableScope, basic, controlStructures, patterns); this.statements = new ExpressionTypingVisitorForStatements(this, writableScope, basic, controlStructures, patterns);
} }
else { else {
this.statements = null; this.statements = null;
} }
this.closures = new ClosureExpressionsTypingVisitor(globalContext, this); this.closures = new ClosureExpressionsTypingVisitor(this);
}
@Override
@NotNull
public ExpressionTypingComponents getComponents() {
return components;
} }
@NotNull @NotNull
@@ -100,7 +105,7 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
} }
private ExpressionTypingVisitorForStatements createStatementVisitor(ExpressionTypingContext context) { private ExpressionTypingVisitorForStatements createStatementVisitor(ExpressionTypingContext context) {
return new ExpressionTypingVisitorForStatements(globalContext, this, return new ExpressionTypingVisitorForStatements(this,
ExpressionTypingUtils.newWritableScopeImpl(context, "statement scope"), ExpressionTypingUtils.newWritableScopeImpl(context, "statement scope"),
basic, controlStructures, patterns); basic, controlStructures, patterns);
} }
@@ -20,7 +20,6 @@ import com.google.common.collect.Sets;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
@@ -55,21 +54,18 @@ import static org.jetbrains.jet.lang.types.TypeUtils.noExpectedType;
@SuppressWarnings("SuspiciousMethodCalls") @SuppressWarnings("SuspiciousMethodCalls")
public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisitor { public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisitor {
private final GlobalContext globalContext;
private final WritableScope scope; private final WritableScope scope;
private final BasicExpressionTypingVisitor basic; private final BasicExpressionTypingVisitor basic;
private final ControlStructureTypingVisitor controlStructures; private final ControlStructureTypingVisitor controlStructures;
private final PatternMatchingTypingVisitor patterns; private final PatternMatchingTypingVisitor patterns;
public ExpressionTypingVisitorForStatements( public ExpressionTypingVisitorForStatements(
@NotNull GlobalContext globalContext,
@NotNull ExpressionTypingInternals facade, @NotNull ExpressionTypingInternals facade,
@NotNull WritableScope scope, @NotNull WritableScope scope,
BasicExpressionTypingVisitor basic, BasicExpressionTypingVisitor basic,
@NotNull ControlStructureTypingVisitor controlStructures, @NotNull ControlStructureTypingVisitor controlStructures,
@NotNull PatternMatchingTypingVisitor patterns) { @NotNull PatternMatchingTypingVisitor patterns) {
super(facade); super(facade);
this.globalContext = globalContext;
this.scope = scope; this.scope = scope;
this.basic = basic; this.basic = basic;
this.controlStructures = controlStructures; this.controlStructures = controlStructures;
@@ -93,7 +89,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
@Override @Override
public JetTypeInfo visitObjectDeclaration(@NotNull JetObjectDeclaration declaration, ExpressionTypingContext context) { public JetTypeInfo visitObjectDeclaration(@NotNull JetObjectDeclaration declaration, ExpressionTypingContext context) {
TopDownAnalyzer.processClassOrObject( TopDownAnalyzer.processClassOrObject(
globalContext, components.globalContext,
scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), declaration); scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), declaration);
return DataFlowUtils.checkStatementType(declaration, context, context.dataFlowInfo); return DataFlowUtils.checkStatementType(declaration, context, context.dataFlowInfo);
} }
@@ -118,7 +114,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
JetExpression delegateExpression = property.getDelegateExpression(); JetExpression delegateExpression = property.getDelegateExpression();
if (delegateExpression != null) { if (delegateExpression != null) {
context.expressionTypingServices.getTypeInfo(delegateExpression, context); components.expressionTypingServices.getTypeInfo(delegateExpression, context);
context.trace.report(LOCAL_VARIABLE_WITH_DELEGATE.on(property.getDelegate())); context.trace.report(LOCAL_VARIABLE_WITH_DELEGATE.on(property.getDelegate()));
} }
@@ -126,7 +122,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
AnnotationResolver.reportUnsupportedAnnotationForTypeParameter(typeParameter, context.trace); AnnotationResolver.reportUnsupportedAnnotationForTypeParameter(typeParameter, context.trace);
} }
VariableDescriptor propertyDescriptor = context.expressionTypingServices.getDescriptorResolver(). VariableDescriptor propertyDescriptor = components.expressionTypingServices.getDescriptorResolver().
resolveLocalVariableDescriptor(scope, property, context.dataFlowInfo, context.trace); resolveLocalVariableDescriptor(scope, property, context.dataFlowInfo, context.trace);
JetExpression initializer = property.getInitializer(); JetExpression initializer = property.getInitializer();
DataFlowInfo dataFlowInfo = context.dataFlowInfo; DataFlowInfo dataFlowInfo = context.dataFlowInfo;
@@ -150,7 +146,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
@Override @Override
public JetTypeInfo visitMultiDeclaration(@NotNull JetMultiDeclaration multiDeclaration, ExpressionTypingContext context) { public JetTypeInfo visitMultiDeclaration(@NotNull JetMultiDeclaration multiDeclaration, ExpressionTypingContext context) {
context.expressionTypingServices.getAnnotationResolver().resolveAnnotationsWithArguments( components.expressionTypingServices.getAnnotationResolver().resolveAnnotationsWithArguments(
scope, multiDeclaration.getModifierList(), context.trace); scope, multiDeclaration.getModifierList(), context.trace);
JetExpression initializer = multiDeclaration.getInitializer(); JetExpression initializer = multiDeclaration.getInitializer();
@@ -164,21 +160,21 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
if (expressionReceiver == null) { if (expressionReceiver == null) {
return JetTypeInfo.create(null, dataFlowInfo); return JetTypeInfo.create(null, dataFlowInfo);
} }
ExpressionTypingUtils.defineLocalVariablesFromMultiDeclaration(scope, multiDeclaration, expressionReceiver, initializer, context); components.expressionTypingUtils.defineLocalVariablesFromMultiDeclaration(scope, multiDeclaration, expressionReceiver, initializer, context);
return DataFlowUtils.checkStatementType(multiDeclaration, context, dataFlowInfo); return DataFlowUtils.checkStatementType(multiDeclaration, context, dataFlowInfo);
} }
@Override @Override
public JetTypeInfo visitNamedFunction(@NotNull JetNamedFunction function, ExpressionTypingContext context) { public JetTypeInfo visitNamedFunction(@NotNull JetNamedFunction function, ExpressionTypingContext context) {
SimpleFunctionDescriptor functionDescriptor = context.expressionTypingServices.getDescriptorResolver(). SimpleFunctionDescriptor functionDescriptor = components.expressionTypingServices.getDescriptorResolver().
resolveFunctionDescriptorWithAnnotationArguments( resolveFunctionDescriptorWithAnnotationArguments(
scope.getContainingDeclaration(), scope, function, context.trace, context.dataFlowInfo); scope.getContainingDeclaration(), scope, function, context.trace, context.dataFlowInfo);
scope.addFunctionDescriptor(functionDescriptor); scope.addFunctionDescriptor(functionDescriptor);
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace); JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace);
context.expressionTypingServices.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, context.dataFlowInfo, null, context.trace); components.expressionTypingServices.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, context.dataFlowInfo, null, context.trace);
context.expressionTypingServices.resolveValueParameters(function.getValueParameters(), functionDescriptor.getValueParameters(), components.expressionTypingServices.resolveValueParameters(function.getValueParameters(), functionDescriptor.getValueParameters(),
scope, context.dataFlowInfo, context.trace, /* needCompleteAnalysis = */ true); scope, context.dataFlowInfo, context.trace, /* needCompleteAnalysis = */ true);
ModifiersChecker.create(context.trace).checkModifiersForLocalDeclaration(function); ModifiersChecker.create(context.trace).checkModifiersForLocalDeclaration(function);
@@ -188,7 +184,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
@Override @Override
public JetTypeInfo visitClass(@NotNull JetClass klass, ExpressionTypingContext context) { public JetTypeInfo visitClass(@NotNull JetClass klass, ExpressionTypingContext context) {
TopDownAnalyzer.processClassOrObject( TopDownAnalyzer.processClassOrObject(
globalContext, components.globalContext,
scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), klass); scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), klass);
return DataFlowUtils.checkStatementType(klass, context, context.dataFlowInfo); return DataFlowUtils.checkStatementType(klass, context, context.dataFlowInfo);
} }
@@ -255,8 +251,11 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
Name name = OperatorConventions.ASSIGNMENT_OPERATIONS.get(operationType); Name name = OperatorConventions.ASSIGNMENT_OPERATIONS.get(operationType);
TemporaryTraceAndCache temporaryForAssignmentOperation = TemporaryTraceAndCache.create( TemporaryTraceAndCache temporaryForAssignmentOperation = TemporaryTraceAndCache.create(
context, "trace to check assignment operation like '+=' for", expression); context, "trace to check assignment operation like '+=' for", expression);
OverloadResolutionResults<FunctionDescriptor> assignmentOperationDescriptors = BasicExpressionTypingVisitor.getResolutionResultsForBinaryCall( OverloadResolutionResults<FunctionDescriptor> assignmentOperationDescriptors =
scope, name, context.replaceTraceAndCache(temporaryForAssignmentOperation), expression, receiver); components.callResolver.resolveBinaryCall(
context.replaceTraceAndCache(temporaryForAssignmentOperation).replaceScope(scope),
receiver, expression, name
);
JetType assignmentOperationType = OverloadResolutionResultsUtil.getResultingType(assignmentOperationDescriptors, JetType assignmentOperationType = OverloadResolutionResultsUtil.getResultingType(assignmentOperationDescriptors,
context.contextDependency); context.contextDependency);
@@ -264,8 +263,10 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
Name counterpartName = OperatorConventions.BINARY_OPERATION_NAMES.get(OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(operationType)); Name counterpartName = OperatorConventions.BINARY_OPERATION_NAMES.get(OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(operationType));
TemporaryTraceAndCache temporaryForBinaryOperation = TemporaryTraceAndCache.create( TemporaryTraceAndCache temporaryForBinaryOperation = TemporaryTraceAndCache.create(
context, "trace to check binary operation like '+' for", expression); context, "trace to check binary operation like '+' for", expression);
OverloadResolutionResults<FunctionDescriptor> binaryOperationDescriptors = BasicExpressionTypingVisitor.getResolutionResultsForBinaryCall( OverloadResolutionResults<FunctionDescriptor> binaryOperationDescriptors = components.callResolver.resolveBinaryCall(
scope, counterpartName, context.replaceTraceAndCache(temporaryForBinaryOperation), expression, receiver); context.replaceTraceAndCache(temporaryForBinaryOperation).replaceScope(scope),
receiver, expression, counterpartName
);
JetType binaryOperationType = OverloadResolutionResultsUtil.getResultingType(binaryOperationDescriptors, context.contextDependency); JetType binaryOperationType = OverloadResolutionResultsUtil.getResultingType(binaryOperationDescriptors, context.contextDependency);
JetType type = assignmentOperationType != null ? assignmentOperationType : binaryOperationType; JetType type = assignmentOperationType != null ? assignmentOperationType : binaryOperationType;
@@ -308,7 +309,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
ExpressionTypingContext context = ExpressionTypingContext context =
contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(scope).replaceContextDependency(INDEPENDENT); contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(scope).replaceContextDependency(INDEPENDENT);
JetExpression leftOperand = expression.getLeft(); JetExpression leftOperand = expression.getLeft();
JetExpression left = context.expressionTypingServices.deparenthesizeWithTypeResolution(leftOperand, context); JetExpression left = components.expressionTypingServices.deparenthesizeWithTypeResolution(leftOperand, context);
JetExpression right = expression.getRight(); JetExpression right = expression.getRight();
if (left instanceof JetArrayAccessExpression) { if (left instanceof JetArrayAccessExpression) {
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left; JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left;
@@ -377,7 +378,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
@Override @Override
public JetTypeInfo visitBlockExpression(@NotNull JetBlockExpression expression, ExpressionTypingContext context) { public JetTypeInfo visitBlockExpression(@NotNull JetBlockExpression expression, ExpressionTypingContext context) {
return BasicExpressionTypingVisitor.visitBlockExpression(expression, context, true); return components.expressionTypingServices.getBlockReturnedType(expression, context, true);
} }
@Override @Override
@@ -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<Call, OverloadResolutionResults<FunctionDescriptor>> calls =
expressionTypingUtils.makeAndResolveFakeCall(loopRange, context, Collections.<JetExpression>emptyList(), iterator);
Call iteratorCall = calls.getFirst();
OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResults = calls.getSecond();
if (iteratorResolutionResults.isSuccess()) {
ResolvedCall<FunctionDescriptor> 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<JetExpression, JetType> ambiguity,
@NotNull DiagnosticFactory1<JetExpression, JetType> missing,
@NotNull DiagnosticFactory1<JetExpression, JetType> noneApplicable,
@NotNull WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> resolvedCallKey
) {
OverloadResolutionResults<FunctionDescriptor> 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<FunctionDescriptor> resolvedCall = nextResolutionResults.getResultingCall();
context.trace.record(resolvedCallKey, loopRangeExpression, resolvedCall);
return resolvedCall.getResultingDescriptor().getReturnType();
}
return null;
}
}
@@ -142,7 +142,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
ExpressionTypingContext newContext = contextWithExpectedType ExpressionTypingContext newContext = contextWithExpectedType
.replaceScope(scopeToExtend).replaceDataFlowInfo(newDataFlowInfo).replaceContextDependency(INDEPENDENT); .replaceScope(scopeToExtend).replaceDataFlowInfo(newDataFlowInfo).replaceContextDependency(INDEPENDENT);
CoercionStrategy coercionStrategy = isStatement ? CoercionStrategy.COERCION_TO_UNIT : CoercionStrategy.NO_COERCION; 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); scopeToExtend, Collections.singletonList(bodyExpression), coercionStrategy, newContext, context.trace);
JetType type = typeInfo.getType(); JetType type = typeInfo.getType();
if (type != null) { if (type != null) {
@@ -278,7 +278,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
return result; return result;
} }
private static DataFlowInfos checkTypeForIs( private DataFlowInfos checkTypeForIs(
ExpressionTypingContext context, ExpressionTypingContext context,
JetType subjectType, JetType subjectType,
JetTypeReference typeReferenceAfterIs, JetTypeReference typeReferenceAfterIs,
@@ -288,7 +288,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
return noChange(context); return noChange(context);
} }
TypeResolutionContext typeResolutionContext = new TypeResolutionContext(context.scope, context.trace, true, /*allowBareTypes=*/ true); 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); JetType type = TypeReconstructionUtil.reconstructBareType(typeReferenceAfterIs, possiblyBareTarget, subjectType, context.trace);
if (!subjectType.isNullable() && type.isNullable()) { if (!subjectType.isNullable() && type.isNullable()) {
JetTypeElement element = typeReferenceAfterIs.getTypeElement(); JetTypeElement element = typeReferenceAfterIs.getTypeElement();
@@ -21,6 +21,7 @@ import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap; import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; 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.lang.resolve.TypeResolver;
import org.jetbrains.jet.context.GlobalContext; import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.storage.StorageManager; 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.ArgumentTypeResolver;
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver; import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; 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.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider; import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
@@ -44,6 +48,7 @@ public class InjectorForTests {
private final PlatformToKotlinClassMap platformToKotlinClassMap; private final PlatformToKotlinClassMap platformToKotlinClassMap;
private final DescriptorResolver descriptorResolver; private final DescriptorResolver descriptorResolver;
private final ExpressionTypingServices expressionTypingServices; private final ExpressionTypingServices expressionTypingServices;
private final ExpressionTypingUtils expressionTypingUtils;
private final TypeResolver typeResolver; private final TypeResolver typeResolver;
private final GlobalContext globalContext; private final GlobalContext globalContext;
private final StorageManager storageManager; private final StorageManager storageManager;
@@ -52,6 +57,9 @@ public class InjectorForTests {
private final ArgumentTypeResolver argumentTypeResolver; private final ArgumentTypeResolver argumentTypeResolver;
private final CandidateResolver candidateResolver; private final CandidateResolver candidateResolver;
private final DelegatedPropertyResolver delegatedPropertyResolver; private final DelegatedPropertyResolver delegatedPropertyResolver;
private final ExpressionTypingComponents expressionTypingComponents;
private final ControlStructureTypingUtils controlStructureTypingUtils;
private final ForLoopConventionsChecker forLoopConventionsChecker;
private final CallExpressionResolver callExpressionResolver; private final CallExpressionResolver callExpressionResolver;
private final CallResolverExtensionProvider callResolverExtensionProvider; private final CallResolverExtensionProvider callResolverExtensionProvider;
private final QualifiedExpressionResolver qualifiedExpressionResolver; private final QualifiedExpressionResolver qualifiedExpressionResolver;
@@ -64,15 +72,19 @@ public class InjectorForTests {
this.moduleDescriptor = moduleDescriptor; this.moduleDescriptor = moduleDescriptor;
this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap(); this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap();
this.descriptorResolver = new DescriptorResolver(); this.descriptorResolver = new DescriptorResolver();
this.globalContext = org.jetbrains.jet.context.ContextPackage.GlobalContext(); this.expressionTypingComponents = new ExpressionTypingComponents();
this.expressionTypingServices = new ExpressionTypingServices(globalContext, platformToKotlinClassMap); this.expressionTypingServices = new ExpressionTypingServices(expressionTypingComponents);
this.callResolver = new CallResolver();
this.expressionTypingUtils = new ExpressionTypingUtils(getExpressionTypingServices(), callResolver);
this.typeResolver = new TypeResolver(); this.typeResolver = new TypeResolver();
this.globalContext = org.jetbrains.jet.context.ContextPackage.GlobalContext();
this.storageManager = globalContext.getStorageManager(); this.storageManager = globalContext.getStorageManager();
this.annotationResolver = new AnnotationResolver(); this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver(); this.argumentTypeResolver = new ArgumentTypeResolver();
this.candidateResolver = new CandidateResolver(); this.candidateResolver = new CandidateResolver();
this.delegatedPropertyResolver = new DelegatedPropertyResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver();
this.controlStructureTypingUtils = new ControlStructureTypingUtils(getExpressionTypingServices());
this.forLoopConventionsChecker = new ForLoopConventionsChecker();
this.callExpressionResolver = new CallExpressionResolver(); this.callExpressionResolver = new CallExpressionResolver();
this.callResolverExtensionProvider = new CallResolverExtensionProvider(); this.callResolverExtensionProvider = new CallResolverExtensionProvider();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver(); this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
@@ -108,8 +120,21 @@ public class InjectorForTests {
candidateResolver.setArgumentTypeResolver(argumentTypeResolver); candidateResolver.setArgumentTypeResolver(argumentTypeResolver);
delegatedPropertyResolver.setCallResolver(callResolver);
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); 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); callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
} }
@@ -126,6 +151,10 @@ public class InjectorForTests {
return this.expressionTypingServices; return this.expressionTypingServices;
} }
public ExpressionTypingUtils getExpressionTypingUtils() {
return this.expressionTypingUtils;
}
public TypeResolver getTypeResolver() { public TypeResolver getTypeResolver() {
return this.typeResolver; return this.typeResolver;
} }
@@ -46,7 +46,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import static com.intellij.testFramework.UsefulTestCase.assertInstanceOf; import static com.intellij.testFramework.UsefulTestCase.assertInstanceOf;
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.resolveFakeCall;
public class JetExpectedResolveDataUtil { public class JetExpectedResolveDataUtil {
private JetExpectedResolveDataUtil() { private JetExpectedResolveDataUtil() {
@@ -131,13 +130,14 @@ public class JetExpectedResolveDataUtil {
JetType... parameterTypes JetType... parameterTypes
) { ) {
ModuleDescriptor emptyModule = JetTestUtils.createEmptyModule(); 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( ExpressionTypingContext context = ExpressionTypingContext.newContext(
expressionTypingServices, new BindingTraceContext(), classDescriptor.getDefaultType().getMemberScope(), expressionTypingServices, new BindingTraceContext(), classDescriptor.getDefaultType().getMemberScope(),
DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE); DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE);
OverloadResolutionResults<FunctionDescriptor> functions = resolveFakeCall( OverloadResolutionResults<FunctionDescriptor> functions = injector.getExpressionTypingUtils().resolveFakeCall(
context, ReceiverValue.NO_RECEIVER, Name.identifier(name), parameterTypes); context, ReceiverValue.NO_RECEIVER, Name.identifier(name), parameterTypes);
for (ResolvedCall<? extends FunctionDescriptor> resolvedCall : functions.getResultingCalls()) { for (ResolvedCall<? extends FunctionDescriptor> resolvedCall : functions.getResultingCalls()) {
@@ -19,13 +19,11 @@ package org.jetbrains.jet.generators.injectors
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.jet.context.GlobalContext import org.jetbrains.jet.context.GlobalContext
import org.jetbrains.jet.context.GlobalContextImpl 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.ModuleDescriptor
import org.jetbrains.jet.lang.descriptors.ModuleDescriptorImpl import org.jetbrains.jet.lang.descriptors.ModuleDescriptorImpl
import org.jetbrains.jet.lang.resolve.* import org.jetbrains.jet.lang.resolve.*
import org.jetbrains.jet.lang.resolve.java.JavaClassFinderImpl import org.jetbrains.jet.lang.resolve.java.JavaClassFinderImpl
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver 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.java.resolver.*
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession 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.DependencyClassByQualifiedNameResolverDummyImpl
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices
import org.jetbrains.jet.di.* 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. // NOTE: After making changes, you need to re-generate the injectors.
// To do that, you can run main in this file. // To do that, you can run main in this file.
@@ -168,6 +167,7 @@ private fun generatorForMacro() =
parameter(javaClass<ModuleDescriptor>(), useAsContext = true) parameter(javaClass<ModuleDescriptor>(), useAsContext = true)
publicField(javaClass<ExpressionTypingServices>()) publicField(javaClass<ExpressionTypingServices>())
publicField(javaClass<ExpressionTypingComponents>())
field(javaClass<GlobalContext>(), useAsContext = true, field(javaClass<GlobalContext>(), useAsContext = true,
init = GivenExpression("org.jetbrains.jet.context.ContextPackage.GlobalContext()")) init = GivenExpression("org.jetbrains.jet.context.ContextPackage.GlobalContext()"))
@@ -181,6 +181,7 @@ private fun generatorForTests() =
publicFields( publicFields(
javaClass<DescriptorResolver>(), javaClass<DescriptorResolver>(),
javaClass<ExpressionTypingServices>(), javaClass<ExpressionTypingServices>(),
javaClass<ExpressionTypingUtils>(),
javaClass<TypeResolver>() javaClass<TypeResolver>()
) )
@@ -36,7 +36,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; 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.codeInsight.TipsManager;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies; import org.jetbrains.jet.plugin.project.ResolveSessionForBodies;
@@ -68,14 +68,14 @@ public abstract class BaseJetVariableMacro extends Macro {
return null; return null;
} }
ExpressionTypingServices callResolverContext = ExpressionTypingComponents components =
new InjectorForMacros(project, resolveSession.getModuleDescriptor()).getExpressionTypingServices(); new InjectorForMacros(project, resolveSession.getModuleDescriptor()).getExpressionTypingComponents();
List<VariableDescriptor> filteredDescriptors = new ArrayList<VariableDescriptor>(); List<VariableDescriptor> filteredDescriptors = new ArrayList<VariableDescriptor>();
for (DeclarationDescriptor declarationDescriptor : scope.getAllDescriptors()) { for (DeclarationDescriptor declarationDescriptor : scope.getAllDescriptors()) {
if (declarationDescriptor instanceof VariableDescriptor) { if (declarationDescriptor instanceof VariableDescriptor) {
VariableDescriptor variableDescriptor = (VariableDescriptor) declarationDescriptor; VariableDescriptor variableDescriptor = (VariableDescriptor) declarationDescriptor;
if (isSuitable(variableDescriptor, scope, project, callResolverContext)) { if (isSuitable(variableDescriptor, scope, project, components)) {
filteredDescriptors.add(variableDescriptor); filteredDescriptors.add(variableDescriptor);
} }
} }
@@ -94,7 +94,12 @@ public abstract class BaseJetVariableMacro extends Macro {
return declarations.toArray(new JetNamedDeclaration[declarations.size()]); 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 @Nullable
private static JetExpression findContextExpression(PsiFile psiFile, int startOffset) { private static JetExpression findContextExpression(PsiFile psiFile, int startOffset) {
@@ -20,7 +20,7 @@ import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; 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; import org.jetbrains.jet.plugin.JetBundle;
public class JetAnyVariableMacro extends BaseJetVariableMacro { public class JetAnyVariableMacro extends BaseJetVariableMacro {
@@ -35,7 +35,7 @@ public class JetAnyVariableMacro extends BaseJetVariableMacro {
} }
@Override @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; return true;
} }
} }
@@ -20,8 +20,7 @@ import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; 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.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.JetBundle;
public class JetIterableVariableMacro extends BaseJetVariableMacro { public class JetIterableVariableMacro extends BaseJetVariableMacro {
@@ -37,7 +36,12 @@ public class JetIterableVariableMacro extends BaseJetVariableMacro {
} }
@Override @Override
protected boolean isSuitable(@NotNull VariableDescriptor variableDescriptor, @NotNull JetScope scope, @NotNull Project project, ExpressionTypingServices callResolverContext) { protected boolean isSuitable(
return ExpressionTypingUtils.isVariableIterable(callResolverContext, project, variableDescriptor, scope); @NotNull VariableDescriptor variableDescriptor,
@NotNull JetScope scope,
@NotNull Project project,
@NotNull ExpressionTypingComponents components
) {
return components.getForLoopConventionsChecker().isVariableIterable(variableDescriptor, scope);
} }
} }
@@ -20,7 +20,7 @@ import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; 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; import org.jetbrains.jet.plugin.JetBundle;
public class JetSuggestVariableNameMacro extends BaseJetVariableMacro { public class JetSuggestVariableNameMacro extends BaseJetVariableMacro {
@@ -39,7 +39,7 @@ public class JetSuggestVariableNameMacro extends BaseJetVariableMacro {
@NotNull VariableDescriptor variableDescriptor, @NotNull VariableDescriptor variableDescriptor,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull Project project, @NotNull Project project,
ExpressionTypingServices callResolverContext @NotNull ExpressionTypingComponents components
) { ) {
return variableDescriptor.getType().isNullable(); return variableDescriptor.getType().isNullable();
} }
@@ -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.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; 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.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver; import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
@@ -71,6 +75,10 @@ public class InjectorForTopDownAnalyzerForJs {
private final CallResolver callResolver; private final CallResolver callResolver;
private final ArgumentTypeResolver argumentTypeResolver; private final ArgumentTypeResolver argumentTypeResolver;
private final ExpressionTypingServices expressionTypingServices; 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 CallExpressionResolver callExpressionResolver;
private final DescriptorResolver descriptorResolver; private final DescriptorResolver descriptorResolver;
private final DelegatedPropertyResolver delegatedPropertyResolver; private final DelegatedPropertyResolver delegatedPropertyResolver;
@@ -110,7 +118,11 @@ public class InjectorForTopDownAnalyzerForJs {
this.annotationResolver = new AnnotationResolver(); this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver(); this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver(); 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.callExpressionResolver = new CallExpressionResolver();
this.descriptorResolver = new DescriptorResolver(); this.descriptorResolver = new DescriptorResolver();
this.delegatedPropertyResolver = new DelegatedPropertyResolver(); this.delegatedPropertyResolver = new DelegatedPropertyResolver();
@@ -174,6 +186,18 @@ public class InjectorForTopDownAnalyzerForJs {
expressionTypingServices.setProject(project); expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver); 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); callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setAnnotationResolver(annotationResolver); descriptorResolver.setAnnotationResolver(annotationResolver);
@@ -182,6 +206,7 @@ public class InjectorForTopDownAnalyzerForJs {
descriptorResolver.setStorageManager(storageManager); descriptorResolver.setStorageManager(storageManager);
descriptorResolver.setTypeResolver(typeResolver); descriptorResolver.setTypeResolver(typeResolver);
delegatedPropertyResolver.setCallResolver(callResolver);
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices); delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver); typeResolver.setAnnotationResolver(annotationResolver);