Split CompileTimeConstant into two entities
1. ConstantValue * just holds some value and its type * implementations for concrete constants 2. CompileTimeConstant * is only produced by ConstantExpressionEvaluator * has additional flags (canBeUsedInAnnotation etc) * has two implementations TypedCompileTimeConstant containing a constant value and IntegerValueConstant which does not have exact type * can be converted to ConstantValue Adjustt usages to use ConstantValue if flags are not needed Add tests for some uncovered cases
This commit is contained in:
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
|
||||
@@ -210,16 +211,16 @@ public class AnnotationResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<ValueParameterDescriptor, CompileTimeConstant<?>> resolveAnnotationArguments(
|
||||
public static Map<ValueParameterDescriptor, ConstantValue<?>> resolveAnnotationArguments(
|
||||
@NotNull ResolvedCall<?> resolvedCall,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
Map<ValueParameterDescriptor, CompileTimeConstant<?>> arguments = new HashMap<ValueParameterDescriptor, CompileTimeConstant<?>>();
|
||||
Map<ValueParameterDescriptor, ConstantValue<?>> arguments = new HashMap<ValueParameterDescriptor, ConstantValue<?>>();
|
||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument : resolvedCall.getValueArguments().entrySet()) {
|
||||
ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey();
|
||||
ResolvedValueArgument resolvedArgument = descriptorToArgument.getValue();
|
||||
|
||||
CompileTimeConstant<?> value = getAnnotationArgumentValue(trace, parameterDescriptor, resolvedArgument);
|
||||
ConstantValue<?> value = getAnnotationArgumentValue(trace, parameterDescriptor, resolvedArgument);
|
||||
if (value != null) {
|
||||
arguments.put(parameterDescriptor, value);
|
||||
}
|
||||
@@ -228,32 +229,30 @@ public class AnnotationResolver {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CompileTimeConstant<?> getAnnotationArgumentValue(
|
||||
public static ConstantValue<?> getAnnotationArgumentValue(
|
||||
BindingTrace trace,
|
||||
ValueParameterDescriptor parameterDescriptor,
|
||||
ResolvedValueArgument resolvedArgument
|
||||
) {
|
||||
JetType varargElementType = parameterDescriptor.getVarargElementType();
|
||||
boolean argumentsAsVararg = varargElementType != null && !hasSpread(resolvedArgument);
|
||||
List<CompileTimeConstant<?>> constants = resolveValueArguments(
|
||||
resolvedArgument, argumentsAsVararg ? varargElementType : parameterDescriptor.getType(), trace);
|
||||
final JetType constantType = argumentsAsVararg ? varargElementType : parameterDescriptor.getType();
|
||||
List<CompileTimeConstant<?>> compileTimeConstants = resolveValueArguments(resolvedArgument, constantType, trace);
|
||||
List<ConstantValue<?>> constants = KotlinPackage.map(compileTimeConstants, new Function1<CompileTimeConstant<?>, ConstantValue<?>>() {
|
||||
@Override
|
||||
public ConstantValue<?> invoke(CompileTimeConstant<?> constant) {
|
||||
return constant.toConstantValue(constantType);
|
||||
}
|
||||
});
|
||||
|
||||
if (argumentsAsVararg) {
|
||||
if (parameterDescriptor.declaresDefaultValue() && compileTimeConstants.isEmpty()) return null;
|
||||
|
||||
boolean usesVariableAsConstant = KotlinPackage.any(constants, new Function1<CompileTimeConstant<?>, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(CompileTimeConstant<?> constant) {
|
||||
return constant.usesVariableAsConstant();
|
||||
}
|
||||
});
|
||||
|
||||
if (parameterDescriptor.declaresDefaultValue() && constants.isEmpty()) return null;
|
||||
|
||||
return new ArrayValue(constants, parameterDescriptor.getType(), usesVariableAsConstant);
|
||||
return new ArrayValue(constants, parameterDescriptor.getType());
|
||||
}
|
||||
else {
|
||||
// we should actually get only one element, but just in case of getting many, we take the last one
|
||||
return !constants.isEmpty() ? KotlinPackage.last(constants) : null;
|
||||
return KotlinPackage.lastOrNull(constants);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +279,7 @@ public class AnnotationResolver {
|
||||
}
|
||||
|
||||
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.getConstant(argumentExpression, trace.getBindingContext());
|
||||
if (constant != null && constant.canBeUsedInAnnotations()) {
|
||||
if (constant != null && constant.getCanBeUsedInAnnotations()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
|
||||
import org.jetbrains.kotlin.resolve.scopes.*;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
@@ -735,8 +734,7 @@ public class BodyResolver {
|
||||
JetScope propertyDeclarationInnerScope = JetScopeUtils.getPropertyDeclarationInnerScopeForInitializer(
|
||||
propertyDescriptor, scope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace);
|
||||
JetType expectedTypeForInitializer = property.getTypeReference() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
|
||||
CompileTimeConstant<?> compileTimeInitializer = propertyDescriptor.getCompileTimeInitializer();
|
||||
if (compileTimeInitializer == null) {
|
||||
if (propertyDescriptor.getCompileTimeInitializer() == null) {
|
||||
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer,
|
||||
outerDataFlowInfo, trace);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.psi.JetTypeReference;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.constants.BooleanValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.TypeProjection;
|
||||
@@ -113,7 +115,7 @@ public class CompileTimeConstantUtils {
|
||||
annotatedDescriptor.getAnnotations().findAnnotation(new FqName("kotlin.jvm.internal.Intrinsic"));
|
||||
if (intrinsicAnnotation == null) return null;
|
||||
|
||||
Collection<CompileTimeConstant<?>> values = intrinsicAnnotation.getAllValueArguments().values();
|
||||
Collection<ConstantValue<?>> values = intrinsicAnnotation.getAllValueArguments().values();
|
||||
if (values.isEmpty()) return null;
|
||||
|
||||
Object value = values.iterator().next().getValue();
|
||||
@@ -132,9 +134,13 @@ public class CompileTimeConstantUtils {
|
||||
if (expression == null) return false;
|
||||
CompileTimeConstant<?> compileTimeConstant =
|
||||
ConstantExpressionEvaluator.evaluate(expression, trace, KotlinBuiltIns.getInstance().getBooleanType());
|
||||
if (!(compileTimeConstant instanceof BooleanValue) || compileTimeConstant.usesVariableAsConstant()) return false;
|
||||
if (!(compileTimeConstant instanceof TypedCompileTimeConstant) || compileTimeConstant.getUsesVariableAsConstant()) return false;
|
||||
|
||||
Boolean value = ((BooleanValue) compileTimeConstant).getValue();
|
||||
ConstantValue constantValue = ((TypedCompileTimeConstant) compileTimeConstant).getConstantValue();
|
||||
|
||||
if (!(constantValue instanceof BooleanValue)) return false;
|
||||
|
||||
Boolean value = ((BooleanValue) constantValue).getValue();
|
||||
return expectedValue == null || expectedValue.equals(value);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,10 +37,8 @@ import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.EvaluatePackage;
|
||||
import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsPackage;
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||
@@ -868,17 +866,13 @@ public class DescriptorResolver {
|
||||
if (!variable.hasInitializer()) return;
|
||||
|
||||
variableDescriptor.setCompileTimeInitializer(
|
||||
storageManager.createRecursionTolerantNullableLazyValue(new Function0<CompileTimeConstant<?>>() {
|
||||
storageManager.createRecursionTolerantNullableLazyValue(new Function0<ConstantValue<?>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public CompileTimeConstant<?> invoke() {
|
||||
public ConstantValue<?> invoke() {
|
||||
JetExpression initializer = variable.getInitializer();
|
||||
JetType initializerType = expressionTypingServices.safeGetType(scope, initializer, variableType, dataFlowInfo, trace);
|
||||
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.evaluate(initializer, trace, initializerType);
|
||||
if (constant instanceof IntegerValueTypeConstant) {
|
||||
return EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) constant, initializerType);
|
||||
}
|
||||
return constant;
|
||||
return ConstantExpressionEvaluator.evaluateToConstantValue(initializer, trace, initializerType);
|
||||
}
|
||||
}, null)
|
||||
);
|
||||
|
||||
@@ -26,13 +26,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.*;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue;
|
||||
|
||||
import java.util.*;
|
||||
@@ -302,9 +302,9 @@ public class ModifiersChecker {
|
||||
}
|
||||
|
||||
String value = null;
|
||||
Collection<CompileTimeConstant<?>> values = annotation.getAllValueArguments().values();
|
||||
Collection<ConstantValue<?>> values = annotation.getAllValueArguments().values();
|
||||
if (!values.isEmpty()) {
|
||||
CompileTimeConstant<?> name = values.iterator().next();
|
||||
ConstantValue<?> name = values.iterator().next();
|
||||
if (name instanceof StringValue) {
|
||||
value = ((StringValue) name).getValue();
|
||||
}
|
||||
|
||||
+1
-2
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*;
|
||||
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||
@@ -369,7 +368,7 @@ public class CallExpressionResolver {
|
||||
}
|
||||
|
||||
CompileTimeConstant<?> value = ConstantExpressionEvaluator.evaluate(expression, context.trace, context.expectedType);
|
||||
if (value instanceof IntegerValueConstant && ((IntegerValueConstant) value).isPure()) {
|
||||
if (value != null && value.getIsPure()) {
|
||||
return ExpressionTypingUtils.createCompileTimeConstantTypeInfo(value, expression, context);
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classObjectType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getClassObjectReferenceTarget
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassObjectType
|
||||
@@ -59,7 +58,7 @@ public class FakeCallableDescriptorForObject(
|
||||
|
||||
override fun getOriginal(): CallableDescriptor = this
|
||||
|
||||
override fun getCompileTimeInitializer(): CompileTimeConstant<out Any?>? = null
|
||||
override fun getCompileTimeInitializer() = null
|
||||
|
||||
override fun getSource(): SourceElement = classDescriptor.getSource()
|
||||
}
|
||||
|
||||
+4
-4
@@ -51,7 +51,7 @@ public class CompileTimeConstantChecker {
|
||||
|
||||
// return true if there is an error
|
||||
public boolean checkConstantExpressionType(
|
||||
@Nullable CompileTimeConstant compileTimeConstant,
|
||||
@Nullable ConstantValue<?> compileTimeConstant,
|
||||
@NotNull JetConstantExpression expression,
|
||||
@NotNull JetType expectedType
|
||||
) {
|
||||
@@ -76,7 +76,7 @@ public class CompileTimeConstantChecker {
|
||||
}
|
||||
|
||||
private boolean checkIntegerValue(
|
||||
@Nullable CompileTimeConstant value,
|
||||
@Nullable ConstantValue<?> value,
|
||||
@NotNull JetType expectedType,
|
||||
@NotNull JetConstantExpression expression
|
||||
) {
|
||||
@@ -98,7 +98,7 @@ public class CompileTimeConstantChecker {
|
||||
}
|
||||
|
||||
private boolean checkFloatValue(
|
||||
@Nullable CompileTimeConstant value,
|
||||
@Nullable ConstantValue<?> value,
|
||||
@NotNull JetType expectedType,
|
||||
@NotNull JetConstantExpression expression
|
||||
) {
|
||||
@@ -125,7 +125,7 @@ public class CompileTimeConstantChecker {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkCharValue(CompileTimeConstant<?> constant, JetType expectedType, JetConstantExpression expression) {
|
||||
private boolean checkCharValue(ConstantValue<?> constant, JetType expectedType, JetConstantExpression expression) {
|
||||
if (!noExpectedTypeOrError(expectedType)
|
||||
&& !JetTypeChecker.DEFAULT.isSubtypeOf(builtIns.getCharType(), expectedType)) {
|
||||
return reportError(CONSTANT_EXPECTED_TYPE_MISMATCH.on(expression, "character", expectedType));
|
||||
|
||||
+118
-103
@@ -41,31 +41,26 @@ import java.math.BigInteger
|
||||
import kotlin.platform.platformStatic
|
||||
|
||||
public class ConstantExpressionEvaluator private constructor(val trace: BindingTrace) : JetVisitor<CompileTimeConstant<*>, JetType>() {
|
||||
|
||||
private val builtIns = KotlinBuiltIns.getInstance()
|
||||
private val factory = ConstantValueFactory(KotlinBuiltIns.getInstance())
|
||||
|
||||
companion object {
|
||||
platformStatic public fun evaluate(expression: JetExpression, trace: BindingTrace, expectedType: JetType? = TypeUtils.NO_EXPECTED_TYPE): CompileTimeConstant<*>? {
|
||||
val evaluator = ConstantExpressionEvaluator(trace)
|
||||
val constant = evaluator.evaluate(expression, expectedType)
|
||||
return if (constant !is ErrorValue) constant else null
|
||||
val constant = evaluator.evaluate(expression, expectedType) ?: return null
|
||||
return if (!constant.isError) constant else null
|
||||
}
|
||||
|
||||
platformStatic public fun isPropertyCompileTimeConstant(descriptor: VariableDescriptor): Boolean {
|
||||
if (descriptor.isVar()) {
|
||||
return false
|
||||
}
|
||||
if (DescriptorUtils.isObject(descriptor.getContainingDeclaration()) ||
|
||||
DescriptorUtils.isStaticDeclaration(descriptor)) {
|
||||
val returnType = descriptor.getType()
|
||||
return KotlinBuiltIns.isPrimitiveType(returnType) || KotlinBuiltIns.isString(returnType)
|
||||
}
|
||||
return false
|
||||
platformStatic public fun evaluateToConstantValue(
|
||||
expression: JetExpression,
|
||||
trace: BindingTrace,
|
||||
expectedType: JetType
|
||||
): ConstantValue<*>? {
|
||||
return evaluate(expression, trace, expectedType)?.toConstantValue(expectedType)
|
||||
}
|
||||
|
||||
platformStatic public fun getConstant(expression: JetExpression, bindingContext: BindingContext): CompileTimeConstant<*>? {
|
||||
val constant = getPossiblyErrorConstant(expression, bindingContext)
|
||||
return if (constant !is ErrorValue) constant else null
|
||||
val constant = getPossiblyErrorConstant(expression, bindingContext) ?: return null
|
||||
return if (!constant.isError) constant else null
|
||||
}
|
||||
|
||||
platformStatic private fun getPossiblyErrorConstant(expression: JetExpression, bindingContext: BindingContext): CompileTimeConstant<*>? {
|
||||
@@ -87,30 +82,38 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
return null
|
||||
}
|
||||
|
||||
private val stringExpressionEvaluator = object : JetVisitor<StringValue, Nothing>() {
|
||||
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.Impl(true, false, false), builtIns)
|
||||
private val stringExpressionEvaluator = object : JetVisitor<TypedCompileTimeConstant<String>, Nothing>() {
|
||||
private fun createStringConstant(compileTimeConstant: CompileTimeConstant<*>): TypedCompileTimeConstant<String>? {
|
||||
val constantValue = compileTimeConstant.toConstantValue(TypeUtils.NO_EXPECTED_TYPE)
|
||||
return when (constantValue) {
|
||||
is ErrorValue, is EnumValue -> return null
|
||||
is NullValue -> factory.createStringValue("null")
|
||||
else -> factory.createStringValue(constantValue.value.toString())
|
||||
}.wrap(compileTimeConstant.parameters)
|
||||
}
|
||||
|
||||
fun evaluate(entry: JetStringTemplateEntry): StringValue? {
|
||||
fun evaluate(entry: JetStringTemplateEntry): TypedCompileTimeConstant<String>? {
|
||||
return entry.accept(this, null)
|
||||
}
|
||||
|
||||
override fun visitStringTemplateEntryWithExpression(entry: JetStringTemplateEntryWithExpression, data: Nothing?): StringValue? {
|
||||
val expression = entry.getExpression()
|
||||
if (expression == null) return null
|
||||
override fun visitStringTemplateEntryWithExpression(entry: JetStringTemplateEntryWithExpression, data: Nothing?): TypedCompileTimeConstant<String>? {
|
||||
val expression = entry.getExpression() ?: return null
|
||||
|
||||
return createStringConstant(this@ConstantExpressionEvaluator.evaluate(expression, KotlinBuiltIns.getInstance().getStringType()))
|
||||
return this@ConstantExpressionEvaluator.evaluate(expression, KotlinBuiltIns.getInstance().getStringType())?.let {
|
||||
createStringConstant(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitLiteralStringTemplateEntry(entry: JetLiteralStringTemplateEntry, data: Nothing?) = factory.createStringValue(entry.getText())
|
||||
override fun visitLiteralStringTemplateEntry(entry: JetLiteralStringTemplateEntry, data: Nothing?) = factory.createStringValue(entry.getText()).wrap()
|
||||
|
||||
override fun visitEscapeStringTemplateEntry(entry: JetEscapeStringTemplateEntry, data: Nothing?) = factory.createStringValue(entry.getUnescapedValue())
|
||||
override fun visitEscapeStringTemplateEntry(entry: JetEscapeStringTemplateEntry, data: Nothing?) = factory.createStringValue(entry.getUnescapedValue()).wrap()
|
||||
}
|
||||
|
||||
override fun visitConstantExpression(expression: JetConstantExpression, expectedType: JetType?): CompileTimeConstant<*>? {
|
||||
val text = expression.getText() ?: return null
|
||||
|
||||
val nodeElementType = expression.getNode().getElementType()
|
||||
if (nodeElementType == JetNodeTypes.NULL) return NullValue(builtIns)
|
||||
if (nodeElementType == JetNodeTypes.NULL) return factory.createNullValue().wrap()
|
||||
|
||||
val result: Any? = when (nodeElementType) {
|
||||
JetNodeTypes.INTEGER_CONSTANT -> parseLong(text)
|
||||
@@ -121,7 +124,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
} ?: return null
|
||||
|
||||
fun isLongWithSuffix() = nodeElementType == JetNodeTypes.INTEGER_CONSTANT && hasLongSuffix(text)
|
||||
return createConstant(result, expectedType, CompileTimeConstant.Parameters.Impl(true, !isLongWithSuffix(), false))
|
||||
return createConstant(result, expectedType, CompileTimeConstant.Parameters(true, !isLongWithSuffix(), false))
|
||||
}
|
||||
|
||||
override fun visitParenthesizedExpression(expression: JetParenthesizedExpression, expectedType: JetType?): CompileTimeConstant<*>? {
|
||||
@@ -152,17 +155,17 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
break
|
||||
}
|
||||
else {
|
||||
if (!constant.canBeUsedInAnnotations()) canBeUsedInAnnotation = false
|
||||
if (constant.usesVariableAsConstant()) usesVariableAsConstant = true
|
||||
sb.append(constant.value)
|
||||
if (!constant.canBeUsedInAnnotations) canBeUsedInAnnotation = false
|
||||
if (constant.usesVariableAsConstant) usesVariableAsConstant = true
|
||||
sb.append(constant.constantValue.value)
|
||||
}
|
||||
}
|
||||
return if (!interupted)
|
||||
createConstant(
|
||||
sb.toString(),
|
||||
expectedType,
|
||||
CompileTimeConstant.Parameters.Impl(
|
||||
isPure = true,
|
||||
CompileTimeConstant.Parameters(
|
||||
isPure = false,
|
||||
canBeUsedInAnnotation = canBeUsedInAnnotation,
|
||||
usesVariableAsConstant = usesVariableAsConstant
|
||||
)
|
||||
@@ -174,8 +177,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
evaluate(expression.getLeft(), expectedType)
|
||||
|
||||
override fun visitBinaryExpression(expression: JetBinaryExpression, expectedType: JetType?): CompileTimeConstant<*>? {
|
||||
val leftExpression = expression.getLeft()
|
||||
if (leftExpression == null) return null
|
||||
val leftExpression = expression.getLeft() ?: return null
|
||||
|
||||
val operationToken = expression.getOperationToken()
|
||||
if (OperatorConventions.BOOLEAN_OPERATIONS.containsKey(operationToken)) {
|
||||
@@ -183,14 +185,12 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
val leftConstant = evaluate(leftExpression, booleanType)
|
||||
if (leftConstant == null) return null
|
||||
|
||||
val rightExpression = expression.getRight()
|
||||
if (rightExpression == null) return null
|
||||
val rightExpression = expression.getRight() ?: return null
|
||||
|
||||
val rightConstant = evaluate(rightExpression, booleanType)
|
||||
if (rightConstant == null) return null
|
||||
val rightConstant = evaluate(rightExpression, booleanType) ?: return null
|
||||
|
||||
val leftValue = leftConstant.value
|
||||
val rightValue = rightConstant.value
|
||||
val leftValue = leftConstant.getValue(booleanType)
|
||||
val rightValue = rightConstant.getValue(booleanType)
|
||||
|
||||
if (leftValue !is Boolean || rightValue !is Boolean) return null
|
||||
val result = when (operationToken) {
|
||||
@@ -198,8 +198,14 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
JetTokens.OROR -> leftValue || rightValue
|
||||
else -> throw IllegalArgumentException("Unknown boolean operation token ${operationToken}")
|
||||
}
|
||||
val usesVariableAsConstant = leftConstant.usesVariableAsConstant() || rightConstant.usesVariableAsConstant()
|
||||
return createConstant(result, expectedType, CompileTimeConstant.Parameters.Impl(true, true, usesVariableAsConstant))
|
||||
return createConstant(
|
||||
result, expectedType,
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation = true,
|
||||
isPure = false,
|
||||
usesVariableAsConstant = leftConstant.usesVariableAsConstant || rightConstant.usesVariableAsConstant
|
||||
)
|
||||
)
|
||||
}
|
||||
else {
|
||||
return evaluateCall(expression.getOperationReference(), leftExpression, expectedType)
|
||||
@@ -226,7 +232,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
return createConstant(
|
||||
result,
|
||||
expectedType,
|
||||
CompileTimeConstant.Parameters.Impl(
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation,
|
||||
!isNumberConversionMethod && isArgumentPure,
|
||||
usesVariableAsConstant)
|
||||
@@ -240,8 +246,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
if (isDivisionByZero(resultingDescriptorName.asString(), argumentForParameter.value)) {
|
||||
val parentExpression: JetExpression = PsiTreeUtil.getParentOfType(receiverExpression, javaClass())!!
|
||||
trace.report(Errors.DIVISION_BY_ZERO.on(parentExpression))
|
||||
//TODO_R:
|
||||
return ErrorValue.create("Division by zero")
|
||||
return factory.createErrorValue("Division by zero").wrap()
|
||||
}
|
||||
|
||||
val result = evaluateBinaryAndCheck(argumentForReceiver, argumentForParameter, resultingDescriptorName.asString(), callExpression)
|
||||
@@ -250,11 +255,10 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
val areArgumentsPure = isPureConstant(argumentForReceiver.expression) && isPureConstant(argumentForParameter.expression)
|
||||
val canBeUsedInAnnotation = canBeUsedInAnnotation(argumentForReceiver.expression) && canBeUsedInAnnotation(argumentForParameter.expression)
|
||||
val usesVariableAsConstant = usesVariableAsConstant(argumentForReceiver.expression) || usesVariableAsConstant(argumentForParameter.expression)
|
||||
val parameters = CompileTimeConstant.Parameters.Impl(canBeUsedInAnnotation, areArgumentsPure, usesVariableAsConstant)
|
||||
val factory = CompileTimeConstantFactory(parameters, builtIns)
|
||||
val parameters = CompileTimeConstant.Parameters(canBeUsedInAnnotation, areArgumentsPure, usesVariableAsConstant)
|
||||
return when (resultingDescriptorName) {
|
||||
OperatorConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression, factory)
|
||||
OperatorConventions.EQUALS -> createCompileTimeConstantForEquals(result, callExpression, factory)
|
||||
OperatorConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression, factory)?.wrap(parameters)
|
||||
OperatorConventions.EQUALS -> createCompileTimeConstantForEquals(result, callExpression, factory)?.wrap(parameters)
|
||||
else -> {
|
||||
createConstant(result, expectedType, parameters)
|
||||
}
|
||||
@@ -264,17 +268,11 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
return null
|
||||
}
|
||||
|
||||
private fun usesVariableAsConstant(expression: JetExpression) = getConstant(expression, trace.getBindingContext())?.usesVariableAsConstant() ?: false
|
||||
private fun usesVariableAsConstant(expression: JetExpression) = getConstant(expression, trace.getBindingContext())?.usesVariableAsConstant ?: false
|
||||
|
||||
private fun canBeUsedInAnnotation(expression: JetExpression) = getConstant(expression, trace.getBindingContext())?.canBeUsedInAnnotations() ?: false
|
||||
private fun canBeUsedInAnnotation(expression: JetExpression) = getConstant(expression, trace.getBindingContext())?.canBeUsedInAnnotations ?: false
|
||||
|
||||
private fun isPureConstant(expression: JetExpression): Boolean {
|
||||
val compileTimeConstant = getConstant(expression, trace.getBindingContext())
|
||||
if (compileTimeConstant is IntegerValueConstant) {
|
||||
return compileTimeConstant.isPure()
|
||||
}
|
||||
return false
|
||||
}
|
||||
private fun isPureConstant(expression: JetExpression) = getConstant(expression, trace.getBindingContext())?.isPure ?: false
|
||||
|
||||
private fun evaluateUnaryAndCheck(receiver: OperationArgument, name: String, callExpression: JetExpression): Any? {
|
||||
val functions = unaryOperations[UnaryOperationKey(receiver.ctcType, name)]
|
||||
@@ -342,25 +340,19 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
override fun visitSimpleNameExpression(expression: JetSimpleNameExpression, expectedType: JetType?): CompileTimeConstant<*>? {
|
||||
val enumDescriptor = trace.getBindingContext().get(BindingContext.REFERENCE_TARGET, expression);
|
||||
if (enumDescriptor != null && DescriptorUtils.isEnumEntry(enumDescriptor)) {
|
||||
return EnumValue(enumDescriptor as ClassDescriptor)
|
||||
return factory.createEnumValue(enumDescriptor as ClassDescriptor).wrap()
|
||||
}
|
||||
|
||||
val resolvedCall = expression.getResolvedCall(trace.getBindingContext())
|
||||
if (resolvedCall != null) {
|
||||
val callableDescriptor = resolvedCall.getResultingDescriptor()
|
||||
if (callableDescriptor is VariableDescriptor) {
|
||||
val compileTimeConstant = callableDescriptor.getCompileTimeInitializer()
|
||||
if (compileTimeConstant == null) return null
|
||||
val variableInitializer = callableDescriptor.getCompileTimeInitializer() ?: return null
|
||||
|
||||
val value: Any? =
|
||||
if (compileTimeConstant is IntegerValueTypeConstant)
|
||||
compileTimeConstant.getValue(expectedType ?: TypeUtils.NO_EXPECTED_TYPE)
|
||||
else
|
||||
compileTimeConstant.value
|
||||
return createConstant(
|
||||
value,
|
||||
variableInitializer.value,
|
||||
expectedType,
|
||||
CompileTimeConstant.Parameters.Impl(
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation = isPropertyCompileTimeConstant(callableDescriptor),
|
||||
isPure = false,
|
||||
usesVariableAsConstant = true
|
||||
@@ -371,6 +363,18 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
return null
|
||||
}
|
||||
|
||||
private fun isPropertyCompileTimeConstant(descriptor: VariableDescriptor): Boolean {
|
||||
if (descriptor.isVar()) {
|
||||
return false
|
||||
}
|
||||
if (DescriptorUtils.isObject(descriptor.getContainingDeclaration()) ||
|
||||
DescriptorUtils.isStaticDeclaration(descriptor)) {
|
||||
val returnType = descriptor.getType()
|
||||
return KotlinBuiltIns.isPrimitiveType(returnType) || KotlinBuiltIns.isString(returnType)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun visitQualifiedExpression(expression: JetQualifiedExpression, expectedType: JetType?): CompileTimeConstant<*>? {
|
||||
val selectorExpression = expression.getSelectorExpression()
|
||||
// 1.toInt(); 1.plus(1);
|
||||
@@ -409,7 +413,10 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
|
||||
val arguments = call.getValueArguments().values().flatMap { resolveArguments(it.getArguments(), varargType) }
|
||||
|
||||
return ArrayValue(arguments, resultingDescriptor.getReturnType()!!, arguments.any() { it.usesVariableAsConstant() })
|
||||
return ArrayValue(arguments.map { it.toConstantValue(varargType) }, resultingDescriptor.getReturnType()!!).
|
||||
wrap(
|
||||
usesVariableAsConstant = arguments.any { it.usesVariableAsConstant }
|
||||
)
|
||||
}
|
||||
|
||||
// Ann()
|
||||
@@ -420,7 +427,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
classDescriptor.getDefaultType(),
|
||||
AnnotationResolver.resolveAnnotationArguments(call, trace)
|
||||
)
|
||||
return AnnotationValue(descriptor)
|
||||
return AnnotationValue(descriptor).wrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,7 +437,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
override fun visitClassLiteralExpression(expression: JetClassLiteralExpression, expectedType: JetType?): CompileTimeConstant<*>? {
|
||||
val jetType = trace.getType(expression)!!
|
||||
if (jetType.isError()) return null
|
||||
return KClassValue(jetType)
|
||||
return KClassValue(jetType).wrap()
|
||||
}
|
||||
|
||||
private fun resolveArguments(valueArguments: List<ValueArgument>, expectedType: JetType): List<CompileTimeConstant<*>> {
|
||||
@@ -476,32 +483,54 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
|
||||
}
|
||||
|
||||
private fun createOperationArgument(expression: JetExpression, expressionType: JetType, compileTimeType: CompileTimeType<*>): OperationArgument? {
|
||||
val evaluatedConstant = evaluate(expression, trace, expressionType)
|
||||
if (evaluatedConstant == null) return null
|
||||
|
||||
if (evaluatedConstant is IntegerValueTypeConstant) {
|
||||
val evaluationResultWithNewType = evaluatedConstant.getValue(expressionType)
|
||||
return OperationArgument(evaluationResultWithNewType, compileTimeType, expression)
|
||||
}
|
||||
|
||||
val evaluationResult = evaluatedConstant.value
|
||||
if (evaluationResult == null) return null
|
||||
|
||||
val compileTimeConstant = evaluate(expression, trace, expressionType) ?: return null
|
||||
val evaluationResult = compileTimeConstant.getValue(expressionType) ?: return null
|
||||
return OperationArgument(evaluationResult, compileTimeType, expression)
|
||||
}
|
||||
|
||||
fun createConstant(
|
||||
private fun createConstant(
|
||||
value: Any?,
|
||||
expectedType: JetType?,
|
||||
parameters: CompileTimeConstant.Parameters
|
||||
): CompileTimeConstant<*>? {
|
||||
return CompileTimeConstantFactory(parameters, builtIns).createCompileTimeConstant(value, if (parameters.isPure) expectedType ?: TypeUtils.NO_EXPECTED_TYPE else null)
|
||||
return if (parameters.isPure) {
|
||||
return createCompileTimeConstant(value, parameters, expectedType ?: TypeUtils.NO_EXPECTED_TYPE)
|
||||
}
|
||||
else {
|
||||
factory.createConstantValue(value)?.wrap(parameters)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createCompileTimeConstant(
|
||||
value: Any?,
|
||||
parameters: CompileTimeConstant.Parameters,
|
||||
expectedType: JetType
|
||||
): CompileTimeConstant<*>? {
|
||||
return when (value) {
|
||||
is Byte, is Short, is Int, is Long -> createIntegerCompileTimeConstant((value as Number).toLong(), parameters, expectedType)
|
||||
else -> factory.createConstantValue(value)?.wrap(parameters)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createIntegerCompileTimeConstant(
|
||||
value: Long,
|
||||
parameters: CompileTimeConstant.Parameters,
|
||||
expectedType: JetType
|
||||
): CompileTimeConstant<*>? {
|
||||
if (TypeUtils.noExpectedType(expectedType) || expectedType.isError()) {
|
||||
return IntegerValueTypeConstant(value, parameters)
|
||||
}
|
||||
val integerValue = factory.createIntegerConstantValue(value, expectedType)
|
||||
if (integerValue != null) {
|
||||
return integerValue.wrap(parameters)
|
||||
}
|
||||
return when (value) {
|
||||
value.toInt().toLong() -> factory.createIntValue(value.toInt())
|
||||
else -> factory.createLongValue(value)
|
||||
}.wrap(parameters)
|
||||
}
|
||||
}
|
||||
|
||||
public fun IntegerValueTypeConstant.createCompileTimeConstantWithType(expectedType: JetType): CompileTimeConstant<*>?
|
||||
= CompileTimeConstantFactory(CompileTimeConstant.Parameters.Impl(this.canBeUsedInAnnotations(), true, false), KotlinBuiltIns.getInstance()).createCompileTimeConstant(this.getValue(expectedType))
|
||||
|
||||
private fun hasLongSuffix(text: String) = text.endsWith('l') || text.endsWith('L')
|
||||
|
||||
public fun parseLong(text: String): Long? {
|
||||
@@ -557,7 +586,7 @@ private fun parseBoolean(text: String): Boolean {
|
||||
}
|
||||
|
||||
|
||||
private fun createCompileTimeConstantForEquals(result: Any?, operationReference: JetExpression, factory: CompileTimeConstantFactory): CompileTimeConstant<*>? {
|
||||
private fun createCompileTimeConstantForEquals(result: Any?, operationReference: JetExpression, factory: ConstantValueFactory): ConstantValue<*>? {
|
||||
if (result is Boolean) {
|
||||
assert(operationReference is JetSimpleNameExpression, "This method should be called only for equals operations")
|
||||
val operationToken = (operationReference as JetSimpleNameExpression).getReferencedNameElementType()
|
||||
@@ -575,7 +604,7 @@ private fun createCompileTimeConstantForEquals(result: Any?, operationReference:
|
||||
return null
|
||||
}
|
||||
|
||||
private fun createCompileTimeConstantForCompareTo(result: Any?, operationReference: JetExpression, factory: CompileTimeConstantFactory): CompileTimeConstant<*>? {
|
||||
private fun createCompileTimeConstantForCompareTo(result: Any?, operationReference: JetExpression, factory: ConstantValueFactory): ConstantValue<*>? {
|
||||
if (result is Int) {
|
||||
assert(operationReference is JetSimpleNameExpression, "This method should be called only for compareTo operations")
|
||||
val operationToken = (operationReference as JetSimpleNameExpression).getReferencedNameElementType()
|
||||
@@ -594,19 +623,6 @@ private fun createCompileTimeConstantForCompareTo(result: Any?, operationReferen
|
||||
return null
|
||||
}
|
||||
|
||||
private fun createStringConstant(value: CompileTimeConstant<*>?): StringValue? {
|
||||
return when (value) {
|
||||
is IntegerValueTypeConstant -> CompileTimeConstantFactory(value.parameters, KotlinBuiltIns.getInstance()).createStringValue(value.getValue(TypeUtils.NO_EXPECTED_TYPE).toString())
|
||||
is StringValue -> value
|
||||
is IntValue, is ByteValue, is ShortValue, is LongValue,
|
||||
is CharValue,
|
||||
is DoubleValue, is FloatValue,
|
||||
is BooleanValue,
|
||||
is NullValue -> CompileTimeConstantFactory(value.parameters, KotlinBuiltIns.getInstance()).createStringValue("${value.value}")
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun isIntegerType(value: Any?) = value is Byte || value is Short || value is Int || value is Long
|
||||
|
||||
private fun getReceiverExpressionType(resolvedCall: ResolvedCall<*>): JetType? {
|
||||
@@ -668,4 +684,3 @@ private fun <A> unaryOperation(
|
||||
|
||||
private data class BinaryOperationKey<A, B>(val f: CompileTimeType<out A>, val s: CompileTimeType<out B>, val functionName: String)
|
||||
private data class UnaryOperationKey<A>(val f: CompileTimeType<out A>, val functionName: String)
|
||||
|
||||
|
||||
+3
-3
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.diagnostics.Severity;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue;
|
||||
import org.jetbrains.kotlin.util.ExtensionProvider;
|
||||
|
||||
@@ -214,9 +214,9 @@ public class DiagnosticsWithSuppression implements Diagnostics {
|
||||
if (!KotlinBuiltIns.isSuppressAnnotation(annotationDescriptor)) continue;
|
||||
|
||||
// We only add strings and skip other values to facilitate recovery in presence of erroneous code
|
||||
for (CompileTimeConstant<?> arrayValue : annotationDescriptor.getAllValueArguments().values()) {
|
||||
for (ConstantValue<?> arrayValue : annotationDescriptor.getAllValueArguments().values()) {
|
||||
if ((arrayValue instanceof ArrayValue)) {
|
||||
for (CompileTimeConstant<?> value : ((ArrayValue) arrayValue).getValue()) {
|
||||
for (ConstantValue<?> value : ((ArrayValue) arrayValue).getValue()) {
|
||||
if (value instanceof StringValue) {
|
||||
builder.add(String.valueOf(((StringValue) value).getValue()).toLowerCase());
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ArgumentMapping;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue;
|
||||
|
||||
import static kotlin.KotlinPackage.firstOrNull;
|
||||
@@ -53,7 +53,7 @@ public class InlineUtil {
|
||||
if (annotation == null) {
|
||||
return InlineStrategy.NOT_INLINE;
|
||||
}
|
||||
CompileTimeConstant<?> argument = firstOrNull(annotation.getAllValueArguments().values());
|
||||
ConstantValue<?> argument = firstOrNull(annotation.getAllValueArguments().values());
|
||||
if (argument == null) {
|
||||
return InlineStrategy.AS_FUNCTION;
|
||||
}
|
||||
@@ -72,9 +72,9 @@ public class InlineUtil {
|
||||
private static boolean hasInlineOption(@NotNull ValueParameterDescriptor descriptor, @NotNull InlineOption option) {
|
||||
AnnotationDescriptor annotation = descriptor.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.inlineOptions);
|
||||
if (annotation != null) {
|
||||
CompileTimeConstant<?> argument = firstOrNull(annotation.getAllValueArguments().values());
|
||||
ConstantValue<?> argument = firstOrNull(annotation.getAllValueArguments().values());
|
||||
if (argument instanceof ArrayValue) {
|
||||
for (CompileTimeConstant<?> value : ((ArrayValue) argument).getValue()) {
|
||||
for (ConstantValue<?> value : ((ArrayValue) argument).getValue()) {
|
||||
if (value instanceof EnumValue && ((EnumValue) value).getValue().getName().asString().equals(option.name())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+3
-3
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.AnnotationResolver
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
||||
import org.jetbrains.kotlin.resolve.lazy.LazyEntity
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
@@ -109,7 +109,7 @@ public class LazyAnnotationDescriptor(
|
||||
|
||||
override fun getAllValueArguments() = valueArguments()
|
||||
|
||||
private fun computeValueArguments(): Map<ValueParameterDescriptor, CompileTimeConstant<*>> {
|
||||
private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> {
|
||||
val resolutionResults = c.annotationResolver.resolveAnnotationCall(annotationEntry, c.scope, c.trace)
|
||||
AnnotationResolver.checkAnnotationType(annotationEntry, c.trace, resolutionResults)
|
||||
|
||||
@@ -121,7 +121,7 @@ public class LazyAnnotationDescriptor(
|
||||
if (resolvedArgument == null) null
|
||||
else AnnotationResolver.getAnnotationArgumentValue(c.trace, valueParameter, resolvedArgument)
|
||||
}
|
||||
.filterValues { it != null } as Map<ValueParameterDescriptor, CompileTimeConstant<*>>
|
||||
.filterValues { it != null } as Map<ValueParameterDescriptor, ConstantValue<*>>
|
||||
}
|
||||
|
||||
override fun forceResolveAllContents() {
|
||||
|
||||
+7
-8
@@ -55,9 +55,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantChecker;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.*;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl;
|
||||
@@ -121,19 +119,20 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
@Override
|
||||
public JetTypeInfo visitConstantExpression(@NotNull JetConstantExpression expression, ExpressionTypingContext context) {
|
||||
CompileTimeConstant<?> value = ConstantExpressionEvaluator.evaluate(expression, context.trace, context.expectedType);
|
||||
CompileTimeConstant<?> compileTimeConstant = ConstantExpressionEvaluator.evaluate(expression, context.trace, context.expectedType);
|
||||
|
||||
if (!(value instanceof IntegerValueTypeConstant)) {
|
||||
if (!(compileTimeConstant instanceof IntegerValueTypeConstant)) {
|
||||
CompileTimeConstantChecker compileTimeConstantChecker = context.getCompileTimeConstantChecker();
|
||||
boolean hasError = compileTimeConstantChecker.checkConstantExpressionType(value, expression, context.expectedType);
|
||||
ConstantValue constantValue = compileTimeConstant != null ? ((TypedCompileTimeConstant) compileTimeConstant).getConstantValue() : null;
|
||||
boolean hasError = compileTimeConstantChecker.checkConstantExpressionType(constantValue, expression, context.expectedType);
|
||||
if (hasError) {
|
||||
IElementType elementType = expression.getNode().getElementType();
|
||||
return TypeInfoFactoryPackage.createTypeInfo(getDefaultType(elementType), context);
|
||||
}
|
||||
}
|
||||
|
||||
assert value != null : "CompileTimeConstant should be evaluated for constant expression or an error should be recorded " + expression.getText();
|
||||
return createCompileTimeConstantTypeInfo(value, expression, context);
|
||||
assert compileTimeConstant != null : "CompileTimeConstant should be evaluated for constant expression or an error should be recorded " + expression.getText();
|
||||
return createCompileTimeConstantTypeInfo(compileTimeConstant, expression, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -31,11 +31,9 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantChecker;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.EvaluatePackage;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.kotlin.types.TypesPackage;
|
||||
@@ -176,12 +174,9 @@ public class DataFlowUtils {
|
||||
}
|
||||
|
||||
if (expression instanceof JetConstantExpression) {
|
||||
CompileTimeConstant<?> value = ConstantExpressionEvaluator.evaluate(expression, c.trace, c.expectedType);
|
||||
if (value instanceof IntegerValueTypeConstant) {
|
||||
value = EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) value, c.expectedType);
|
||||
}
|
||||
ConstantValue<?> constantValue = ConstantExpressionEvaluator.evaluateToConstantValue(expression, c.trace, c.expectedType);
|
||||
boolean error = new CompileTimeConstantChecker(c.trace, true)
|
||||
.checkConstantExpressionType(value, (JetConstantExpression) expression, c.expectedType);
|
||||
.checkConstantExpressionType(constantValue, (JetConstantExpression) expression, c.expectedType);
|
||||
if (hasError != null) hasError.set(error);
|
||||
return expressionType;
|
||||
}
|
||||
|
||||
+14
-5
@@ -22,7 +22,6 @@ import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
|
||||
@@ -33,6 +32,7 @@ import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassReceiver;
|
||||
@@ -248,10 +248,19 @@ public class ExpressionTypingUtils {
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
JetType expressionType = value.getType();
|
||||
if (value instanceof IntegerValueTypeConstant && context.contextDependency == INDEPENDENT) {
|
||||
expressionType = ((IntegerValueTypeConstant) value).getType(context.expectedType);
|
||||
ArgumentTypeResolver.updateNumberType(expressionType, expression, context);
|
||||
JetType expressionType;
|
||||
if (value instanceof IntegerValueTypeConstant) {
|
||||
IntegerValueTypeConstant integerValueTypeConstant = (IntegerValueTypeConstant) value;
|
||||
if (context.contextDependency == INDEPENDENT) {
|
||||
expressionType = integerValueTypeConstant.getType(context.expectedType);
|
||||
ArgumentTypeResolver.updateNumberType(expressionType, expression, context);
|
||||
}
|
||||
else {
|
||||
expressionType = integerValueTypeConstant.getUnknownIntegerType();
|
||||
}
|
||||
}
|
||||
else {
|
||||
expressionType = ((TypedCompileTimeConstant<?>) value).getType();
|
||||
}
|
||||
|
||||
return TypeInfoFactoryPackage.createCheckedTypeInfo(expressionType, context, expression);
|
||||
|
||||
Reference in New Issue
Block a user