getQualifiedExpressionTypeInfo moved to CallExpressionResolver

CallExpressionResolver made a component
This commit is contained in:
Svetlana Isakova
2013-02-07 20:43:26 +04:00
parent 664e25d113
commit 170a3ad718
11 changed files with 196 additions and 90 deletions
@@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
@@ -86,6 +87,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
private CallResolver callResolver;
private ArgumentTypeResolver argumentTypeResolver;
private ExpressionTypingServices expressionTypingServices;
private CallExpressionResolver callExpressionResolver;
private TypeResolver typeResolver;
private QualifiedExpressionResolver qualifiedExpressionResolver;
private CandidateResolver candidateResolver;
@@ -137,6 +139,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.expressionTypingServices = new ExpressionTypingServices();
this.callExpressionResolver = new CallExpressionResolver();
this.typeResolver = new TypeResolver();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
this.candidateResolver = new CandidateResolver();
@@ -228,11 +231,14 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
argumentTypeResolver.setExpressionTypingServices(expressionTypingServices);
argumentTypeResolver.setTypeResolver(typeResolver);
expressionTypingServices.setCallExpressionResolver(callExpressionResolver);
expressionTypingServices.setCallResolver(callResolver);
expressionTypingServices.setDescriptorResolver(descriptorResolver);
expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver);
callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver);
typeResolver.setDescriptorResolver(descriptorResolver);
typeResolver.setModuleConfiguration(moduleConfiguration);
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver;
@@ -49,6 +50,7 @@ public class InjectorForBodyResolve {
private CallResolver callResolver;
private ArgumentTypeResolver argumentTypeResolver;
private ExpressionTypingServices expressionTypingServices;
private CallExpressionResolver callExpressionResolver;
private DescriptorResolver descriptorResolver;
private AnnotationResolver annotationResolver;
private TypeResolver typeResolver;
@@ -75,6 +77,7 @@ public class InjectorForBodyResolve {
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.expressionTypingServices = new ExpressionTypingServices();
this.callExpressionResolver = new CallExpressionResolver();
this.descriptorResolver = new DescriptorResolver();
this.annotationResolver = new AnnotationResolver();
this.typeResolver = new TypeResolver();
@@ -103,11 +106,14 @@ public class InjectorForBodyResolve {
argumentTypeResolver.setExpressionTypingServices(expressionTypingServices);
argumentTypeResolver.setTypeResolver(typeResolver);
expressionTypingServices.setCallExpressionResolver(callExpressionResolver);
expressionTypingServices.setCallResolver(callResolver);
expressionTypingServices.setDescriptorResolver(descriptorResolver);
expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver);
callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setAnnotationResolver(annotationResolver);
descriptorResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setTypeResolver(typeResolver);
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.psi.JetImportsFactory;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
@@ -47,6 +48,7 @@ public class InjectorForLazyResolve {
private AnnotationResolver annotationResolver;
private QualifiedExpressionResolver qualifiedExpressionResolver;
private JetImportsFactory jetImportsFactory;
private CallExpressionResolver callExpressionResolver;
private CallResolver callResolver;
private ArgumentTypeResolver argumentTypeResolver;
private CandidateResolver candidateResolver;
@@ -68,6 +70,7 @@ public class InjectorForLazyResolve {
this.annotationResolver = new AnnotationResolver();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
this.jetImportsFactory = new JetImportsFactory();
this.callExpressionResolver = new CallExpressionResolver();
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.candidateResolver = new CandidateResolver();
@@ -76,6 +79,7 @@ public class InjectorForLazyResolve {
this.descriptorResolver.setExpressionTypingServices(expressionTypingServices);
this.descriptorResolver.setTypeResolver(typeResolver);
this.expressionTypingServices.setCallExpressionResolver(callExpressionResolver);
this.expressionTypingServices.setCallResolver(callResolver);
this.expressionTypingServices.setDescriptorResolver(descriptorResolver);
this.expressionTypingServices.setProject(project);
@@ -91,6 +95,8 @@ public class InjectorForLazyResolve {
this.jetImportsFactory.setProject(project);
callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
callResolver.setExpressionTypingServices(expressionTypingServices);
@@ -19,6 +19,7 @@ package org.jetbrains.jet.di;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver;
@@ -35,6 +36,7 @@ public class InjectorForMacros {
private ExpressionTypingServices expressionTypingServices;
private final Project project;
private final ModuleConfiguration moduleConfiguration;
private CallExpressionResolver callExpressionResolver;
private CallResolver callResolver;
private ArgumentTypeResolver argumentTypeResolver;
private TypeResolver typeResolver;
@@ -50,6 +52,7 @@ public class InjectorForMacros {
this.expressionTypingServices = new ExpressionTypingServices();
this.project = project;
this.moduleConfiguration = moduleConfiguration;
this.callExpressionResolver = new CallExpressionResolver();
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.typeResolver = new TypeResolver();
@@ -58,11 +61,14 @@ public class InjectorForMacros {
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
this.candidateResolver = new CandidateResolver();
this.expressionTypingServices.setCallExpressionResolver(callExpressionResolver);
this.expressionTypingServices.setCallResolver(callResolver);
this.expressionTypingServices.setDescriptorResolver(descriptorResolver);
this.expressionTypingServices.setProject(project);
this.expressionTypingServices.setTypeResolver(typeResolver);
callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
callResolver.setExpressionTypingServices(expressionTypingServices);
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
@@ -68,6 +69,7 @@ public class InjectorForTopDownAnalyzerBasic {
private CallResolver callResolver;
private ArgumentTypeResolver argumentTypeResolver;
private ExpressionTypingServices expressionTypingServices;
private CallExpressionResolver callExpressionResolver;
private TypeResolver typeResolver;
private QualifiedExpressionResolver qualifiedExpressionResolver;
private CandidateResolver candidateResolver;
@@ -104,6 +106,7 @@ public class InjectorForTopDownAnalyzerBasic {
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.expressionTypingServices = new ExpressionTypingServices();
this.callExpressionResolver = new CallExpressionResolver();
this.typeResolver = new TypeResolver();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
this.candidateResolver = new CandidateResolver();
@@ -169,11 +172,14 @@ public class InjectorForTopDownAnalyzerBasic {
argumentTypeResolver.setExpressionTypingServices(expressionTypingServices);
argumentTypeResolver.setTypeResolver(typeResolver);
expressionTypingServices.setCallExpressionResolver(callExpressionResolver);
expressionTypingServices.setCallResolver(callResolver);
expressionTypingServices.setDescriptorResolver(descriptorResolver);
expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver);
callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver);
typeResolver.setDescriptorResolver(descriptorResolver);
typeResolver.setModuleConfiguration(moduleConfiguration);
@@ -22,36 +22,45 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.constants.ConstantUtils;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope;
import org.jetbrains.jet.lang.resolve.scopes.FilteringScope;
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.ReceiverValue;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeInfo;
import org.jetbrains.jet.lang.types.NamespaceType;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.expressions.DataFlowUtils;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingContext;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
import javax.inject.Inject;
import java.util.Collections;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW;
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLUTION_SCOPE;
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
public class CallExpressionResolver {
@NotNull
private ExpressionTypingServices expressionTypingServices;
@Inject
public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) {
this.expressionTypingServices = expressionTypingServices;
}
@Nullable
private static JetType lookupNamespaceOrClassObject(@NotNull JetSimpleNameExpression expression, @NotNull ExpressionTypingContext context) {
private JetType lookupNamespaceOrClassObject(@NotNull JetSimpleNameExpression expression, @NotNull ExpressionTypingContext context) {
Name referencedName = expression.getReferencedNameAsName();
ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
if (classifier != null) {
@@ -97,7 +106,7 @@ public class CallExpressionResolver {
}
@NotNull
private static JetScope getStaticNestedClassesScope(@NotNull ClassDescriptor descriptor) {
private JetScope getStaticNestedClassesScope(@NotNull ClassDescriptor descriptor) {
JetScope innerClassesScope = descriptor.getUnsubstitutedInnerClassesScope();
return new FilteringScope(innerClassesScope, new Predicate<DeclarationDescriptor>() {
@Override
@@ -107,7 +116,7 @@ public class CallExpressionResolver {
});
}
private static boolean furtherNameLookup(
private boolean furtherNameLookup(
@NotNull JetSimpleNameExpression expression,
@NotNull JetType[] result,
@NotNull ExpressionTypingContext context
@@ -126,7 +135,7 @@ public class CallExpressionResolver {
}
@Nullable
private static NamespaceType lookupNamespaceType(@NotNull JetSimpleNameExpression expression, @NotNull ExpressionTypingContext context) {
private NamespaceType lookupNamespaceType(@NotNull JetSimpleNameExpression expression, @NotNull ExpressionTypingContext context) {
Name name = expression.getReferencedNameAsName();
NamespaceDescriptor namespace = context.scope.getNamespace(name);
if (namespace == null) {
@@ -134,7 +143,7 @@ public class CallExpressionResolver {
}
context.trace.record(REFERENCE_TARGET, expression, namespace);
// Construct a NamespaceType with everything from the namespace and with static nested classes of the corresponding class (if any)
// Construct a NamespaceType with everything from the namespace and with nested classes of the corresponding class (if any)
JetScope scope;
ClassifierDescriptor classifier = context.scope.getClassifier(name);
if (classifier instanceof ClassDescriptor) {
@@ -147,7 +156,7 @@ public class CallExpressionResolver {
}
@Nullable
private static ResolvedCall<FunctionDescriptor> getResolvedCallForFunction(
private ResolvedCall<FunctionDescriptor> getResolvedCallForFunction(
@NotNull Call call, @NotNull JetExpression callExpression, @NotNull ReceiverValue receiver,
@NotNull ExpressionTypingContext context, @NotNull boolean[] result
) {
@@ -166,7 +175,7 @@ public class CallExpressionResolver {
}
@Nullable
private static JetType getVariableType(@NotNull JetSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver,
private JetType getVariableType(@NotNull JetSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context, @NotNull boolean[] result) {
TemporaryBindingTrace traceForVariable = TemporaryBindingTrace.create(
@@ -201,7 +210,7 @@ public class CallExpressionResolver {
}
@NotNull
public static JetTypeInfo getSimpleNameExpressionTypeInfo(@NotNull JetSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver,
public JetTypeInfo getSimpleNameExpressionTypeInfo(@NotNull JetSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context) {
boolean[] result = new boolean[1];
@@ -230,13 +239,14 @@ public class CallExpressionResolver {
}
@NotNull
public static JetTypeInfo getCallExpressionTypeInfo(@NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver,
public JetTypeInfo getCallExpressionTypeInfo(@NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context) {
boolean[] result = new boolean[1];
Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression);
TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function call", callExpression);
TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function call",
callExpression);
ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction(call, callExpression, receiver,
context.replaceBindingTrace(traceForFunction), result);
if (result[0]) {
@@ -272,7 +282,7 @@ public class CallExpressionResolver {
return JetTypeInfo.create(null, context.dataFlowInfo);
}
private static void checkSuper(@NotNull ReceiverValue receiverValue, @NotNull OverloadResolutionResults<? extends CallableDescriptor> results,
private void checkSuper(@NotNull ReceiverValue receiverValue, @NotNull OverloadResolutionResults<? extends CallableDescriptor> results,
@NotNull BindingTrace trace, @NotNull JetExpression expression) {
if (!results.isSingleResult()) return;
if (!(receiverValue instanceof ExpressionReceiver)) return;
@@ -286,7 +296,7 @@ public class CallExpressionResolver {
}
@NotNull
public static JetTypeInfo getSelectorReturnTypeInfo(
public JetTypeInfo getSelectorReturnTypeInfo(
@NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode,
@NotNull JetExpression selectorExpression,
@@ -314,4 +324,41 @@ public class CallExpressionResolver {
}
return JetTypeInfo.create(null, context.dataFlowInfo);
}
@NotNull
public JetTypeInfo getQualifiedExpressionTypeInfo(@NotNull JetQualifiedExpression expression, @NotNull ExpressionTypingContext context) {
// TODO : functions as values
JetExpression selectorExpression = expression.getSelectorExpression();
JetExpression receiverExpression = expression.getReceiverExpression();
JetTypeInfo receiverTypeInfo = expressionTypingServices.getTypeInfoWithNamespaces(
receiverExpression, context.scope, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
JetType receiverType = receiverTypeInfo.getType();
if (selectorExpression == null) return JetTypeInfo.create(null, context.dataFlowInfo);
if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText());
context = context.replaceDataFlowInfo(receiverTypeInfo.getDataFlowInfo());
if (selectorExpression instanceof JetSimpleNameExpression) {
ConstantUtils.propagateConstantValues(expression, context.trace, (JetSimpleNameExpression) selectorExpression);
}
JetTypeInfo selectorReturnTypeInfo = getSelectorReturnTypeInfo(
new ExpressionReceiver(receiverExpression, receiverType), expression.getOperationTokenNode(), selectorExpression, context);
JetType selectorReturnType = selectorReturnTypeInfo.getType();
//TODO move further
if (!(receiverType instanceof NamespaceType) && expression.getOperationSign() == JetTokens.SAFE_ACCESS) {
if (selectorReturnType != null && !selectorReturnType.isNullable() && !KotlinBuiltIns.getInstance().isUnit(selectorReturnType)) {
if (receiverType.isNullable()) {
selectorReturnType = TypeUtils.makeNullable(selectorReturnType);
}
}
}
// TODO : this is suspicious: remove this code?
if (selectorReturnType != null) {
context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, selectorReturnType);
}
return DataFlowUtils.checkType(selectorReturnType, expression, context, selectorReturnTypeInfo.getDataFlowInfo());
}
}
@@ -0,0 +1,66 @@
/*
* Copyright 2010-2013 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.constants;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.*;
import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.BYTE;
import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.INT;
public class ConstantUtils {
public static void propagateConstantValues(JetQualifiedExpression expression, BindingTrace trace, JetSimpleNameExpression selectorExpression) {
JetExpression receiverExpression = expression.getReceiverExpression();
CompileTimeConstant<?> receiverValue = trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, receiverExpression);
CompileTimeConstant<?> wholeExpressionValue = trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, expression);
DeclarationDescriptor declarationDescriptor = trace.getBindingContext().get(BindingContext.REFERENCE_TARGET, selectorExpression);
if (wholeExpressionValue == null && receiverValue != null && !(receiverValue instanceof ErrorValue) && receiverValue.getValue() instanceof Number
&& KotlinBuiltIns.getInstance().getNumber() == declarationDescriptor) {
Number value = (Number) receiverValue.getValue();
Name referencedName = selectorExpression.getReferencedNameAsName();
if (OperatorConventions.NUMBER_CONVERSIONS.contains(referencedName)) {
if (DOUBLE.equals(referencedName)) {
trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new DoubleValue(value.doubleValue()));
}
else if (FLOAT.equals(referencedName)) {
trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new FloatValue(value.floatValue()));
}
else if (LONG.equals(referencedName)) {
trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new LongValue(value.longValue()));
}
else if (SHORT.equals(referencedName)) {
trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ShortValue(value.shortValue()));
}
else if (BYTE.equals(referencedName)) {
trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ByteValue(value.byteValue()));
}
else if (INT.equals(referencedName)) {
trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new IntValue(value.intValue()));
}
}
}
}
}
@@ -69,7 +69,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
public JetTypeInfo visitSimpleNameExpression(JetSimpleNameExpression expression, ExpressionTypingContext context) {
// TODO : other members
// TODO : type substitutions???
JetTypeInfo typeInfo = CallExpressionResolver.getSimpleNameExpressionTypeInfo(expression, NO_RECEIVER, null, context);
CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver();
JetTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, NO_RECEIVER, null, context);
JetType type = DataFlowUtils.checkType(typeInfo.getType(), expression, context);
ExpressionTypingUtils.checkWrappingInRef(expression, context.trace, context.scope);
return JetTypeInfo.create(type, typeInfo.getDataFlowInfo()); // TODO : Extensions to this
@@ -589,76 +590,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Override
public JetTypeInfo visitQualifiedExpression(JetQualifiedExpression expression, ExpressionTypingContext context) {
// TODO : functions as values
JetExpression selectorExpression = expression.getSelectorExpression();
JetExpression receiverExpression = expression.getReceiverExpression();
ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE);
JetTypeInfo receiverTypeInfo = facade.getTypeInfo(receiverExpression, contextWithNoExpectedType.replaceNamespacesAllowed(true));
JetType receiverType = receiverTypeInfo.getType();
if (selectorExpression == null) return JetTypeInfo.create(null, context.dataFlowInfo);
if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText());
context = context.replaceDataFlowInfo(receiverTypeInfo.getDataFlowInfo());
if (selectorExpression instanceof JetSimpleNameExpression) {
propagateConstantValues(expression, context, (JetSimpleNameExpression) selectorExpression);
}
JetTypeInfo selectorReturnTypeInfo = CallExpressionResolver.getSelectorReturnTypeInfo(
new ExpressionReceiver(receiverExpression, receiverType), expression.getOperationTokenNode(), selectorExpression, context);
JetType selectorReturnType = selectorReturnTypeInfo.getType();
//TODO move further
if (!(receiverType instanceof NamespaceType) && expression.getOperationSign() == JetTokens.SAFE_ACCESS) {
if (selectorReturnType != null && !selectorReturnType.isNullable() && !KotlinBuiltIns.getInstance().isUnit(selectorReturnType)) {
if (receiverType.isNullable()) {
selectorReturnType = TypeUtils.makeNullable(selectorReturnType);
}
}
}
// TODO : this is suspicious: remove this code?
if (selectorReturnType != null) {
context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, selectorReturnType);
}
return DataFlowUtils.checkType(selectorReturnType, expression, context, selectorReturnTypeInfo.getDataFlowInfo());
}
private static void propagateConstantValues(JetQualifiedExpression expression, ExpressionTypingContext context, JetSimpleNameExpression selectorExpression) {
JetExpression receiverExpression = expression.getReceiverExpression();
CompileTimeConstant<?> receiverValue = context.trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, receiverExpression);
CompileTimeConstant<?> wholeExpressionValue = context.trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, expression);
DeclarationDescriptor declarationDescriptor = context.trace.getBindingContext().get(BindingContext.REFERENCE_TARGET, selectorExpression);
if (wholeExpressionValue == null && receiverValue != null && !(receiverValue instanceof ErrorValue) && receiverValue.getValue() instanceof Number
&& KotlinBuiltIns.getInstance().getNumber() == declarationDescriptor) {
Number value = (Number) receiverValue.getValue();
Name referencedName = selectorExpression.getReferencedNameAsName();
if (OperatorConventions.NUMBER_CONVERSIONS.contains(referencedName)) {
if (DOUBLE.equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new DoubleValue(value.doubleValue()));
}
else if (FLOAT.equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new FloatValue(value.floatValue()));
}
else if (LONG.equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new LongValue(value.longValue()));
}
else if (SHORT.equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ShortValue(value.shortValue()));
}
else if (BYTE.equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ByteValue(value.byteValue()));
}
else if (INT.equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new IntValue(value.intValue()));
}
}
}
CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver();
return callExpressionResolver.getQualifiedExpressionTypeInfo(expression, context);
}
@Override
public JetTypeInfo visitCallExpression(JetCallExpression expression, ExpressionTypingContext context) {
JetTypeInfo expressionTypeInfo = CallExpressionResolver.getCallExpressionTypeInfo(expression, NO_RECEIVER, null, context);
CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver();
JetTypeInfo expressionTypeInfo = callExpressionResolver.getCallExpressionTypeInfo(expression, NO_RECEIVER, null, context);
return DataFlowUtils.checkType(expressionTypeInfo.getType(), expression, context, expressionTypeInfo.getDataFlowInfo());
}
@@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -61,6 +62,8 @@ public class ExpressionTypingServices {
@NotNull
private CallResolver callResolver;
@NotNull
private CallExpressionResolver callExpressionResolver;
@NotNull
private DescriptorResolver descriptorResolver;
@NotNull
private TypeResolver typeResolver;
@@ -87,6 +90,16 @@ public class ExpressionTypingServices {
this.callResolver = callResolver;
}
@NotNull
public CallExpressionResolver getCallExpressionResolver() {
return callExpressionResolver;
}
@Inject
public void setCallExpressionResolver(@NotNull CallExpressionResolver callExpressionResolver) {
this.callExpressionResolver = callExpressionResolver;
}
@NotNull
public DescriptorResolver getDescriptorResolver() {
return descriptorResolver;
@@ -128,11 +141,10 @@ public class ExpressionTypingServices {
return getTypeInfo(scope, expression, expectedType, dataFlowInfo, trace).getType();
}
public JetType getTypeWithNamespaces(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull BindingTrace trace) {
public JetTypeInfo getTypeInfoWithNamespaces(@NotNull JetExpression expression, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace) {
ExpressionTypingContext context = ExpressionTypingContext.newContext(
this, trace, scope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, true);
return expressionTypingFacade.getTypeInfo(expression, context).getType();
// return ((ExpressionTypingContext) ExpressionTyperVisitorWithNamespaces).INSTANCE.getType(expression, ExpressionTypingContext.newRootContext(semanticServices, trace, scope, DataFlowInfo.getEmpty(), TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE));
this, trace, scope, dataFlowInfo, expectedType, true);
return expressionTypingFacade.getTypeInfo(expression, context);
}
@NotNull
@@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lang.ModuleConfiguration;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
@@ -41,6 +42,7 @@ public class InjectorForTests {
private ModuleConfiguration moduleConfiguration;
private final Project project;
private AnnotationResolver annotationResolver;
private CallExpressionResolver callExpressionResolver;
private QualifiedExpressionResolver qualifiedExpressionResolver;
private ArgumentTypeResolver argumentTypeResolver;
private CandidateResolver candidateResolver;
@@ -56,6 +58,7 @@ public class InjectorForTests {
this.moduleConfiguration = ModuleConfiguration.EMPTY;
this.project = project;
this.annotationResolver = new AnnotationResolver();
this.callExpressionResolver = new CallExpressionResolver();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.candidateResolver = new CandidateResolver();
@@ -64,6 +67,7 @@ public class InjectorForTests {
this.descriptorResolver.setExpressionTypingServices(expressionTypingServices);
this.descriptorResolver.setTypeResolver(typeResolver);
this.expressionTypingServices.setCallExpressionResolver(callExpressionResolver);
this.expressionTypingServices.setCallResolver(callResolver);
this.expressionTypingServices.setDescriptorResolver(descriptorResolver);
this.expressionTypingServices.setProject(project);
@@ -82,6 +86,8 @@ public class InjectorForTests {
annotationResolver.setCallResolver(callResolver);
annotationResolver.setExpressionTypingServices(expressionTypingServices);
callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
argumentTypeResolver.setExpressionTypingServices(expressionTypingServices);
argumentTypeResolver.setTypeResolver(typeResolver);
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
@@ -68,6 +69,7 @@ public class InjectorForTopDownAnalyzerForJs {
private CallResolver callResolver;
private ArgumentTypeResolver argumentTypeResolver;
private ExpressionTypingServices expressionTypingServices;
private CallExpressionResolver callExpressionResolver;
private TypeResolver typeResolver;
private QualifiedExpressionResolver qualifiedExpressionResolver;
private CandidateResolver candidateResolver;
@@ -104,6 +106,7 @@ public class InjectorForTopDownAnalyzerForJs {
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.expressionTypingServices = new ExpressionTypingServices();
this.callExpressionResolver = new CallExpressionResolver();
this.typeResolver = new TypeResolver();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
this.candidateResolver = new CandidateResolver();
@@ -169,11 +172,14 @@ public class InjectorForTopDownAnalyzerForJs {
argumentTypeResolver.setExpressionTypingServices(expressionTypingServices);
argumentTypeResolver.setTypeResolver(typeResolver);
expressionTypingServices.setCallExpressionResolver(callExpressionResolver);
expressionTypingServices.setCallResolver(callResolver);
expressionTypingServices.setDescriptorResolver(descriptorResolver);
expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver);
callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver);
typeResolver.setDescriptorResolver(descriptorResolver);
typeResolver.setModuleConfiguration(moduleConfiguration);