Resolve compileTimeInitializer for variable in lazy resolve
This commit is contained in:
+2
-1
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorFactory;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
@@ -196,7 +197,7 @@ public class DescriptorSerializer {
|
||||
}
|
||||
}
|
||||
|
||||
hasConstant = !propertyDescriptor.isVar() && propertyDescriptor.getCompileTimeInitializer() != null;
|
||||
hasConstant = propertyDescriptor.getCompileTimeInitializer() != null;
|
||||
}
|
||||
|
||||
builder.setFlags(Flags.getCallableFlags(
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.resolve.calls.context.ResolutionResultsCacheImpl;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.SimpleResolutionContext;
|
||||
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.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
@@ -565,7 +566,10 @@ public class BodyResolver {
|
||||
JetScope propertyDeclarationInnerScope = JetScopeUtils.getPropertyDeclarationInnerScopeForInitializer(
|
||||
scope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace);
|
||||
JetType expectedTypeForInitializer = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
|
||||
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer, c.getOuterDataFlowInfo(), trace);
|
||||
CompileTimeConstant<?> compileTimeInitializer = propertyDescriptor.getCompileTimeInitializer();
|
||||
if (compileTimeInitializer == null) {
|
||||
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer, c.getOuterDataFlowInfo(), trace);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -959,7 +959,7 @@ public class DescriptorResolver {
|
||||
@Override
|
||||
public JetType invoke() {
|
||||
JetType initializerType = resolveInitializerType(scope, initializer, dataFlowInfo, trace);
|
||||
setConstantForVariableIfNeeded(variableDescriptor, initializer, initializerType, trace);
|
||||
setConstantForVariableIfNeeded(variableDescriptor, scope, variable, dataFlowInfo, initializerType, trace);
|
||||
return transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace);
|
||||
}
|
||||
}
|
||||
@@ -967,40 +967,45 @@ public class DescriptorResolver {
|
||||
}
|
||||
else {
|
||||
JetType initializerType = resolveInitializerType(scope, initializer, dataFlowInfo, trace);
|
||||
setConstantForVariableIfNeeded(variableDescriptor, initializer, initializerType, trace);
|
||||
setConstantForVariableIfNeeded(variableDescriptor, scope, variable, dataFlowInfo, initializerType, trace);
|
||||
return initializerType;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
JetType type = typeResolver.resolveType(scope, propertyTypeRef, trace, true);
|
||||
JetExpression initializer = variable.getInitializer();
|
||||
if (initializer != null) {
|
||||
setConstantForVariableIfNeeded(variableDescriptor, initializer, type, trace);
|
||||
}
|
||||
setConstantForVariableIfNeeded(variableDescriptor, scope, variable, dataFlowInfo, type, trace);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
private void setConstantForVariableIfNeeded(
|
||||
@NotNull VariableDescriptorImpl variableDescriptor,
|
||||
@NotNull final JetExpression initializer,
|
||||
@NotNull final JetType initializerType,
|
||||
@NotNull final JetScope scope,
|
||||
@NotNull JetVariableDeclaration variable,
|
||||
@NotNull final DataFlowInfo dataFlowInfo,
|
||||
@NotNull final JetType variableType,
|
||||
@NotNull final BindingTrace trace
|
||||
) {
|
||||
if (variableDescriptor.isVar()) return;
|
||||
if (!shouldRecordInitializerForProperty(variableDescriptor, variableType)) return;
|
||||
|
||||
variableDescriptor.setCompileTimeInitializer(storageManager.createRecursionTolerantNullableLazyValue(new Function0<CompileTimeConstant<?>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public CompileTimeConstant<?> invoke() {
|
||||
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.object$.evaluate(initializer, trace, initializerType);
|
||||
if ((constant instanceof IntegerValueTypeConstant)) {
|
||||
return EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) constant, initializerType);
|
||||
final JetExpression initializer = variable.getInitializer();
|
||||
if (initializer == null) return;
|
||||
|
||||
variableDescriptor.setCompileTimeInitializer(
|
||||
storageManager.createRecursionTolerantNullableLazyValue(new Function0<CompileTimeConstant<?>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public CompileTimeConstant<?> invoke() {
|
||||
JetType initializerType = expressionTypingServices.safeGetType(scope, initializer, variableType, dataFlowInfo, trace);
|
||||
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.object$.evaluate(initializer, trace, initializerType);
|
||||
if (constant instanceof IntegerValueTypeConstant) {
|
||||
return EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) constant, initializerType);
|
||||
}
|
||||
return constant;
|
||||
}
|
||||
return constant;
|
||||
}
|
||||
}, null));
|
||||
}, null)
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package test
|
||||
|
||||
// val prop1: 1
|
||||
val prop1: Int = 1
|
||||
|
||||
// val prop2: 1
|
||||
val prop2: Int? = 1
|
||||
|
||||
// val prop3: 1
|
||||
val prop3: Number? = 1
|
||||
|
||||
// val prop4: 1
|
||||
val prop4: Any? = 1
|
||||
|
||||
// val prop5: 1
|
||||
val prop5: Number = 1
|
||||
|
||||
// val prop6: 1
|
||||
val prop6: Any = 1
|
||||
|
||||
// val prop7: \"a\"
|
||||
val prop7: String = "a"
|
||||
|
||||
// val prop8: \"a\"
|
||||
val prop8: String? = "a"
|
||||
|
||||
// val prop9: \"a\"
|
||||
val prop9: Any? = "a"
|
||||
|
||||
// val prop10: \"a\"
|
||||
val prop10: Any = "a"
|
||||
|
||||
// val prop11: null
|
||||
val prop11: aaa = 1
|
||||
|
||||
// val prop14: null
|
||||
val prop14: aaa? = 1
|
||||
|
||||
class A
|
||||
|
||||
// val prop15: null
|
||||
val prop15: A = 1
|
||||
|
||||
// val prop16: 1
|
||||
val prop16: A? = 1
|
||||
@@ -1,34 +1,34 @@
|
||||
package test
|
||||
|
||||
// val prop1: Division by zero
|
||||
// val prop1: null
|
||||
val prop1 = 1 / 0
|
||||
|
||||
// val prop2: Division by zero
|
||||
// val prop2: null
|
||||
val prop2 = 1 / 0.0
|
||||
|
||||
// val prop3: Division by zero
|
||||
// val prop3: null
|
||||
val prop3 = 1.0 / 0
|
||||
|
||||
// val prop4: 10.0.toDouble()
|
||||
val prop4 = 1 / 0.1
|
||||
|
||||
// val prop5: Division by zero
|
||||
// val prop5: null
|
||||
val prop5 = 1 / 0.toLong()
|
||||
|
||||
// val prop6: Division by zero
|
||||
// val prop6: null
|
||||
val prop6 = 1.0 / 0.toInt()
|
||||
|
||||
// val prop7: Division by zero
|
||||
// val prop7: null
|
||||
val prop7 = 1.0 / 0.toLong()
|
||||
|
||||
// val prop8: Division by zero
|
||||
// val prop8: null
|
||||
val prop8 = 1.0 / 0.toByte()
|
||||
|
||||
// val prop9: Division by zero
|
||||
// val prop9: null
|
||||
val prop9 = 1.0 / 0.toShort()
|
||||
|
||||
// val prop10: Division by zero
|
||||
// val prop10: null
|
||||
val prop10 = 1.0 / 0.toFloat()
|
||||
|
||||
// val prop11: Division by zero
|
||||
// val prop11: null
|
||||
val prop11 = 1.0 / 0.toDouble()
|
||||
@@ -0,0 +1,6 @@
|
||||
package test;
|
||||
|
||||
public final class ClassWithConstVal {
|
||||
public final int f = 1;
|
||||
public final int f2 = f;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package test
|
||||
|
||||
public class ClassWithConstVal() : java.lang.Object() {
|
||||
public val f: Int = 1
|
||||
public val f2: Int = f
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
public final class ClassWithConstVal : java.lang.Object {
|
||||
public constructor ClassWithConstVal()
|
||||
public final val f: kotlin.Int = 1
|
||||
public final val f2: kotlin.Int = 1
|
||||
}
|
||||
@@ -48,6 +48,11 @@ public class EvaluateExpressionTestGenerated extends AbstractEvaluateExpressionT
|
||||
doConstantTest("compiler/testData/evaluate/constant/compareTo.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("differentTypes.kt")
|
||||
public void testDifferentTypes() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/differentTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("divideByZero.kt")
|
||||
public void testDivideByZero() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/divideByZero.kt");
|
||||
|
||||
@@ -546,6 +546,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
||||
doTestCompiledJavaCompareWithKotlin("compiler/testData/loadJava/compiledJavaCompareWithKotlin/ClassDoesNotOverrideMethod.java");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithConstVal.java")
|
||||
public void testClassWithConstVal() throws Exception {
|
||||
doTestCompiledJavaCompareWithKotlin("compiler/testData/loadJava/compiledJavaCompareWithKotlin/ClassWithConstVal.java");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithTypeP.java")
|
||||
public void testClassWithTypeP() throws Exception {
|
||||
doTestCompiledJavaCompareWithKotlin("compiler/testData/loadJava/compiledJavaCompareWithKotlin/ClassWithTypeP.java");
|
||||
|
||||
+5
@@ -1509,6 +1509,11 @@ public class LazyResolveRecursiveComparingTestGenerated extends AbstractLazyReso
|
||||
doTestNotCheckingPrimaryConstructors("compiler/testData/loadJava/compiledJavaCompareWithKotlin/ClassDoesNotOverrideMethod.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithConstVal.kt")
|
||||
public void testClassWithConstVal() throws Exception {
|
||||
doTestNotCheckingPrimaryConstructors("compiler/testData/loadJava/compiledJavaCompareWithKotlin/ClassWithConstVal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithTypeP.kt")
|
||||
public void testClassWithTypeP() throws Exception {
|
||||
doTestNotCheckingPrimaryConstructors("compiler/testData/loadJava/compiledJavaCompareWithKotlin/ClassWithTypeP.kt");
|
||||
|
||||
+1
-1
@@ -266,7 +266,7 @@ public abstract class LazyJavaMemberScope(
|
||||
|
||||
propertyDescriptor.setType(effectiveSignature.getReturnType(), Collections.emptyList(), DescriptorUtils.getExpectedThisObjectIfNeeded(getContainingDeclaration()), null : JetType?)
|
||||
|
||||
if (!propertyDescriptor.isVar()) {
|
||||
if (DescriptorUtils.shouldRecordInitializerForProperty(propertyDescriptor, propertyDescriptor.getType())) {
|
||||
propertyDescriptor.setCompileTimeInitializer(
|
||||
c.storageManager.createNullableLazyValue {
|
||||
JavaPropertyInitializerEvaluator.getInstance().getInitializerConstant(field, propertyDescriptor)
|
||||
|
||||
@@ -495,4 +495,16 @@ public class DescriptorUtils {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean shouldRecordInitializerForProperty(@NotNull VariableDescriptor variable, @NotNull JetType type) {
|
||||
if (variable.isVar() || type.isError()) return false;
|
||||
|
||||
if (type instanceof LazyType || type.isNullable()) return true;
|
||||
|
||||
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
|
||||
return builtIns.isPrimitiveType(type) ||
|
||||
builtIns.getStringType().equals(type) ||
|
||||
builtIns.getNumber().getDefaultType().equals(type) ||
|
||||
builtIns.getAnyType().equals(type);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user