added CandidateResolver
(that took some methods from CallResolver)
This commit is contained in:
+7
-1
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
|
|||||||
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
|
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
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.CandidateResolver;
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||||
@@ -83,6 +84,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
private DeclarationResolver declarationResolver;
|
private DeclarationResolver declarationResolver;
|
||||||
private AnnotationResolver annotationResolver;
|
private AnnotationResolver annotationResolver;
|
||||||
private CallResolver callResolver;
|
private CallResolver callResolver;
|
||||||
|
private CandidateResolver candidateResolver;
|
||||||
private ExpressionTypingServices expressionTypingServices;
|
private ExpressionTypingServices expressionTypingServices;
|
||||||
private TypeResolver typeResolver;
|
private TypeResolver typeResolver;
|
||||||
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||||
@@ -132,6 +134,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
this.declarationResolver = new DeclarationResolver();
|
this.declarationResolver = new DeclarationResolver();
|
||||||
this.annotationResolver = new AnnotationResolver();
|
this.annotationResolver = new AnnotationResolver();
|
||||||
this.callResolver = new CallResolver();
|
this.callResolver = new CallResolver();
|
||||||
|
this.candidateResolver = new CandidateResolver();
|
||||||
this.expressionTypingServices = new ExpressionTypingServices();
|
this.expressionTypingServices = new ExpressionTypingServices();
|
||||||
this.typeResolver = new TypeResolver();
|
this.typeResolver = new TypeResolver();
|
||||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||||
@@ -216,11 +219,14 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
annotationResolver.setCallResolver(callResolver);
|
annotationResolver.setCallResolver(callResolver);
|
||||||
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
|
||||||
callResolver.setDescriptorResolver(descriptorResolver);
|
callResolver.setCandidateResolver(candidateResolver);
|
||||||
callResolver.setExpressionTypingServices(expressionTypingServices);
|
callResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
||||||
callResolver.setTypeResolver(typeResolver);
|
callResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
|
candidateResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
candidateResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
expressionTypingServices.setCallResolver(callResolver);
|
expressionTypingServices.setCallResolver(callResolver);
|
||||||
expressionTypingServices.setDescriptorResolver(descriptorResolver);
|
expressionTypingServices.setDescriptorResolver(descriptorResolver);
|
||||||
expressionTypingServices.setProject(project);
|
expressionTypingServices.setProject(project);
|
||||||
|
|||||||
@@ -24,9 +24,10 @@ import org.jetbrains.jet.lang.resolve.BindingTrace;
|
|||||||
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
|
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
|
||||||
import org.jetbrains.jet.lang.ModuleConfiguration;
|
import org.jetbrains.jet.lang.ModuleConfiguration;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
|
||||||
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
|
||||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionResultsHandler;
|
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionResultsHandler;
|
||||||
@@ -48,9 +49,10 @@ public class InjectorForBodyResolve {
|
|||||||
private final BodiesResolveContext bodiesResolveContext;
|
private final BodiesResolveContext bodiesResolveContext;
|
||||||
private final ModuleConfiguration moduleConfiguration;
|
private final ModuleConfiguration moduleConfiguration;
|
||||||
private CallResolver callResolver;
|
private CallResolver callResolver;
|
||||||
|
private CandidateResolver candidateResolver;
|
||||||
|
private ExpressionTypingServices expressionTypingServices;
|
||||||
private DescriptorResolver descriptorResolver;
|
private DescriptorResolver descriptorResolver;
|
||||||
private AnnotationResolver annotationResolver;
|
private AnnotationResolver annotationResolver;
|
||||||
private ExpressionTypingServices expressionTypingServices;
|
|
||||||
private TypeResolver typeResolver;
|
private TypeResolver typeResolver;
|
||||||
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||||
private ResolutionResultsHandler resolutionResultsHandler;
|
private ResolutionResultsHandler resolutionResultsHandler;
|
||||||
@@ -74,9 +76,10 @@ public class InjectorForBodyResolve {
|
|||||||
this.bodiesResolveContext = bodiesResolveContext;
|
this.bodiesResolveContext = bodiesResolveContext;
|
||||||
this.moduleConfiguration = moduleConfiguration;
|
this.moduleConfiguration = moduleConfiguration;
|
||||||
this.callResolver = new CallResolver();
|
this.callResolver = new CallResolver();
|
||||||
|
this.candidateResolver = new CandidateResolver();
|
||||||
|
this.expressionTypingServices = new ExpressionTypingServices();
|
||||||
this.descriptorResolver = new DescriptorResolver();
|
this.descriptorResolver = new DescriptorResolver();
|
||||||
this.annotationResolver = new AnnotationResolver();
|
this.annotationResolver = new AnnotationResolver();
|
||||||
this.expressionTypingServices = new ExpressionTypingServices();
|
|
||||||
this.typeResolver = new TypeResolver();
|
this.typeResolver = new TypeResolver();
|
||||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||||
this.resolutionResultsHandler = new ResolutionResultsHandler();
|
this.resolutionResultsHandler = new ResolutionResultsHandler();
|
||||||
@@ -96,11 +99,19 @@ public class InjectorForBodyResolve {
|
|||||||
this.bodyResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
this.bodyResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
||||||
this.bodyResolver.setTrace(bindingTrace);
|
this.bodyResolver.setTrace(bindingTrace);
|
||||||
|
|
||||||
callResolver.setDescriptorResolver(descriptorResolver);
|
callResolver.setCandidateResolver(candidateResolver);
|
||||||
callResolver.setExpressionTypingServices(expressionTypingServices);
|
callResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
||||||
callResolver.setTypeResolver(typeResolver);
|
callResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
|
candidateResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
candidateResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
|
expressionTypingServices.setCallResolver(callResolver);
|
||||||
|
expressionTypingServices.setDescriptorResolver(descriptorResolver);
|
||||||
|
expressionTypingServices.setProject(project);
|
||||||
|
expressionTypingServices.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
descriptorResolver.setAnnotationResolver(annotationResolver);
|
descriptorResolver.setAnnotationResolver(annotationResolver);
|
||||||
descriptorResolver.setExpressionTypingServices(expressionTypingServices);
|
descriptorResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
descriptorResolver.setTypeResolver(typeResolver);
|
descriptorResolver.setTypeResolver(typeResolver);
|
||||||
@@ -108,11 +119,6 @@ public class InjectorForBodyResolve {
|
|||||||
annotationResolver.setCallResolver(callResolver);
|
annotationResolver.setCallResolver(callResolver);
|
||||||
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
|
||||||
expressionTypingServices.setCallResolver(callResolver);
|
|
||||||
expressionTypingServices.setDescriptorResolver(descriptorResolver);
|
|
||||||
expressionTypingServices.setProject(project);
|
|
||||||
expressionTypingServices.setTypeResolver(typeResolver);
|
|
||||||
|
|
||||||
typeResolver.setAnnotationResolver(annotationResolver);
|
typeResolver.setAnnotationResolver(annotationResolver);
|
||||||
typeResolver.setDescriptorResolver(descriptorResolver);
|
typeResolver.setDescriptorResolver(descriptorResolver);
|
||||||
typeResolver.setModuleConfiguration(moduleConfiguration);
|
typeResolver.setModuleConfiguration(moduleConfiguration);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider;
|
|||||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
|
||||||
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.results.OverloadingConflictResolver;
|
import org.jetbrains.jet.lang.resolve.calls.results.OverloadingConflictResolver;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -47,6 +48,7 @@ public class InjectorForLazyResolve {
|
|||||||
private AnnotationResolver annotationResolver;
|
private AnnotationResolver annotationResolver;
|
||||||
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||||
private CallResolver callResolver;
|
private CallResolver callResolver;
|
||||||
|
private CandidateResolver candidateResolver;
|
||||||
private ResolutionResultsHandler resolutionResultsHandler;
|
private ResolutionResultsHandler resolutionResultsHandler;
|
||||||
private OverloadingConflictResolver overloadingConflictResolver;
|
private OverloadingConflictResolver overloadingConflictResolver;
|
||||||
|
|
||||||
@@ -67,6 +69,7 @@ public class InjectorForLazyResolve {
|
|||||||
this.annotationResolver = new AnnotationResolver();
|
this.annotationResolver = new AnnotationResolver();
|
||||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||||
this.callResolver = new CallResolver();
|
this.callResolver = new CallResolver();
|
||||||
|
this.candidateResolver = new CandidateResolver();
|
||||||
this.resolutionResultsHandler = new ResolutionResultsHandler();
|
this.resolutionResultsHandler = new ResolutionResultsHandler();
|
||||||
this.overloadingConflictResolver = new OverloadingConflictResolver();
|
this.overloadingConflictResolver = new OverloadingConflictResolver();
|
||||||
|
|
||||||
@@ -87,11 +90,14 @@ public class InjectorForLazyResolve {
|
|||||||
this.annotationResolver.setCallResolver(callResolver);
|
this.annotationResolver.setCallResolver(callResolver);
|
||||||
this.annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
this.annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
|
||||||
callResolver.setDescriptorResolver(descriptorResolver);
|
callResolver.setCandidateResolver(candidateResolver);
|
||||||
callResolver.setExpressionTypingServices(expressionTypingServices);
|
callResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
||||||
callResolver.setTypeResolver(typeResolver);
|
callResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
|
candidateResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
candidateResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
resolutionResultsHandler.setOverloadingConflictResolver(overloadingConflictResolver);
|
resolutionResultsHandler.setOverloadingConflictResolver(overloadingConflictResolver);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,10 @@ import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
|||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import org.jetbrains.jet.lang.ModuleConfiguration;
|
import org.jetbrains.jet.lang.ModuleConfiguration;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
|
||||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||||
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.results.OverloadingConflictResolver;
|
import org.jetbrains.jet.lang.resolve.calls.results.OverloadingConflictResolver;
|
||||||
@@ -37,9 +38,10 @@ public class InjectorForMacros {
|
|||||||
private final Project project;
|
private final Project project;
|
||||||
private final ModuleConfiguration moduleConfiguration;
|
private final ModuleConfiguration moduleConfiguration;
|
||||||
private CallResolver callResolver;
|
private CallResolver callResolver;
|
||||||
private DescriptorResolver descriptorResolver;
|
private CandidateResolver candidateResolver;
|
||||||
private AnnotationResolver annotationResolver;
|
|
||||||
private TypeResolver typeResolver;
|
private TypeResolver typeResolver;
|
||||||
|
private AnnotationResolver annotationResolver;
|
||||||
|
private DescriptorResolver descriptorResolver;
|
||||||
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||||
private ResolutionResultsHandler resolutionResultsHandler;
|
private ResolutionResultsHandler resolutionResultsHandler;
|
||||||
private OverloadingConflictResolver overloadingConflictResolver;
|
private OverloadingConflictResolver overloadingConflictResolver;
|
||||||
@@ -52,9 +54,10 @@ public class InjectorForMacros {
|
|||||||
this.project = project;
|
this.project = project;
|
||||||
this.moduleConfiguration = moduleConfiguration;
|
this.moduleConfiguration = moduleConfiguration;
|
||||||
this.callResolver = new CallResolver();
|
this.callResolver = new CallResolver();
|
||||||
this.descriptorResolver = new DescriptorResolver();
|
this.candidateResolver = new CandidateResolver();
|
||||||
this.annotationResolver = new AnnotationResolver();
|
|
||||||
this.typeResolver = new TypeResolver();
|
this.typeResolver = new TypeResolver();
|
||||||
|
this.annotationResolver = new AnnotationResolver();
|
||||||
|
this.descriptorResolver = new DescriptorResolver();
|
||||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||||
this.resolutionResultsHandler = new ResolutionResultsHandler();
|
this.resolutionResultsHandler = new ResolutionResultsHandler();
|
||||||
this.overloadingConflictResolver = new OverloadingConflictResolver();
|
this.overloadingConflictResolver = new OverloadingConflictResolver();
|
||||||
@@ -64,23 +67,26 @@ public class InjectorForMacros {
|
|||||||
this.expressionTypingServices.setProject(project);
|
this.expressionTypingServices.setProject(project);
|
||||||
this.expressionTypingServices.setTypeResolver(typeResolver);
|
this.expressionTypingServices.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
callResolver.setDescriptorResolver(descriptorResolver);
|
callResolver.setCandidateResolver(candidateResolver);
|
||||||
callResolver.setExpressionTypingServices(expressionTypingServices);
|
callResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
||||||
callResolver.setTypeResolver(typeResolver);
|
callResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
descriptorResolver.setAnnotationResolver(annotationResolver);
|
candidateResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
descriptorResolver.setExpressionTypingServices(expressionTypingServices);
|
candidateResolver.setTypeResolver(typeResolver);
|
||||||
descriptorResolver.setTypeResolver(typeResolver);
|
|
||||||
|
|
||||||
annotationResolver.setCallResolver(callResolver);
|
|
||||||
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
|
||||||
|
|
||||||
typeResolver.setAnnotationResolver(annotationResolver);
|
typeResolver.setAnnotationResolver(annotationResolver);
|
||||||
typeResolver.setDescriptorResolver(descriptorResolver);
|
typeResolver.setDescriptorResolver(descriptorResolver);
|
||||||
typeResolver.setModuleConfiguration(moduleConfiguration);
|
typeResolver.setModuleConfiguration(moduleConfiguration);
|
||||||
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||||
|
|
||||||
|
annotationResolver.setCallResolver(callResolver);
|
||||||
|
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
|
||||||
|
descriptorResolver.setAnnotationResolver(annotationResolver);
|
||||||
|
descriptorResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
descriptorResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
resolutionResultsHandler.setOverloadingConflictResolver(overloadingConflictResolver);
|
resolutionResultsHandler.setOverloadingConflictResolver(overloadingConflictResolver);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
|
|||||||
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
|
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
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.CandidateResolver;
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||||
@@ -66,6 +67,7 @@ public class InjectorForTopDownAnalyzerBasic {
|
|||||||
private DeclarationResolver declarationResolver;
|
private DeclarationResolver declarationResolver;
|
||||||
private AnnotationResolver annotationResolver;
|
private AnnotationResolver annotationResolver;
|
||||||
private CallResolver callResolver;
|
private CallResolver callResolver;
|
||||||
|
private CandidateResolver candidateResolver;
|
||||||
private ExpressionTypingServices expressionTypingServices;
|
private ExpressionTypingServices expressionTypingServices;
|
||||||
private TypeResolver typeResolver;
|
private TypeResolver typeResolver;
|
||||||
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||||
@@ -101,6 +103,7 @@ public class InjectorForTopDownAnalyzerBasic {
|
|||||||
this.declarationResolver = new DeclarationResolver();
|
this.declarationResolver = new DeclarationResolver();
|
||||||
this.annotationResolver = new AnnotationResolver();
|
this.annotationResolver = new AnnotationResolver();
|
||||||
this.callResolver = new CallResolver();
|
this.callResolver = new CallResolver();
|
||||||
|
this.candidateResolver = new CandidateResolver();
|
||||||
this.expressionTypingServices = new ExpressionTypingServices();
|
this.expressionTypingServices = new ExpressionTypingServices();
|
||||||
this.typeResolver = new TypeResolver();
|
this.typeResolver = new TypeResolver();
|
||||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||||
@@ -159,11 +162,14 @@ public class InjectorForTopDownAnalyzerBasic {
|
|||||||
annotationResolver.setCallResolver(callResolver);
|
annotationResolver.setCallResolver(callResolver);
|
||||||
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
|
||||||
callResolver.setDescriptorResolver(descriptorResolver);
|
callResolver.setCandidateResolver(candidateResolver);
|
||||||
callResolver.setExpressionTypingServices(expressionTypingServices);
|
callResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
||||||
callResolver.setTypeResolver(typeResolver);
|
callResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
|
candidateResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
candidateResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
expressionTypingServices.setCallResolver(callResolver);
|
expressionTypingServices.setCallResolver(callResolver);
|
||||||
expressionTypingServices.setDescriptorResolver(descriptorResolver);
|
expressionTypingServices.setDescriptorResolver(descriptorResolver);
|
||||||
expressionTypingServices.setProject(project);
|
expressionTypingServices.setProject(project);
|
||||||
|
|||||||
@@ -16,28 +16,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.calls;
|
package org.jetbrains.jet.lang.resolve.calls;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
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.AutoCastReceiver;
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl;
|
|
||||||
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.autocasts.DataFlowValue;
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory;
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.inference.*;
|
|
||||||
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.model.ResolvedCallImpl;
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.results.*;
|
import org.jetbrains.jet.lang.resolve.calls.results.*;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.tasks.*;
|
import org.jetbrains.jet.lang.resolve.calls.tasks.*;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall;
|
import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall;
|
||||||
@@ -45,7 +35,6 @@ 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.ExpressionReceiver;
|
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
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;
|
||||||
@@ -61,7 +50,6 @@ import java.util.*;
|
|||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.*;
|
import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.calls.inference.InferenceErrorData.ExtendedInferenceErrorData;
|
|
||||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
||||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||||
|
|
||||||
@@ -78,7 +66,7 @@ public class CallResolver {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private TypeResolver typeResolver;
|
private TypeResolver typeResolver;
|
||||||
@NotNull
|
@NotNull
|
||||||
private DescriptorResolver descriptorResolver;
|
private CandidateResolver candidateResolver;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public void setResolutionResultsHandler(@NotNull ResolutionResultsHandler resolutionResultsHandler) {
|
public void setResolutionResultsHandler(@NotNull ResolutionResultsHandler resolutionResultsHandler) {
|
||||||
@@ -96,12 +84,10 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public void setDescriptorResolver(@NotNull DescriptorResolver descriptorResolver) {
|
public void setCandidateResolver(@NotNull CandidateResolver candidateResolver) {
|
||||||
this.descriptorResolver = descriptorResolver;
|
this.candidateResolver = candidateResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public OverloadResolutionResults<VariableDescriptor> resolveSimpleProperty(@NotNull BasicResolutionContext context) {
|
public OverloadResolutionResults<VariableDescriptor> resolveSimpleProperty(@NotNull BasicResolutionContext context) {
|
||||||
JetExpression calleeExpression = context.call.getCalleeExpression();
|
JetExpression calleeExpression = context.call.getCalleeExpression();
|
||||||
@@ -122,7 +108,8 @@ public class CallResolver {
|
|||||||
List<ResolutionTask<VariableDescriptor, VariableDescriptor>> prioritizedTasks =
|
List<ResolutionTask<VariableDescriptor, VariableDescriptor>> prioritizedTasks =
|
||||||
TaskPrioritizer.<VariableDescriptor, VariableDescriptor>computePrioritizedTasks(context, referencedName, nameExpression,
|
TaskPrioritizer.<VariableDescriptor, VariableDescriptor>computePrioritizedTasks(context, referencedName, nameExpression,
|
||||||
callableDescriptorCollectors);
|
callableDescriptorCollectors);
|
||||||
return doResolveCallOrGetCachedResults(RESOLUTION_RESULTS_FOR_PROPERTY, context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, nameExpression);
|
return doResolveCallOrGetCachedResults(RESOLUTION_RESULTS_FOR_PROPERTY, context, prioritizedTasks,
|
||||||
|
CallTransformer.PROPERTY_CALL_TRANSFORMER, nameExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -337,98 +324,17 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
completeTypeInferenceDependentOnExpectedTypeForCall(CallResolutionContext.create(context, tracing, resolvedCall), successful, failed);
|
candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall(
|
||||||
|
CallResolutionContext.create(context, tracing, resolvedCall), successful, failed);
|
||||||
}
|
}
|
||||||
OverloadResolutionResultsImpl<D> results = resolutionResultsHandler.computeResultAndReportErrors(context.trace, tracing, successful,
|
OverloadResolutionResultsImpl<D> results = resolutionResultsHandler.computeResultAndReportErrors(context.trace, tracing, successful,
|
||||||
failed);
|
failed);
|
||||||
if (!results.isSingleResult()) {
|
if (!results.isSingleResult()) {
|
||||||
checkTypesWithNoCallee(context);
|
candidateResolver.checkTypesWithNoCallee(context);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <D extends CallableDescriptor> void completeTypeInferenceDependentOnExpectedTypeForCall(
|
|
||||||
CallResolutionContext<D, D> context,
|
|
||||||
Set<ResolvedCallWithTrace<D>> successful,
|
|
||||||
Set<ResolvedCallWithTrace<D>> failed
|
|
||||||
) {
|
|
||||||
ResolvedCallImpl<D> resolvedCall = context.candidateCall;
|
|
||||||
assert resolvedCall.hasUnknownTypeParameters();
|
|
||||||
D descriptor = resolvedCall.getCandidateDescriptor();
|
|
||||||
ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem();
|
|
||||||
assert constraintSystem != null;
|
|
||||||
|
|
||||||
TypeSubstitutor substituteDontCare = ConstraintSystemWithPriorities
|
|
||||||
.makeConstantSubstitutor(resolvedCall.getCandidateDescriptor().getTypeParameters(), ConstraintSystemImpl.DONT_CARE);
|
|
||||||
|
|
||||||
// constraints for function literals
|
|
||||||
// Value parameters
|
|
||||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : resolvedCall.getValueArguments().entrySet()) {
|
|
||||||
ResolvedValueArgument resolvedValueArgument = entry.getValue();
|
|
||||||
ValueParameterDescriptor valueParameterDescriptor = entry.getKey();
|
|
||||||
|
|
||||||
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
|
|
||||||
if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue;
|
|
||||||
|
|
||||||
ConstraintSystem systemWithCurrentSubstitution = constraintSystem.copy();
|
|
||||||
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintSystem.getCurrentSubstitutor(),
|
|
||||||
systemWithCurrentSubstitution, context, null);
|
|
||||||
if (systemWithCurrentSubstitution.hasContradiction() || systemWithCurrentSubstitution.hasErrorInConstrainingTypes()) {
|
|
||||||
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintSystem, context, null);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
constraintSystem = systemWithCurrentSubstitution;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstraintSystem constraintSystemWithoutExpectedTypeConstraint = constraintSystem.copy();
|
|
||||||
constraintSystem.addSupertypeConstraint(descriptor.getReturnType(), context.expectedType,
|
|
||||||
ConstraintPosition.EXPECTED_TYPE_POSITION);
|
|
||||||
|
|
||||||
|
|
||||||
if (!constraintSystem.isSuccessful()) {
|
|
||||||
resolvedCall.setResultingSubstitutor(constraintSystemWithoutExpectedTypeConstraint.getResultingSubstitutor());
|
|
||||||
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()).argumentTypes;
|
|
||||||
JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
|
|
||||||
context.tracing.typeInferenceFailed(resolvedCall.getTrace(),
|
|
||||||
InferenceErrorData
|
|
||||||
.create(descriptor, constraintSystem, argumentTypes, receiverType,
|
|
||||||
context.expectedType),
|
|
||||||
constraintSystemWithoutExpectedTypeConstraint);
|
|
||||||
resolvedCall.addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR);
|
|
||||||
failed.add(resolvedCall);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor());
|
|
||||||
// Here we type check the arguments with inferred types expected
|
|
||||||
checkAllValueArguments(context);
|
|
||||||
|
|
||||||
checkBounds(resolvedCall, constraintSystem, resolvedCall.getTrace(), context.tracing);
|
|
||||||
resolvedCall.setHasUnknownTypeParameters(false);
|
|
||||||
if (resolvedCall.getStatus().isSuccess() || resolvedCall.getStatus() == ResolutionStatus.UNKNOWN_STATUS) {
|
|
||||||
resolvedCall.addStatus(ResolutionStatus.SUCCESS);
|
|
||||||
successful.add(resolvedCall);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
failed.add(resolvedCall);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private <D extends CallableDescriptor> void checkBounds(
|
|
||||||
@NotNull ResolvedCallImpl<D> call,
|
|
||||||
@NotNull ConstraintSystem constraintSystem,
|
|
||||||
@NotNull BindingTrace trace,
|
|
||||||
@NotNull TracingStrategy tracing
|
|
||||||
) {
|
|
||||||
for (TypeParameterDescriptor typeParameter : call.getCandidateDescriptor().getTypeParameters()) {
|
|
||||||
if (!ConstraintsUtil.checkUpperBoundIsSatisfied(constraintSystem, typeParameter)) {
|
|
||||||
tracing.upperBoundViolated(trace, InferenceErrorData.create(call.getCandidateDescriptor(), constraintSystem));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private <F extends CallableDescriptor> void cacheResults(@NotNull WritableSlice<CallKey, OverloadResolutionResults<F>> resolutionResultsSlice,
|
private <F extends CallableDescriptor> void cacheResults(@NotNull WritableSlice<CallKey, OverloadResolutionResults<F>> resolutionResultsSlice,
|
||||||
@NotNull BasicResolutionContext context, @NotNull OverloadResolutionResults<F> results,
|
@NotNull BasicResolutionContext context, @NotNull OverloadResolutionResults<F> results,
|
||||||
@NotNull DelegatingBindingTrace traceToResolveCall) {
|
@NotNull DelegatingBindingTrace traceToResolveCall) {
|
||||||
@@ -452,7 +358,7 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> checkArgumentTypesAndFail(BasicResolutionContext context) {
|
private <D extends CallableDescriptor> OverloadResolutionResults<D> checkArgumentTypesAndFail(BasicResolutionContext context) {
|
||||||
checkTypesWithNoCallee(context);
|
candidateResolver.checkTypesWithNoCallee(context);
|
||||||
return OverloadResolutionResultsImpl.nameNotFound();
|
return OverloadResolutionResultsImpl.nameNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,7 +412,7 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
context.trace.report(UNRESOLVED_REFERENCE.on(reference));
|
context.trace.report(UNRESOLVED_REFERENCE.on(reference));
|
||||||
checkTypesWithNoCallee(context);
|
candidateResolver.checkTypesWithNoCallee(context);
|
||||||
}
|
}
|
||||||
return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.<F>nameNotFound();
|
return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.<F>nameNotFound();
|
||||||
}
|
}
|
||||||
@@ -571,7 +477,7 @@ public class CallResolver {
|
|||||||
Collection<CallResolutionContext<D, F>> contexts = callTransformer.createCallContexts(resolutionCandidate, task, candidateTrace);
|
Collection<CallResolutionContext<D, F>> contexts = callTransformer.createCallContexts(resolutionCandidate, task, candidateTrace);
|
||||||
for (CallResolutionContext<D, F> context : contexts) {
|
for (CallResolutionContext<D, F> context : contexts) {
|
||||||
|
|
||||||
performResolutionForCandidateCall(context, task);
|
candidateResolver.performResolutionForCandidateCall(context, task);
|
||||||
|
|
||||||
/* important for 'variable as function case': temporary bind reference to descriptor (will be rewritten)
|
/* important for 'variable as function case': temporary bind reference to descriptor (will be rewritten)
|
||||||
to have a binding to variable while 'invoke' call resolve */
|
to have a binding to variable while 'invoke' call resolve */
|
||||||
@@ -614,443 +520,13 @@ public class CallResolver {
|
|||||||
successfulCandidates,
|
successfulCandidates,
|
||||||
failedCandidates);
|
failedCandidates);
|
||||||
if (!results.isSingleResult() && !results.isIncomplete()) {
|
if (!results.isSingleResult() && !results.isIncomplete()) {
|
||||||
checkTypesWithNoCallee(task.toBasic());
|
candidateResolver.checkTypesWithNoCallee(task.toBasic());
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <D extends CallableDescriptor, F extends D> void performResolutionForCandidateCall(@NotNull CallResolutionContext<D, F> context,
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@NotNull ResolutionTask<D, F> task) {
|
// to be removed
|
||||||
|
|
||||||
ProgressIndicatorProvider.checkCanceled();
|
|
||||||
|
|
||||||
ResolvedCallImpl<D> candidateCall = context.candidateCall;
|
|
||||||
D candidate = candidateCall.getCandidateDescriptor();
|
|
||||||
|
|
||||||
if (ErrorUtils.isError(candidate)) {
|
|
||||||
candidateCall.addStatus(SUCCESS);
|
|
||||||
checkTypesWithNoCallee(context.toBasic());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Visibilities.isVisible(candidate, context.scope.getContainingDeclaration())) {
|
|
||||||
candidateCall.addStatus(OTHER_ERROR);
|
|
||||||
context.tracing.invisibleMember(context.trace, candidate);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<ValueArgument> unmappedArguments = Sets.newLinkedHashSet();
|
|
||||||
ValueArgumentsToParametersMapper.Status
|
|
||||||
argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing,
|
|
||||||
candidateCall, unmappedArguments);
|
|
||||||
if (!argumentMappingStatus.isSuccess()) {
|
|
||||||
if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR) {
|
|
||||||
candidateCall.addStatus(STRONG_ERROR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
candidateCall.addStatus(OTHER_ERROR);
|
|
||||||
}
|
|
||||||
if ((argumentMappingStatus == ValueArgumentsToParametersMapper.Status.ERROR && candidate.getTypeParameters().isEmpty()) ||
|
|
||||||
argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR) {
|
|
||||||
checkTypesWithNoCallee(context.toBasic());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
checkUnmappedArgumentTypes(context.toBasic(), unmappedArguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<JetTypeProjection> jetTypeArguments = context.call.getTypeArguments();
|
|
||||||
if (jetTypeArguments.isEmpty()) {
|
|
||||||
if (!candidate.getTypeParameters().isEmpty()) {
|
|
||||||
ResolutionStatus status = inferTypeArguments(context);
|
|
||||||
candidateCall.addStatus(status);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
candidateCall.addStatus(checkAllValueArguments(context).status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Explicit type arguments passed
|
|
||||||
|
|
||||||
List<JetType> typeArguments = new ArrayList<JetType>();
|
|
||||||
for (JetTypeProjection projection : jetTypeArguments) {
|
|
||||||
if (projection.getProjectionKind() != JetProjectionKind.NONE) {
|
|
||||||
context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection));
|
|
||||||
}
|
|
||||||
JetTypeReference typeReference = projection.getTypeReference();
|
|
||||||
if (typeReference != null) {
|
|
||||||
typeArguments.add(typeResolver.resolveType(context.scope, typeReference, context.trace, true));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
typeArguments.add(ErrorUtils.createErrorType("Star projection in a call"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int expectedTypeArgumentCount = candidate.getTypeParameters().size();
|
|
||||||
if (expectedTypeArgumentCount == jetTypeArguments.size()) {
|
|
||||||
|
|
||||||
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, context.trace);
|
|
||||||
|
|
||||||
Map<TypeConstructor, TypeProjection>
|
|
||||||
substitutionContext = FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor)candidate, typeArguments);
|
|
||||||
candidateCall.setResultingSubstitutor(TypeSubstitutor.create(substitutionContext));
|
|
||||||
|
|
||||||
List<TypeParameterDescriptor> typeParameters = candidateCall.getCandidateDescriptor().getTypeParameters();
|
|
||||||
for (int i = 0; i < typeParameters.size(); i++) {
|
|
||||||
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
|
||||||
candidateCall.recordTypeArgument(typeParameterDescriptor, typeArguments.get(i));
|
|
||||||
}
|
|
||||||
candidateCall.addStatus(checkAllValueArguments(context).status);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
candidateCall.addStatus(OTHER_ERROR);
|
|
||||||
context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task.performAdvancedChecks(candidate, context.trace, context.tracing);
|
|
||||||
|
|
||||||
// 'super' cannot be passed as an argument, for receiver arguments expression typer does not track this
|
|
||||||
// See TaskPrioritizer for more
|
|
||||||
JetSuperExpression superExpression = TaskPrioritizer.getReceiverSuper(candidateCall.getReceiverArgument());
|
|
||||||
if (superExpression != null) {
|
|
||||||
context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(superExpression, superExpression.getText()));
|
|
||||||
candidateCall.addStatus(OTHER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
recordAutoCastIfNecessary(candidateCall.getReceiverArgument(), candidateCall.getTrace());
|
|
||||||
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
|
|
||||||
}
|
|
||||||
|
|
||||||
private <D extends CallableDescriptor, F extends D> ResolutionStatus inferTypeArguments(CallResolutionContext<D, F> context) {
|
|
||||||
ResolvedCallImpl<D> candidateCall = context.candidateCall;
|
|
||||||
final D candidate = candidateCall.getCandidateDescriptor();
|
|
||||||
|
|
||||||
ResolutionDebugInfo.Data debugInfo = context.trace.get(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement());
|
|
||||||
|
|
||||||
ConstraintSystemImpl constraintsSystem = new ConstraintSystemImpl();
|
|
||||||
|
|
||||||
// If the call is recursive, e.g.
|
|
||||||
// fun foo<T>(t : T) : T = foo(t)
|
|
||||||
// we can't use same descriptor objects for T's as actual type values and same T's as unknowns,
|
|
||||||
// because constraints become trivial (T :< T), and inference fails
|
|
||||||
//
|
|
||||||
// Thus, we replace the parameters of our descriptor with fresh objects (perform alpha-conversion)
|
|
||||||
CallableDescriptor candidateWithFreshVariables = FunctionDescriptorUtil.alphaConvertTypeParameters(candidate);
|
|
||||||
|
|
||||||
|
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : candidateWithFreshVariables.getTypeParameters()) {
|
|
||||||
constraintsSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); // TODO: variance of the occurrences
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeSubstitutor substituteDontCare = ConstraintSystemWithPriorities
|
|
||||||
.makeConstantSubstitutor(candidateWithFreshVariables.getTypeParameters(), ConstraintSystemImpl.DONT_CARE);
|
|
||||||
|
|
||||||
// Value parameters
|
|
||||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
|
|
||||||
ResolvedValueArgument resolvedValueArgument = entry.getValue();
|
|
||||||
ValueParameterDescriptor valueParameterDescriptor = candidateWithFreshVariables.getValueParameters().get(entry.getKey().getIndex());
|
|
||||||
|
|
||||||
|
|
||||||
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
|
|
||||||
if (JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue;
|
|
||||||
// TODO : more attempts, with different expected types
|
|
||||||
|
|
||||||
// Here we type check expecting an error type (DONT_CARE, substitution with substituteDontCare)
|
|
||||||
// and throw the results away
|
|
||||||
// We'll type check the arguments later, with the inferred types expected
|
|
||||||
boolean[] isErrorType = new boolean[1];
|
|
||||||
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintsSystem,
|
|
||||||
context, isErrorType);
|
|
||||||
if (isErrorType[0]) {
|
|
||||||
candidateCall.argumentHasNoType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receiver
|
|
||||||
// Error is already reported if something is missing
|
|
||||||
ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument();
|
|
||||||
ReceiverDescriptor receiverParameter = candidateWithFreshVariables.getReceiverParameter();
|
|
||||||
if (receiverArgument.exists() && receiverParameter.exists()) {
|
|
||||||
constraintsSystem.addSubtypeConstraint(receiverParameter.getType(), receiverArgument.getType(),
|
|
||||||
ConstraintPosition.RECEIVER_POSITION);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstraintSystem constraintSystemWithRightTypeParameters = constraintsSystem.replaceTypeVariables(new Function<TypeParameterDescriptor, TypeParameterDescriptor>() {
|
|
||||||
@Override
|
|
||||||
public TypeParameterDescriptor apply(@Nullable TypeParameterDescriptor typeParameterDescriptor) {
|
|
||||||
assert typeParameterDescriptor != null;
|
|
||||||
return candidate.getTypeParameters().get(typeParameterDescriptor.getIndex());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
candidateCall.setConstraintSystem(constraintSystemWithRightTypeParameters);
|
|
||||||
|
|
||||||
|
|
||||||
// Solution
|
|
||||||
boolean hasContradiction = constraintsSystem.hasContradiction();
|
|
||||||
boolean boundsAreSatisfied = ConstraintsUtil.checkBoundsAreSatisfied(constraintsSystem);
|
|
||||||
if (!hasContradiction && boundsAreSatisfied) {
|
|
||||||
candidateCall.setHasUnknownTypeParameters(true);
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context);
|
|
||||||
ResolutionStatus argumentsStatus = checkingResult.status;
|
|
||||||
List<JetType> argumentTypes = checkingResult.argumentTypes;
|
|
||||||
JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null;
|
|
||||||
ExtendedInferenceErrorData inferenceErrorData = InferenceErrorData
|
|
||||||
.create(candidate, constraintSystemWithRightTypeParameters, argumentTypes, receiverType, context.expectedType);
|
|
||||||
if (hasContradiction) {
|
|
||||||
context.tracing.typeInferenceFailed(candidateCall.getTrace(), inferenceErrorData, constraintSystemWithRightTypeParameters);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
context.tracing.upperBoundViolated(candidateCall.getTrace(), inferenceErrorData);
|
|
||||||
}
|
|
||||||
return TYPE_INFERENCE_ERROR.combine(argumentsStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean addConstraintForValueArgument(ValueArgument valueArgument,
|
|
||||||
@NotNull ValueParameterDescriptor valueParameterDescriptor,
|
|
||||||
@NotNull TypeSubstitutor substitutor,
|
|
||||||
@NotNull ConstraintSystem constraintSystem,
|
|
||||||
@NotNull ResolutionContext context,
|
|
||||||
@Nullable boolean[] isErrorType) {
|
|
||||||
|
|
||||||
JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
|
|
||||||
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
|
||||||
JetType type;
|
|
||||||
if (argumentExpression != null) {
|
|
||||||
TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(
|
|
||||||
context.trace, "transient trace to resolve argument", argumentExpression);
|
|
||||||
type = expressionTypingServices.getType(context.scope, argumentExpression,
|
|
||||||
substitutor.substitute(effectiveExpectedType, Variance.INVARIANT), context.dataFlowInfo, traceForUnknown);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
type = null;
|
|
||||||
}
|
|
||||||
constraintSystem.addSubtypeConstraint(effectiveExpectedType, type, ConstraintPosition.getValueParameterPosition(
|
|
||||||
valueParameterDescriptor.getIndex()));
|
|
||||||
//todo no return
|
|
||||||
if (isErrorType != null) {
|
|
||||||
isErrorType[0] = type == null || ErrorUtils.isErrorType(type);
|
|
||||||
}
|
|
||||||
if (type == null || ErrorUtils.isErrorType(type)) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void recordAutoCastIfNecessary(ReceiverDescriptor receiver, BindingTrace trace) {
|
|
||||||
if (receiver instanceof AutoCastReceiver) {
|
|
||||||
AutoCastReceiver autoCastReceiver = (AutoCastReceiver) receiver;
|
|
||||||
ReceiverDescriptor original = autoCastReceiver.getOriginal();
|
|
||||||
if (original instanceof ExpressionReceiver) {
|
|
||||||
ExpressionReceiver expressionReceiver = (ExpressionReceiver) original;
|
|
||||||
if (autoCastReceiver.canCast()) {
|
|
||||||
trace.record(AUTOCAST, expressionReceiver.getExpression(), autoCastReceiver.getType());
|
|
||||||
trace.record(EXPRESSION_TYPE, expressionReceiver.getExpression(), autoCastReceiver.getType());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
trace.report(AUTOCAST_IMPOSSIBLE.on(expressionReceiver.getExpression(), autoCastReceiver.getType(), expressionReceiver.getExpression().getText()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert autoCastReceiver.canCast() : "A non-expression receiver must always be autocastabe: " + original;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkTypesWithNoCallee(BasicResolutionContext context) {
|
|
||||||
for (ValueArgument valueArgument : context.call.getValueArguments()) {
|
|
||||||
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
|
||||||
if (argumentExpression != null) {
|
|
||||||
expressionTypingServices.getType(context.scope, argumentExpression, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (JetExpression expression : context.call.getFunctionLiteralArguments()) {
|
|
||||||
expressionTypingServices.getType(context.scope, expression, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (JetTypeProjection typeProjection : context.call.getTypeArguments()) {
|
|
||||||
JetTypeReference typeReference = typeProjection.getTypeReference();
|
|
||||||
if (typeReference == null) {
|
|
||||||
context.trace.report(Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(typeProjection));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
typeResolver.resolveType(context.scope, typeReference, context.trace, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkUnmappedArgumentTypes(BasicResolutionContext context, Set<ValueArgument> unmappedArguments) {
|
|
||||||
for (ValueArgument valueArgument : unmappedArguments) {
|
|
||||||
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
|
||||||
if (argumentExpression != null) {
|
|
||||||
expressionTypingServices.getType(context.scope, argumentExpression, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private <D extends CallableDescriptor, F extends D> ValueArgumentsCheckingResult checkAllValueArguments(CallResolutionContext<D, F> context) {
|
|
||||||
ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes(context, context.candidateCall, context.candidateCall.getTrace());
|
|
||||||
ResolutionStatus resultStatus = checkingResult.status;
|
|
||||||
ResolvedCall<D> candidateCall = context.candidateCall;
|
|
||||||
|
|
||||||
// Comment about a very special case.
|
|
||||||
// Call 'b.foo(1)' where class 'Foo' has an extension member 'fun B.invoke(Int)' should be checked two times for safe call (in 'checkReceiver'), because
|
|
||||||
// both 'b' (receiver) and 'foo' (this object) might be nullable. In the first case we mark dot, in the second 'foo'.
|
|
||||||
// Class 'CallForImplicitInvoke' helps up to recognise this case, and parameter 'implicitInvokeCheck' helps us to distinguish whether we check receiver or this object.
|
|
||||||
|
|
||||||
resultStatus = resultStatus.combine(checkReceiver(context, candidateCall, candidateCall.getResultingDescriptor().getReceiverParameter(), candidateCall.getReceiverArgument(),
|
|
||||||
candidateCall.getExplicitReceiverKind().isReceiver(), false));
|
|
||||||
|
|
||||||
resultStatus = resultStatus.combine(checkReceiver(context, candidateCall, candidateCall.getResultingDescriptor().getExpectedThisObject(), candidateCall.getThisObject(),
|
|
||||||
candidateCall.getExplicitReceiverKind().isThisObject(),
|
|
||||||
// for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error
|
|
||||||
context.call instanceof CallTransformer.CallForImplicitInvoke));
|
|
||||||
return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <D extends CallableDescriptor, F extends D> ResolutionStatus checkReceiver(CallResolutionContext<D, F> context, ResolvedCall<D> candidateCall,
|
|
||||||
ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument,
|
|
||||||
boolean isExplicitReceiver, boolean implicitInvokeCheck) {
|
|
||||||
|
|
||||||
BindingContext bindingContext = context.candidateCall.getTrace().getBindingContext();
|
|
||||||
|
|
||||||
ResolutionStatus result = SUCCESS;
|
|
||||||
if (receiverParameter.exists() && receiverArgument.exists()) {
|
|
||||||
boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.isSafeCall();
|
|
||||||
JetType receiverArgumentType = receiverArgument.getType();
|
|
||||||
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, bindingContext);
|
|
||||||
if (!safeAccess && !receiverParameter.getType().isNullable() && !autoCastService.isNotNull(receiverArgument)) {
|
|
||||||
|
|
||||||
context.tracing.unsafeCall(context.candidateCall.getTrace(), receiverArgumentType, implicitInvokeCheck);
|
|
||||||
result = UNSAFE_CALL_ERROR;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JetType effectiveReceiverArgumentType = safeAccess
|
|
||||||
? TypeUtils.makeNotNullable(receiverArgumentType)
|
|
||||||
: receiverArgumentType;
|
|
||||||
if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(),
|
|
||||||
candidateCall.getCandidateDescriptor().getTypeParameters()) &&
|
|
||||||
!typeChecker.isSubtypeOf(effectiveReceiverArgumentType, receiverParameter.getType())) {
|
|
||||||
context.tracing.wrongReceiverType(context.candidateCall.getTrace(), receiverParameter, receiverArgument);
|
|
||||||
result = OTHER_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DataFlowValue receiverValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(receiverArgument, bindingContext);
|
|
||||||
if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) {
|
|
||||||
context.tracing.unnecessarySafeCall(context.candidateCall.getTrace(), receiverArgumentType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ValueArgumentsCheckingResult {
|
|
||||||
public final List<JetType> argumentTypes;
|
|
||||||
public final ResolutionStatus status;
|
|
||||||
|
|
||||||
private ValueArgumentsCheckingResult(@NotNull ResolutionStatus status, @NotNull List<JetType> argumentTypes) {
|
|
||||||
this.status = status;
|
|
||||||
this.argumentTypes = argumentTypes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkValueArgumentTypes(ResolutionContext context, ResolvedCallImpl<D> candidateCall, BindingTrace trace) {
|
|
||||||
ResolutionStatus resultStatus = SUCCESS;
|
|
||||||
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
|
||||||
List<JetType> argumentTypes = Lists.newArrayList();
|
|
||||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
|
|
||||||
ValueParameterDescriptor parameterDescriptor = entry.getKey();
|
|
||||||
ResolvedValueArgument resolvedArgument = entry.getValue();
|
|
||||||
|
|
||||||
|
|
||||||
for (ValueArgument argument : resolvedArgument.getArguments()) {
|
|
||||||
JetExpression expression = argument.getArgumentExpression();
|
|
||||||
if (expression == null) continue;
|
|
||||||
|
|
||||||
JetType expectedType = getEffectiveExpectedType(parameterDescriptor, argument);
|
|
||||||
if (TypeUtils.dependsOnTypeParameters(expectedType, candidateCall.getCandidateDescriptor().getTypeParameters())) {
|
|
||||||
expectedType = NO_EXPECTED_TYPE;
|
|
||||||
}
|
|
||||||
JetTypeInfo typeInfo = expressionTypingServices.getTypeInfo(context.scope, expression, expectedType, dataFlowInfo, trace);
|
|
||||||
JetType type = typeInfo.getType();
|
|
||||||
argumentTypes.add(type);
|
|
||||||
dataFlowInfo = dataFlowInfo.and(typeInfo.getDataFlowInfo());
|
|
||||||
if (type == null || ErrorUtils.isErrorType(type)) {
|
|
||||||
candidateCall.argumentHasNoType();
|
|
||||||
}
|
|
||||||
else if (expectedType != NO_EXPECTED_TYPE && !typeChecker.isSubtypeOf(type, expectedType)) {
|
|
||||||
// VariableDescriptor variableDescriptor = AutoCastUtils.getVariableDescriptorFromSimpleName(temporaryTrace.getBindingContext(), argument);
|
|
||||||
// if (variableDescriptor != null) {
|
|
||||||
// JetType autoCastType = null;
|
|
||||||
// for (JetType possibleType : dataFlowInfo.getPossibleTypesForVariable(variableDescriptor)) {
|
|
||||||
// if (semanticServices.getTypeChecker().isSubtypeOf(type, parameterType)) {
|
|
||||||
// autoCastType = possibleType;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (autoCastType != null) {
|
|
||||||
// if (AutoCastUtils.isStableVariable(variableDescriptor)) {
|
|
||||||
// temporaryTrace.record(AUTOCAST, argument, autoCastType);
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// temporaryTrace.report(AUTOCAST_IMPOSSIBLE.on(argument, autoCastType, variableDescriptor));
|
|
||||||
// resultStatus = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
resultStatus = OTHER_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ValueArgumentsCheckingResult(resultStatus, argumentTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JetType getEffectiveExpectedType(ValueParameterDescriptor parameterDescriptor, ValueArgument argument) {
|
|
||||||
if (argument.getSpreadElement() != null) {
|
|
||||||
if (parameterDescriptor.getVarargElementType() == null) {
|
|
||||||
// Spread argument passed to a non-vararg parameter, an error is already reported by ValueArgumentsToParametersMapper
|
|
||||||
return ConstraintSystemImpl.DONT_CARE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return parameterDescriptor.getType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (argument.isNamed()) {
|
|
||||||
return parameterDescriptor.getType();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JetType varargElementType = parameterDescriptor.getVarargElementType();
|
|
||||||
if (varargElementType == null) {
|
|
||||||
return parameterDescriptor.getType();
|
|
||||||
}
|
|
||||||
return varargElementType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkGenericBoundsInAFunctionCall(List<JetTypeProjection> jetTypeArguments, List<JetType> typeArguments, CallableDescriptor functionDescriptor, BindingTrace trace) {
|
|
||||||
Map<TypeConstructor, TypeProjection> context = Maps.newHashMap();
|
|
||||||
|
|
||||||
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getOriginal().getTypeParameters();
|
|
||||||
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
|
|
||||||
TypeParameterDescriptor typeParameter = typeParameters.get(i);
|
|
||||||
JetType typeArgument = typeArguments.get(i);
|
|
||||||
context.put(typeParameter.getTypeConstructor(), new TypeProjection(typeArgument));
|
|
||||||
}
|
|
||||||
TypeSubstitutor substitutor = TypeSubstitutor.create(context);
|
|
||||||
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
|
|
||||||
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
|
||||||
JetType typeArgument = typeArguments.get(i);
|
|
||||||
JetTypeReference typeReference = jetTypeArguments.get(i).getTypeReference();
|
|
||||||
if (typeReference != null) {
|
|
||||||
descriptorResolver.checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor, trace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated // Creates wrong resolved calls, should be removed
|
@Deprecated // Creates wrong resolved calls, should be removed
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -0,0 +1,600 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 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.resolve.calls;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContext.AUTOCAST;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContext.EXPRESSION_TYPE;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.*;
|
||||||
|
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||||
|
|
||||||
|
public class CandidateResolver {
|
||||||
|
@NotNull
|
||||||
|
private final JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
|
||||||
|
@NotNull
|
||||||
|
private TypeResolver typeResolver;
|
||||||
|
@NotNull
|
||||||
|
private ExpressionTypingServices expressionTypingServices;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) {
|
||||||
|
this.expressionTypingServices = expressionTypingServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setTypeResolver(@NotNull TypeResolver typeResolver) {
|
||||||
|
this.typeResolver = typeResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void checkTypesWithNoCallee(@NotNull ResolutionContext context) {
|
||||||
|
for (ValueArgument valueArgument : context.call.getValueArguments()) {
|
||||||
|
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||||
|
if (argumentExpression != null) {
|
||||||
|
expressionTypingServices.getType(context.scope, argumentExpression, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (JetExpression expression : context.call.getFunctionLiteralArguments()) {
|
||||||
|
expressionTypingServices.getType(context.scope, expression, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (JetTypeProjection typeProjection : context.call.getTypeArguments()) {
|
||||||
|
JetTypeReference typeReference = typeProjection.getTypeReference();
|
||||||
|
if (typeReference == null) {
|
||||||
|
context.trace.report(Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(typeProjection));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
typeResolver.resolveType(context.scope, typeReference, context.trace, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <D extends CallableDescriptor, F extends D> void performResolutionForCandidateCall(
|
||||||
|
@NotNull CallResolutionContext<D, F> context,
|
||||||
|
@NotNull ResolutionTask<D, F> task) {
|
||||||
|
|
||||||
|
ProgressIndicatorProvider.checkCanceled();
|
||||||
|
|
||||||
|
ResolvedCallImpl<D> candidateCall = context.candidateCall;
|
||||||
|
D candidate = candidateCall.getCandidateDescriptor();
|
||||||
|
|
||||||
|
if (ErrorUtils.isError(candidate)) {
|
||||||
|
candidateCall.addStatus(SUCCESS);
|
||||||
|
checkTypesWithNoCallee(context.toBasic());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Visibilities.isVisible(candidate, context.scope.getContainingDeclaration())) {
|
||||||
|
candidateCall.addStatus(OTHER_ERROR);
|
||||||
|
context.tracing.invisibleMember(context.trace, candidate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<ValueArgument> unmappedArguments = Sets.newLinkedHashSet();
|
||||||
|
ValueArgumentsToParametersMapper.Status
|
||||||
|
argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing,
|
||||||
|
candidateCall, unmappedArguments);
|
||||||
|
if (!argumentMappingStatus.isSuccess()) {
|
||||||
|
if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR) {
|
||||||
|
candidateCall.addStatus(STRONG_ERROR);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
candidateCall.addStatus(OTHER_ERROR);
|
||||||
|
}
|
||||||
|
if ((argumentMappingStatus == ValueArgumentsToParametersMapper.Status.ERROR && candidate.getTypeParameters().isEmpty()) ||
|
||||||
|
argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR) {
|
||||||
|
checkTypesWithNoCallee(context.toBasic());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
checkUnmappedArgumentTypes(context.toBasic(), unmappedArguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<JetTypeProjection> jetTypeArguments = context.call.getTypeArguments();
|
||||||
|
if (jetTypeArguments.isEmpty()) {
|
||||||
|
if (!candidate.getTypeParameters().isEmpty()) {
|
||||||
|
ResolutionStatus status = inferTypeArguments(context);
|
||||||
|
candidateCall.addStatus(status);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
candidateCall.addStatus(checkAllValueArguments(context).status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Explicit type arguments passed
|
||||||
|
|
||||||
|
List<JetType> typeArguments = new ArrayList<JetType>();
|
||||||
|
for (JetTypeProjection projection : jetTypeArguments) {
|
||||||
|
if (projection.getProjectionKind() != JetProjectionKind.NONE) {
|
||||||
|
context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection));
|
||||||
|
}
|
||||||
|
JetTypeReference typeReference = projection.getTypeReference();
|
||||||
|
if (typeReference != null) {
|
||||||
|
typeArguments.add(typeResolver.resolveType(context.scope, typeReference, context.trace, true));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
typeArguments.add(ErrorUtils.createErrorType("Star projection in a call"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int expectedTypeArgumentCount = candidate.getTypeParameters().size();
|
||||||
|
if (expectedTypeArgumentCount == jetTypeArguments.size()) {
|
||||||
|
|
||||||
|
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, context.trace);
|
||||||
|
|
||||||
|
Map<TypeConstructor, TypeProjection>
|
||||||
|
substitutionContext = FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor)candidate, typeArguments);
|
||||||
|
candidateCall.setResultingSubstitutor(TypeSubstitutor.create(substitutionContext));
|
||||||
|
|
||||||
|
List<TypeParameterDescriptor> typeParameters = candidateCall.getCandidateDescriptor().getTypeParameters();
|
||||||
|
for (int i = 0; i < typeParameters.size(); i++) {
|
||||||
|
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
||||||
|
candidateCall.recordTypeArgument(typeParameterDescriptor, typeArguments.get(i));
|
||||||
|
}
|
||||||
|
candidateCall.addStatus(checkAllValueArguments(context).status);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
candidateCall.addStatus(OTHER_ERROR);
|
||||||
|
context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task.performAdvancedChecks(candidate, context.trace, context.tracing);
|
||||||
|
|
||||||
|
// 'super' cannot be passed as an argument, for receiver arguments expression typer does not track this
|
||||||
|
// See TaskPrioritizer for more
|
||||||
|
JetSuperExpression superExpression = TaskPrioritizer.getReceiverSuper(candidateCall.getReceiverArgument());
|
||||||
|
if (superExpression != null) {
|
||||||
|
context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(superExpression, superExpression.getText()));
|
||||||
|
candidateCall.addStatus(OTHER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
recordAutoCastIfNecessary(candidateCall.getReceiverArgument(), candidateCall.getTrace());
|
||||||
|
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
|
||||||
|
}
|
||||||
|
|
||||||
|
public <D extends CallableDescriptor> void completeTypeInferenceDependentOnExpectedTypeForCall(
|
||||||
|
CallResolutionContext<D, D> context,
|
||||||
|
Set<ResolvedCallWithTrace<D>> successful,
|
||||||
|
Set<ResolvedCallWithTrace<D>> failed
|
||||||
|
) {
|
||||||
|
ResolvedCallImpl<D> resolvedCall = context.candidateCall;
|
||||||
|
assert resolvedCall.hasUnknownTypeParameters();
|
||||||
|
D descriptor = resolvedCall.getCandidateDescriptor();
|
||||||
|
ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem();
|
||||||
|
assert constraintSystem != null;
|
||||||
|
|
||||||
|
TypeSubstitutor substituteDontCare = ConstraintSystemWithPriorities
|
||||||
|
.makeConstantSubstitutor(resolvedCall.getCandidateDescriptor().getTypeParameters(), ConstraintSystemImpl.DONT_CARE);
|
||||||
|
|
||||||
|
// constraints for function literals
|
||||||
|
// Value parameters
|
||||||
|
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : resolvedCall.getValueArguments().entrySet()) {
|
||||||
|
ResolvedValueArgument resolvedValueArgument = entry.getValue();
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = entry.getKey();
|
||||||
|
|
||||||
|
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
|
||||||
|
if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue;
|
||||||
|
|
||||||
|
ConstraintSystem systemWithCurrentSubstitution = constraintSystem.copy();
|
||||||
|
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintSystem.getCurrentSubstitutor(),
|
||||||
|
systemWithCurrentSubstitution, context, null);
|
||||||
|
if (systemWithCurrentSubstitution.hasContradiction() || systemWithCurrentSubstitution.hasErrorInConstrainingTypes()) {
|
||||||
|
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintSystem, context, null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
constraintSystem = systemWithCurrentSubstitution;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintSystem constraintSystemWithoutExpectedTypeConstraint = constraintSystem.copy();
|
||||||
|
constraintSystem.addSupertypeConstraint(descriptor.getReturnType(), context.expectedType,
|
||||||
|
ConstraintPosition.EXPECTED_TYPE_POSITION);
|
||||||
|
|
||||||
|
|
||||||
|
if (!constraintSystem.isSuccessful()) {
|
||||||
|
resolvedCall.setResultingSubstitutor(constraintSystemWithoutExpectedTypeConstraint.getResultingSubstitutor());
|
||||||
|
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()).argumentTypes;
|
||||||
|
JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
|
||||||
|
context.tracing.typeInferenceFailed(resolvedCall.getTrace(),
|
||||||
|
InferenceErrorData
|
||||||
|
.create(descriptor, constraintSystem, argumentTypes, receiverType,
|
||||||
|
context.expectedType),
|
||||||
|
constraintSystemWithoutExpectedTypeConstraint);
|
||||||
|
resolvedCall.addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR);
|
||||||
|
failed.add(resolvedCall);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor());
|
||||||
|
// Here we type check the arguments with inferred types expected
|
||||||
|
checkAllValueArguments(context);
|
||||||
|
|
||||||
|
checkBounds(resolvedCall, constraintSystem, resolvedCall.getTrace(), context.tracing);
|
||||||
|
resolvedCall.setHasUnknownTypeParameters(false);
|
||||||
|
if (resolvedCall.getStatus().isSuccess() || resolvedCall.getStatus() == ResolutionStatus.UNKNOWN_STATUS) {
|
||||||
|
resolvedCall.addStatus(ResolutionStatus.SUCCESS);
|
||||||
|
successful.add(resolvedCall);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
failed.add(resolvedCall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <D extends CallableDescriptor, F extends D> ResolutionStatus inferTypeArguments(CallResolutionContext<D, F> context) {
|
||||||
|
ResolvedCallImpl<D> candidateCall = context.candidateCall;
|
||||||
|
final D candidate = candidateCall.getCandidateDescriptor();
|
||||||
|
|
||||||
|
context.trace.get(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement());
|
||||||
|
|
||||||
|
ConstraintSystemImpl constraintsSystem = new ConstraintSystemImpl();
|
||||||
|
|
||||||
|
// If the call is recursive, e.g.
|
||||||
|
// fun foo<T>(t : T) : T = foo(t)
|
||||||
|
// we can't use same descriptor objects for T's as actual type values and same T's as unknowns,
|
||||||
|
// because constraints become trivial (T :< T), and inference fails
|
||||||
|
//
|
||||||
|
// Thus, we replace the parameters of our descriptor with fresh objects (perform alpha-conversion)
|
||||||
|
CallableDescriptor candidateWithFreshVariables = FunctionDescriptorUtil.alphaConvertTypeParameters(candidate);
|
||||||
|
|
||||||
|
|
||||||
|
for (TypeParameterDescriptor typeParameterDescriptor : candidateWithFreshVariables.getTypeParameters()) {
|
||||||
|
constraintsSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); // TODO: variance of the occurrences
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeSubstitutor substituteDontCare = ConstraintSystemWithPriorities
|
||||||
|
.makeConstantSubstitutor(candidateWithFreshVariables.getTypeParameters(), ConstraintSystemImpl.DONT_CARE);
|
||||||
|
|
||||||
|
// Value parameters
|
||||||
|
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
|
||||||
|
ResolvedValueArgument resolvedValueArgument = entry.getValue();
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = candidateWithFreshVariables.getValueParameters().get(entry.getKey().getIndex());
|
||||||
|
|
||||||
|
|
||||||
|
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
|
||||||
|
if (JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue;
|
||||||
|
// TODO : more attempts, with different expected types
|
||||||
|
|
||||||
|
// Here we type check expecting an error type (DONT_CARE, substitution with substituteDontCare)
|
||||||
|
// and throw the results away
|
||||||
|
// We'll type check the arguments later, with the inferred types expected
|
||||||
|
boolean[] isErrorType = new boolean[1];
|
||||||
|
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintsSystem,
|
||||||
|
context, isErrorType);
|
||||||
|
if (isErrorType[0]) {
|
||||||
|
candidateCall.argumentHasNoType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receiver
|
||||||
|
// Error is already reported if something is missing
|
||||||
|
ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument();
|
||||||
|
ReceiverDescriptor receiverParameter = candidateWithFreshVariables.getReceiverParameter();
|
||||||
|
if (receiverArgument.exists() && receiverParameter.exists()) {
|
||||||
|
constraintsSystem.addSubtypeConstraint(receiverParameter.getType(), receiverArgument.getType(),
|
||||||
|
ConstraintPosition.RECEIVER_POSITION);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintSystem
|
||||||
|
constraintSystemWithRightTypeParameters = constraintsSystem.replaceTypeVariables(new Function<TypeParameterDescriptor, TypeParameterDescriptor>() {
|
||||||
|
@Override
|
||||||
|
public TypeParameterDescriptor apply(@Nullable TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
|
assert typeParameterDescriptor != null;
|
||||||
|
return candidate.getTypeParameters().get(typeParameterDescriptor.getIndex());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
candidateCall.setConstraintSystem(constraintSystemWithRightTypeParameters);
|
||||||
|
|
||||||
|
|
||||||
|
// Solution
|
||||||
|
boolean hasContradiction = constraintsSystem.hasContradiction();
|
||||||
|
boolean boundsAreSatisfied = ConstraintsUtil.checkBoundsAreSatisfied(constraintsSystem);
|
||||||
|
if (!hasContradiction && boundsAreSatisfied) {
|
||||||
|
candidateCall.setHasUnknownTypeParameters(true);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context);
|
||||||
|
ResolutionStatus argumentsStatus = checkingResult.status;
|
||||||
|
List<JetType> argumentTypes = checkingResult.argumentTypes;
|
||||||
|
JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null;
|
||||||
|
InferenceErrorData.ExtendedInferenceErrorData inferenceErrorData = InferenceErrorData
|
||||||
|
.create(candidate, constraintSystemWithRightTypeParameters, argumentTypes, receiverType, context.expectedType);
|
||||||
|
if (hasContradiction) {
|
||||||
|
context.tracing.typeInferenceFailed(candidateCall.getTrace(), inferenceErrorData, constraintSystemWithRightTypeParameters);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
context.tracing.upperBoundViolated(candidateCall.getTrace(), inferenceErrorData);
|
||||||
|
}
|
||||||
|
return TYPE_INFERENCE_ERROR.combine(argumentsStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addConstraintForValueArgument(
|
||||||
|
@NotNull ValueArgument valueArgument,
|
||||||
|
@NotNull ValueParameterDescriptor valueParameterDescriptor,
|
||||||
|
@NotNull TypeSubstitutor substitutor,
|
||||||
|
@NotNull ConstraintSystem constraintSystem,
|
||||||
|
@NotNull ResolutionContext context,
|
||||||
|
@Nullable boolean[] isErrorType) {
|
||||||
|
|
||||||
|
JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
|
||||||
|
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||||
|
JetType type;
|
||||||
|
if (argumentExpression != null) {
|
||||||
|
TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(
|
||||||
|
context.trace, "transient trace to resolve argument", argumentExpression);
|
||||||
|
type = expressionTypingServices.getType(context.scope, argumentExpression,
|
||||||
|
substitutor.substitute(effectiveExpectedType, Variance.INVARIANT), context.dataFlowInfo, traceForUnknown);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
type = null;
|
||||||
|
}
|
||||||
|
constraintSystem.addSubtypeConstraint(effectiveExpectedType, type, ConstraintPosition.getValueParameterPosition(
|
||||||
|
valueParameterDescriptor.getIndex()));
|
||||||
|
//todo no return
|
||||||
|
if (isErrorType != null) {
|
||||||
|
isErrorType[0] = type == null || ErrorUtils.isErrorType(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <D extends CallableDescriptor, F extends D> ValueArgumentsCheckingResult checkAllValueArguments(CallResolutionContext<D, F> context) {
|
||||||
|
ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes(context, context.candidateCall, context.candidateCall.getTrace());
|
||||||
|
ResolutionStatus resultStatus = checkingResult.status;
|
||||||
|
ResolvedCall<D> candidateCall = context.candidateCall;
|
||||||
|
|
||||||
|
// Comment about a very special case.
|
||||||
|
// Call 'b.foo(1)' where class 'Foo' has an extension member 'fun B.invoke(Int)' should be checked two times for safe call (in 'checkReceiver'), because
|
||||||
|
// both 'b' (receiver) and 'foo' (this object) might be nullable. In the first case we mark dot, in the second 'foo'.
|
||||||
|
// Class 'CallForImplicitInvoke' helps up to recognise this case, and parameter 'implicitInvokeCheck' helps us to distinguish whether we check receiver or this object.
|
||||||
|
|
||||||
|
resultStatus = resultStatus.combine(checkReceiver(context, candidateCall, candidateCall.getResultingDescriptor().getReceiverParameter(), candidateCall.getReceiverArgument(),
|
||||||
|
candidateCall.getExplicitReceiverKind().isReceiver(), false));
|
||||||
|
|
||||||
|
resultStatus = resultStatus.combine(checkReceiver(context, candidateCall, candidateCall.getResultingDescriptor().getExpectedThisObject(), candidateCall.getThisObject(),
|
||||||
|
candidateCall.getExplicitReceiverKind().isThisObject(),
|
||||||
|
// for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error
|
||||||
|
context.call instanceof CallTransformer.CallForImplicitInvoke));
|
||||||
|
return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkValueArgumentTypes(
|
||||||
|
@NotNull ResolutionContext context,
|
||||||
|
@NotNull ResolvedCallImpl<D> candidateCall,
|
||||||
|
@NotNull BindingTrace trace) {
|
||||||
|
ResolutionStatus resultStatus = SUCCESS;
|
||||||
|
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
||||||
|
List<JetType> argumentTypes = Lists.newArrayList();
|
||||||
|
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
|
||||||
|
ValueParameterDescriptor parameterDescriptor = entry.getKey();
|
||||||
|
ResolvedValueArgument resolvedArgument = entry.getValue();
|
||||||
|
|
||||||
|
|
||||||
|
for (ValueArgument argument : resolvedArgument.getArguments()) {
|
||||||
|
JetExpression expression = argument.getArgumentExpression();
|
||||||
|
if (expression == null) continue;
|
||||||
|
|
||||||
|
JetType expectedType = getEffectiveExpectedType(parameterDescriptor, argument);
|
||||||
|
if (TypeUtils.dependsOnTypeParameters(expectedType, candidateCall.getCandidateDescriptor().getTypeParameters())) {
|
||||||
|
expectedType = NO_EXPECTED_TYPE;
|
||||||
|
}
|
||||||
|
JetTypeInfo typeInfo = expressionTypingServices.getTypeInfo(context.scope, expression, expectedType, dataFlowInfo, trace);
|
||||||
|
JetType type = typeInfo.getType();
|
||||||
|
argumentTypes.add(type);
|
||||||
|
dataFlowInfo = dataFlowInfo.and(typeInfo.getDataFlowInfo());
|
||||||
|
if (type == null || ErrorUtils.isErrorType(type)) {
|
||||||
|
candidateCall.argumentHasNoType();
|
||||||
|
}
|
||||||
|
else if (expectedType != NO_EXPECTED_TYPE && !typeChecker.isSubtypeOf(type, expectedType)) {
|
||||||
|
// VariableDescriptor variableDescriptor = AutoCastUtils.getVariableDescriptorFromSimpleName(temporaryTrace.getBindingContext(), argument);
|
||||||
|
// if (variableDescriptor != null) {
|
||||||
|
// JetType autoCastType = null;
|
||||||
|
// for (JetType possibleType : dataFlowInfo.getPossibleTypesForVariable(variableDescriptor)) {
|
||||||
|
// if (semanticServices.getTypeChecker().isSubtypeOf(type, parameterType)) {
|
||||||
|
// autoCastType = possibleType;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (autoCastType != null) {
|
||||||
|
// if (AutoCastUtils.isStableVariable(variableDescriptor)) {
|
||||||
|
// temporaryTrace.record(AUTOCAST, argument, autoCastType);
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// temporaryTrace.report(AUTOCAST_IMPOSSIBLE.on(argument, autoCastType, variableDescriptor));
|
||||||
|
// resultStatus = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
resultStatus = OTHER_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ValueArgumentsCheckingResult(resultStatus, argumentTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkUnmappedArgumentTypes(ResolutionContext context, Set<ValueArgument> unmappedArguments) {
|
||||||
|
for (ValueArgument valueArgument : unmappedArguments) {
|
||||||
|
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||||
|
if (argumentExpression != null) {
|
||||||
|
expressionTypingServices.getType(context.scope, argumentExpression, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <D extends CallableDescriptor, F extends D> ResolutionStatus checkReceiver(CallResolutionContext<D, F> context, ResolvedCall<D> candidateCall,
|
||||||
|
ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument,
|
||||||
|
boolean isExplicitReceiver, boolean implicitInvokeCheck) {
|
||||||
|
|
||||||
|
BindingContext bindingContext = context.candidateCall.getTrace().getBindingContext();
|
||||||
|
|
||||||
|
ResolutionStatus result = SUCCESS;
|
||||||
|
if (receiverParameter.exists() && receiverArgument.exists()) {
|
||||||
|
boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.isSafeCall();
|
||||||
|
JetType receiverArgumentType = receiverArgument.getType();
|
||||||
|
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, bindingContext);
|
||||||
|
if (!safeAccess && !receiverParameter.getType().isNullable() && !autoCastService.isNotNull(receiverArgument)) {
|
||||||
|
|
||||||
|
context.tracing.unsafeCall(context.candidateCall.getTrace(), receiverArgumentType, implicitInvokeCheck);
|
||||||
|
result = UNSAFE_CALL_ERROR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JetType effectiveReceiverArgumentType = safeAccess
|
||||||
|
? TypeUtils.makeNotNullable(receiverArgumentType)
|
||||||
|
: receiverArgumentType;
|
||||||
|
if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(),
|
||||||
|
candidateCall.getCandidateDescriptor().getTypeParameters()) &&
|
||||||
|
!typeChecker.isSubtypeOf(effectiveReceiverArgumentType, receiverParameter.getType())) {
|
||||||
|
context.tracing.wrongReceiverType(context.candidateCall.getTrace(), receiverParameter, receiverArgument);
|
||||||
|
result = OTHER_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DataFlowValue receiverValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(receiverArgument, bindingContext);
|
||||||
|
if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) {
|
||||||
|
context.tracing.unnecessarySafeCall(context.candidateCall.getTrace(), receiverArgumentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ValueArgumentsCheckingResult {
|
||||||
|
|
||||||
|
public final List<JetType> argumentTypes;
|
||||||
|
public final ResolutionStatus status;
|
||||||
|
|
||||||
|
private ValueArgumentsCheckingResult(@NotNull ResolutionStatus status, @NotNull List<JetType> argumentTypes) {
|
||||||
|
this.status = status;
|
||||||
|
this.argumentTypes = argumentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void recordAutoCastIfNecessary(ReceiverDescriptor receiver, BindingTrace trace) {
|
||||||
|
if (receiver instanceof AutoCastReceiver) {
|
||||||
|
AutoCastReceiver autoCastReceiver = (AutoCastReceiver) receiver;
|
||||||
|
ReceiverDescriptor original = autoCastReceiver.getOriginal();
|
||||||
|
if (original instanceof ExpressionReceiver) {
|
||||||
|
ExpressionReceiver expressionReceiver = (ExpressionReceiver) original;
|
||||||
|
if (autoCastReceiver.canCast()) {
|
||||||
|
trace.record(AUTOCAST, expressionReceiver.getExpression(), autoCastReceiver.getType());
|
||||||
|
trace.record(EXPRESSION_TYPE, expressionReceiver.getExpression(), autoCastReceiver.getType());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
trace.report(AUTOCAST_IMPOSSIBLE.on(expressionReceiver.getExpression(), autoCastReceiver.getType(), expressionReceiver.getExpression().getText()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert autoCastReceiver.canCast() : "A non-expression receiver must always be autocastabe: " + original;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static JetType getEffectiveExpectedType(ValueParameterDescriptor parameterDescriptor, ValueArgument argument) {
|
||||||
|
if (argument.getSpreadElement() != null) {
|
||||||
|
if (parameterDescriptor.getVarargElementType() == null) {
|
||||||
|
// Spread argument passed to a non-vararg parameter, an error is already reported by ValueArgumentsToParametersMapper
|
||||||
|
return ConstraintSystemImpl.DONT_CARE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return parameterDescriptor.getType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (argument.isNamed()) {
|
||||||
|
return parameterDescriptor.getType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JetType varargElementType = parameterDescriptor.getVarargElementType();
|
||||||
|
if (varargElementType == null) {
|
||||||
|
return parameterDescriptor.getType();
|
||||||
|
}
|
||||||
|
return varargElementType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <D extends CallableDescriptor> void checkBounds(
|
||||||
|
@NotNull ResolvedCallImpl<D> call,
|
||||||
|
@NotNull ConstraintSystem constraintSystem,
|
||||||
|
@NotNull BindingTrace trace,
|
||||||
|
@NotNull TracingStrategy tracing
|
||||||
|
) {
|
||||||
|
for (TypeParameterDescriptor typeParameter : call.getCandidateDescriptor().getTypeParameters()) {
|
||||||
|
if (!ConstraintsUtil.checkUpperBoundIsSatisfied(constraintSystem, typeParameter)) {
|
||||||
|
tracing.upperBoundViolated(trace, InferenceErrorData.create(call.getCandidateDescriptor(), constraintSystem));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkGenericBoundsInAFunctionCall(
|
||||||
|
@NotNull List<JetTypeProjection> jetTypeArguments,
|
||||||
|
@NotNull List<JetType> typeArguments,
|
||||||
|
@NotNull CallableDescriptor functionDescriptor,
|
||||||
|
@NotNull BindingTrace trace) {
|
||||||
|
Map<TypeConstructor, TypeProjection> context = Maps.newHashMap();
|
||||||
|
|
||||||
|
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getOriginal().getTypeParameters();
|
||||||
|
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
|
||||||
|
TypeParameterDescriptor typeParameter = typeParameters.get(i);
|
||||||
|
JetType typeArgument = typeArguments.get(i);
|
||||||
|
context.put(typeParameter.getTypeConstructor(), new TypeProjection(typeArgument));
|
||||||
|
}
|
||||||
|
TypeSubstitutor substitutor = TypeSubstitutor.create(context);
|
||||||
|
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
|
||||||
|
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
||||||
|
JetType typeArgument = typeArguments.get(i);
|
||||||
|
JetTypeReference typeReference = jetTypeArguments.get(i).getTypeReference();
|
||||||
|
if (typeReference != null) {
|
||||||
|
DescriptorResolver.checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor, trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.ModuleConfiguration;
|
|||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
|
||||||
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.results.OverloadingConflictResolver;
|
import org.jetbrains.jet.lang.resolve.calls.results.OverloadingConflictResolver;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -43,6 +44,7 @@ public class InjectorForTests {
|
|||||||
private final Project project;
|
private final Project project;
|
||||||
private AnnotationResolver annotationResolver;
|
private AnnotationResolver annotationResolver;
|
||||||
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||||
|
private CandidateResolver candidateResolver;
|
||||||
private ResolutionResultsHandler resolutionResultsHandler;
|
private ResolutionResultsHandler resolutionResultsHandler;
|
||||||
private OverloadingConflictResolver overloadingConflictResolver;
|
private OverloadingConflictResolver overloadingConflictResolver;
|
||||||
|
|
||||||
@@ -58,6 +60,7 @@ public class InjectorForTests {
|
|||||||
this.project = project;
|
this.project = project;
|
||||||
this.annotationResolver = new AnnotationResolver();
|
this.annotationResolver = new AnnotationResolver();
|
||||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||||
|
this.candidateResolver = new CandidateResolver();
|
||||||
this.resolutionResultsHandler = new ResolutionResultsHandler();
|
this.resolutionResultsHandler = new ResolutionResultsHandler();
|
||||||
this.overloadingConflictResolver = new OverloadingConflictResolver();
|
this.overloadingConflictResolver = new OverloadingConflictResolver();
|
||||||
|
|
||||||
@@ -75,7 +78,7 @@ public class InjectorForTests {
|
|||||||
this.typeResolver.setModuleConfiguration(moduleConfiguration);
|
this.typeResolver.setModuleConfiguration(moduleConfiguration);
|
||||||
this.typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
this.typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||||
|
|
||||||
this.callResolver.setDescriptorResolver(descriptorResolver);
|
this.callResolver.setCandidateResolver(candidateResolver);
|
||||||
this.callResolver.setExpressionTypingServices(expressionTypingServices);
|
this.callResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
this.callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
this.callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
||||||
this.callResolver.setTypeResolver(typeResolver);
|
this.callResolver.setTypeResolver(typeResolver);
|
||||||
@@ -83,6 +86,9 @@ public class InjectorForTests {
|
|||||||
annotationResolver.setCallResolver(callResolver);
|
annotationResolver.setCallResolver(callResolver);
|
||||||
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
|
||||||
|
candidateResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
candidateResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
resolutionResultsHandler.setOverloadingConflictResolver(overloadingConflictResolver);
|
resolutionResultsHandler.setOverloadingConflictResolver(overloadingConflictResolver);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
|
|||||||
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
|
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
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.CandidateResolver;
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||||
@@ -66,6 +67,7 @@ public class InjectorForTopDownAnalyzerForJs {
|
|||||||
private DeclarationResolver declarationResolver;
|
private DeclarationResolver declarationResolver;
|
||||||
private AnnotationResolver annotationResolver;
|
private AnnotationResolver annotationResolver;
|
||||||
private CallResolver callResolver;
|
private CallResolver callResolver;
|
||||||
|
private CandidateResolver candidateResolver;
|
||||||
private ExpressionTypingServices expressionTypingServices;
|
private ExpressionTypingServices expressionTypingServices;
|
||||||
private TypeResolver typeResolver;
|
private TypeResolver typeResolver;
|
||||||
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||||
@@ -101,6 +103,7 @@ public class InjectorForTopDownAnalyzerForJs {
|
|||||||
this.declarationResolver = new DeclarationResolver();
|
this.declarationResolver = new DeclarationResolver();
|
||||||
this.annotationResolver = new AnnotationResolver();
|
this.annotationResolver = new AnnotationResolver();
|
||||||
this.callResolver = new CallResolver();
|
this.callResolver = new CallResolver();
|
||||||
|
this.candidateResolver = new CandidateResolver();
|
||||||
this.expressionTypingServices = new ExpressionTypingServices();
|
this.expressionTypingServices = new ExpressionTypingServices();
|
||||||
this.typeResolver = new TypeResolver();
|
this.typeResolver = new TypeResolver();
|
||||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||||
@@ -159,11 +162,14 @@ public class InjectorForTopDownAnalyzerForJs {
|
|||||||
annotationResolver.setCallResolver(callResolver);
|
annotationResolver.setCallResolver(callResolver);
|
||||||
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
|
||||||
callResolver.setDescriptorResolver(descriptorResolver);
|
callResolver.setCandidateResolver(candidateResolver);
|
||||||
callResolver.setExpressionTypingServices(expressionTypingServices);
|
callResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
callResolver.setResolutionResultsHandler(resolutionResultsHandler);
|
||||||
callResolver.setTypeResolver(typeResolver);
|
callResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
|
candidateResolver.setExpressionTypingServices(expressionTypingServices);
|
||||||
|
candidateResolver.setTypeResolver(typeResolver);
|
||||||
|
|
||||||
expressionTypingServices.setCallResolver(callResolver);
|
expressionTypingServices.setCallResolver(callResolver);
|
||||||
expressionTypingServices.setDescriptorResolver(descriptorResolver);
|
expressionTypingServices.setDescriptorResolver(descriptorResolver);
|
||||||
expressionTypingServices.setProject(project);
|
expressionTypingServices.setProject(project);
|
||||||
|
|||||||
Reference in New Issue
Block a user