Get call expression type from compile time value if possible

This commit is contained in:
Natalia Ukhorskaya
2013-12-03 18:46:44 +04:00
parent e6c442ba04
commit e805478d6c
5 changed files with 42 additions and 2 deletions
@@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
@@ -34,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsUtil;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -41,6 +43,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.expressions.BasicExpressionTypingVisitor;
import org.jetbrains.jet.lang.types.expressions.DataFlowUtils;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingContext;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
@@ -434,6 +437,12 @@ public class CallExpressionResolver {
if (selectorReturnType != null) {
context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, selectorReturnType);
}
CompileTimeConstant<?> value = ConstantExpressionEvaluator.object$.evaluate(expression, context.trace, context.expectedType);
if (value != null) {
return BasicExpressionTypingVisitor.createCompileTimeConstantTypeInfo(value, expression, context);
}
JetTypeInfo typeInfo = JetTypeInfo.create(selectorReturnType, selectorReturnTypeInfo.getDataFlowInfo());
if (context.contextDependency == INDEPENDENT) {
DataFlowUtils.checkType(typeInfo, expression, context);
@@ -705,7 +705,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}
@NotNull
private static JetTypeInfo createCompileTimeConstantTypeInfo(
public static JetTypeInfo createCompileTimeConstantTypeInfo(
@NotNull CompileTimeConstant<?> value,
@NotNull JetExpression expression,
@NotNull ExpressionTypingContext context
@@ -0,0 +1,26 @@
fun fooInt(p: Int) = p
fun fooLong(p: Long) = p
fun fooByte(p: Byte) = p
fun fooShort(p: Short) = p
fun test() {
fooInt(1.plus(1))
fooByte(1.plus(1))
fooLong(1.plus(1))
fooShort(1.plus(1))
fooInt(1.times(1))
fooByte(1.times(1))
fooLong(1.times(1))
fooShort(1.times(1))
fooInt(1.div(1))
fooByte(1.div(1))
fooLong(1.div(1))
fooShort(1.div(1))
fooInt(1.mod(1))
fooByte(1.mod(1))
fooLong(1.mod(1))
fooShort(1.mod(1))
}
@@ -10,4 +10,4 @@ annotation class Ann(
Ann(1.plus(1), 1.minus(1), 1.times(1), 1.div(1), 1.mod(1)) class MyClass
// EXPECTED: Ann[p1 = 2.toInt(): jet.Int, p2 = 0.toInt(): jet.Int, p3 = 1.toInt(): jet.Int, p4 = 1.toInt(): jet.Int, p5 = 0.toInt(): jet.Int]
// EXPECTED: Ann[p1 = IntegerValueType(2): IntegerValueType(2), p2 = IntegerValueType(0): IntegerValueType(0), p3 = IntegerValueType(1): IntegerValueType(1), p4 = IntegerValueType(1): IntegerValueType(1), p5 = IntegerValueType(0): IntegerValueType(0)]
@@ -2764,6 +2764,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/evaluate/numberBinaryOperations.kt");
}
@TestMetadata("numberBinaryOperationsCall.kt")
public void testNumberBinaryOperationsCall() throws Exception {
doTest("compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsCall.kt");
}
@TestMetadata("otherOverflow.kt")
public void testOtherOverflow() throws Exception {
doTest("compiler/testData/diagnostics/tests/evaluate/otherOverflow.kt");