Introduce limited constant conversions for Kotlin/Native
#KT-25320 Fixed
This commit is contained in:
@@ -31,6 +31,8 @@ val JVM_FIELD_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmField")
|
|||||||
|
|
||||||
val JVM_DEFAULT_FQ_NAME = FqName("kotlin.jvm.JvmDefault")
|
val JVM_DEFAULT_FQ_NAME = FqName("kotlin.jvm.JvmDefault")
|
||||||
|
|
||||||
|
private val IMPLICIT_INTEGER_COERCION_ANNOTATION_FQ_NAME = FqName("kotlin.internal.ImplicitIntegerCoercion")
|
||||||
|
|
||||||
fun CallableMemberDescriptor.hasJvmDefaultAnnotation() =
|
fun CallableMemberDescriptor.hasJvmDefaultAnnotation() =
|
||||||
DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME)
|
DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME)
|
||||||
|
|
||||||
@@ -39,6 +41,10 @@ fun DeclarationDescriptor.hasJvmStaticAnnotation(): Boolean {
|
|||||||
return annotations.findAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) != null
|
return annotations.findAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun DeclarationDescriptor.hasImplicitIntegerCoercionAnnotation(): Boolean {
|
||||||
|
return annotations.findAnnotation(IMPLICIT_INTEGER_COERCION_ANNOTATION_FQ_NAME) != null
|
||||||
|
}
|
||||||
|
|
||||||
private val JVM_SYNTHETIC_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmSynthetic")
|
private val JVM_SYNTHETIC_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmSynthetic")
|
||||||
|
|
||||||
fun DeclarationDescriptor.hasJvmSyntheticAnnotation() = findJvmSyntheticAnnotation() != null
|
fun DeclarationDescriptor.hasJvmSyntheticAnnotation() = findJvmSyntheticAnnotation() != null
|
||||||
|
|||||||
@@ -44,10 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil;
|
|||||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor;
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor;
|
||||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||||
import org.jetbrains.kotlin.types.FunctionPlaceholders;
|
import org.jetbrains.kotlin.types.*;
|
||||||
import org.jetbrains.kotlin.types.FunctionPlaceholdersKt;
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
|
||||||
import org.jetbrains.kotlin.types.TypeUtils;
|
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||||
import org.jetbrains.kotlin.types.expressions.*;
|
import org.jetbrains.kotlin.types.expressions.*;
|
||||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
|
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
|
||||||
@@ -392,9 +389,21 @@ public class ArgumentTypeResolver {
|
|||||||
@NotNull KtExpression expression
|
@NotNull KtExpression expression
|
||||||
) {
|
) {
|
||||||
KotlinType type = trace.getType(expression);
|
KotlinType type = trace.getType(expression);
|
||||||
if (type != null && !type.getConstructor().isDenotable()) {
|
return type != null ? updateResultArgumentTypeIfNotDenotable(trace, statementFilter, expectedType, type, expression) : null;
|
||||||
if (type.getConstructor() instanceof IntegerValueTypeConstructor) {
|
}
|
||||||
IntegerValueTypeConstructor constructor = (IntegerValueTypeConstructor) type.getConstructor();
|
|
||||||
|
@Nullable
|
||||||
|
public KotlinType updateResultArgumentTypeIfNotDenotable(
|
||||||
|
@NotNull BindingTrace trace,
|
||||||
|
@NotNull StatementFilter statementFilter,
|
||||||
|
@NotNull KotlinType expectedType,
|
||||||
|
@NotNull KotlinType targetType,
|
||||||
|
@NotNull KtExpression expression
|
||||||
|
) {
|
||||||
|
TypeConstructor typeConstructor = targetType.getConstructor();
|
||||||
|
if (!typeConstructor.isDenotable()) {
|
||||||
|
if (typeConstructor instanceof IntegerValueTypeConstructor) {
|
||||||
|
IntegerValueTypeConstructor constructor = (IntegerValueTypeConstructor) typeConstructor;
|
||||||
KotlinType primitiveType = TypeUtils.getPrimitiveNumberType(constructor, expectedType);
|
KotlinType primitiveType = TypeUtils.getPrimitiveNumberType(constructor, expectedType);
|
||||||
constantExpressionEvaluator.updateNumberType(primitiveType, expression, statementFilter, trace);
|
constantExpressionEvaluator.updateNumberType(primitiveType, expression, statementFilter, trace);
|
||||||
return primitiveType;
|
return primitiveType;
|
||||||
|
|||||||
@@ -20,9 +20,12 @@ import org.jetbrains.kotlin.builtins.*
|
|||||||
import org.jetbrains.kotlin.contracts.EffectSystem
|
import org.jetbrains.kotlin.contracts.EffectSystem
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext.CONSTRAINT_SYSTEM_COMPLETER
|
import org.jetbrains.kotlin.resolve.BindingContext.CONSTRAINT_SYSTEM_COMPLETER
|
||||||
|
import org.jetbrains.kotlin.resolve.annotations.hasImplicitIntegerCoercionAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnVariable
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnVariable
|
||||||
@@ -46,11 +49,11 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
|||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.Variance
|
|
||||||
import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer
|
import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class CallCompleter(
|
class CallCompleter(
|
||||||
@@ -279,28 +282,50 @@ class CallCompleter(
|
|||||||
|
|
||||||
for (valueArgument in context.call.valueArguments) {
|
for (valueArgument in context.call.valueArguments) {
|
||||||
val argumentMapping = getArgumentMapping(valueArgument!!)
|
val argumentMapping = getArgumentMapping(valueArgument!!)
|
||||||
val (expectedType, callPosition) = when (argumentMapping) {
|
|
||||||
is ArgumentMatch -> Pair(
|
val expectedType: KotlinType
|
||||||
getEffectiveExpectedType(argumentMapping.valueParameter, valueArgument, context),
|
val callPosition: CallPosition
|
||||||
CallPosition.ValueArgumentPosition(results.resultingCall, argumentMapping.valueParameter, valueArgument)
|
val parameter: ValueParameterDescriptor?
|
||||||
)
|
when (argumentMapping) {
|
||||||
else -> Pair(TypeUtils.NO_EXPECTED_TYPE, CallPosition.Unknown)
|
is ArgumentMatch -> {
|
||||||
|
expectedType = getEffectiveExpectedType(argumentMapping.valueParameter, valueArgument, context)
|
||||||
|
callPosition = CallPosition.ValueArgumentPosition(results.resultingCall, argumentMapping.valueParameter, valueArgument)
|
||||||
|
parameter = argumentMapping.valueParameter
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
expectedType = TypeUtils.NO_EXPECTED_TYPE
|
||||||
|
callPosition = CallPosition.Unknown
|
||||||
|
parameter = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val newContext =
|
val newContext =
|
||||||
context.replaceDataFlowInfo(getDataFlowInfoForArgument(valueArgument))
|
context.replaceDataFlowInfo(getDataFlowInfoForArgument(valueArgument))
|
||||||
.replaceExpectedType(expectedType)
|
.replaceExpectedType(expectedType)
|
||||||
.replaceCallPosition(callPosition)
|
.replaceCallPosition(callPosition)
|
||||||
completeOneArgument(valueArgument, newContext)
|
completeOneArgument(valueArgument, parameter, newContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createTypeForConvertableConstant(constant: CompileTimeConstant<*>): SimpleType? {
|
||||||
|
val value = constant.getValue(TypeUtils.NO_EXPECTED_TYPE).safeAs<Number>()?.toLong() ?: return null
|
||||||
|
val typeConstructor = IntegerValueTypeConstructor(
|
||||||
|
value, moduleDescriptor, constant.parameters
|
||||||
|
)
|
||||||
|
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||||
|
Annotations.EMPTY, typeConstructor, emptyList(), false,
|
||||||
|
ErrorUtils.createErrorScope("Scope for number value type ($typeConstructor)", true)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun completeOneArgument(
|
private fun completeOneArgument(
|
||||||
valueArgument: ValueArgument,
|
argument: ValueArgument,
|
||||||
|
parameter: ValueParameterDescriptor?,
|
||||||
context: BasicCallResolutionContext
|
context: BasicCallResolutionContext
|
||||||
) {
|
) {
|
||||||
if (valueArgument.isExternal()) return
|
if (argument.isExternal()) return
|
||||||
|
|
||||||
val expression = valueArgument.getArgumentExpression() ?: return
|
val expression = argument.getArgumentExpression() ?: return
|
||||||
val deparenthesized = KtPsiUtil.getLastElementDeparenthesized(expression, context.statementFilter) ?: return
|
val deparenthesized = KtPsiUtil.getLastElementDeparenthesized(expression, context.statementFilter) ?: return
|
||||||
|
|
||||||
val recordedType = context.trace.getType(expression)
|
val recordedType = context.trace.getType(expression)
|
||||||
@@ -320,6 +345,18 @@ class CallCompleter(
|
|||||||
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression) ?: updatedType
|
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression) ?: updatedType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parameter?.hasImplicitIntegerCoercionAnnotation() == true) {
|
||||||
|
val argumentCompileTimeValue = context.trace[BindingContext.COMPILE_TIME_VALUE, deparenthesized]
|
||||||
|
if (argumentCompileTimeValue != null && argumentCompileTimeValue.parameters.isConvertableConstVal) {
|
||||||
|
val generalNumberType = createTypeForConvertableConstant(argumentCompileTimeValue)
|
||||||
|
if (generalNumberType != null) {
|
||||||
|
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(
|
||||||
|
context.trace, context.statementFilter, context.expectedType, generalNumberType, expression
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context.statementFilter, context.trace)
|
updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context.statementFilter, context.trace)
|
||||||
|
|
||||||
// While the expected type is not known, the function literal arguments are not analyzed (to analyze function literal bodies once),
|
// While the expected type is not known, the function literal arguments are not analyzed (to analyze function literal bodies once),
|
||||||
|
|||||||
+26
-8
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext.COLLECTION_LITERAL_CALL
|
import org.jetbrains.kotlin.resolve.BindingContext.COLLECTION_LITERAL_CALL
|
||||||
|
import org.jetbrains.kotlin.resolve.annotations.hasImplicitIntegerCoercionAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
@@ -401,7 +402,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
isUnsignedNumberLiteral = isUnsigned,
|
isUnsignedNumberLiteral = isUnsigned,
|
||||||
isUnsignedLongNumberLiteral = isUnsignedLong,
|
isUnsignedLongNumberLiteral = isUnsignedLong,
|
||||||
usesVariableAsConstant = false,
|
usesVariableAsConstant = false,
|
||||||
usesNonConstValAsConstant = false
|
usesNonConstValAsConstant = false,
|
||||||
|
isConvertableConstVal = false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -450,7 +452,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
isUnsignedLongNumberLiteral = false,
|
isUnsignedLongNumberLiteral = false,
|
||||||
canBeUsedInAnnotation = canBeUsedInAnnotation,
|
canBeUsedInAnnotation = canBeUsedInAnnotation,
|
||||||
usesVariableAsConstant = usesVariableAsConstant,
|
usesVariableAsConstant = usesVariableAsConstant,
|
||||||
usesNonConstValAsConstant = usesNonConstantVariableAsConstant
|
usesNonConstValAsConstant = usesNonConstantVariableAsConstant,
|
||||||
|
isConvertableConstVal = false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else null
|
else null
|
||||||
@@ -513,7 +516,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
isUnsignedNumberLiteral = false,
|
isUnsignedNumberLiteral = false,
|
||||||
isUnsignedLongNumberLiteral = false,
|
isUnsignedLongNumberLiteral = false,
|
||||||
usesVariableAsConstant = leftConstant.usesVariableAsConstant || rightConstant.usesVariableAsConstant,
|
usesVariableAsConstant = leftConstant.usesVariableAsConstant || rightConstant.usesVariableAsConstant,
|
||||||
usesNonConstValAsConstant = leftConstant.usesNonConstValAsConstant || rightConstant.usesNonConstValAsConstant
|
usesNonConstValAsConstant = leftConstant.usesNonConstValAsConstant || rightConstant.usesNonConstValAsConstant,
|
||||||
|
isConvertableConstVal = false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -560,7 +564,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
canBeUsedInAnnotation,
|
canBeUsedInAnnotation,
|
||||||
!isNumberConversionMethod && isArgumentPure,
|
!isNumberConversionMethod && isArgumentPure,
|
||||||
false, false,
|
false, false,
|
||||||
usesVariableAsConstant, usesNonConstValAsConstant
|
usesVariableAsConstant, usesNonConstValAsConstant,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else if (argumentsEntrySet.size == 1) {
|
} else if (argumentsEntrySet.size == 1) {
|
||||||
@@ -592,7 +597,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
val usesNonConstValAsConstant =
|
val usesNonConstValAsConstant =
|
||||||
usesNonConstValAsConstant(argumentForReceiver.expression) || usesNonConstValAsConstant(argumentForParameter.expression)
|
usesNonConstValAsConstant(argumentForReceiver.expression) || usesNonConstValAsConstant(argumentForParameter.expression)
|
||||||
val parameters = CompileTimeConstant.Parameters(
|
val parameters = CompileTimeConstant.Parameters(
|
||||||
canBeUsedInAnnotation, areArgumentsPure, false, false, usesVariableAsConstant, usesNonConstValAsConstant
|
canBeUsedInAnnotation, areArgumentsPure, false, false, usesVariableAsConstant, usesNonConstValAsConstant, false
|
||||||
)
|
)
|
||||||
return when (resultingDescriptorName) {
|
return when (resultingDescriptorName) {
|
||||||
OperatorNameConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression)?.wrap(parameters)
|
OperatorNameConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression)?.wrap(parameters)
|
||||||
@@ -705,6 +710,11 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
// TODO: FIXME: see KT-10425
|
// TODO: FIXME: see KT-10425
|
||||||
if (callableDescriptor is PropertyDescriptor && callableDescriptor.modality != Modality.FINAL) return null
|
if (callableDescriptor is PropertyDescriptor && callableDescriptor.modality != Modality.FINAL) return null
|
||||||
|
|
||||||
|
val isConvertableConstVal =
|
||||||
|
callableDescriptor.isConst &&
|
||||||
|
callableDescriptor.hasImplicitIntegerCoercionAnnotation() &&
|
||||||
|
callableDescriptor.compileTimeInitializer is IntValue
|
||||||
|
|
||||||
return callableDescriptor.compileTimeInitializer?.wrap(
|
return callableDescriptor.compileTimeInitializer?.wrap(
|
||||||
CompileTimeConstant.Parameters(
|
CompileTimeConstant.Parameters(
|
||||||
canBeUsedInAnnotation = isPropertyCompileTimeConstant(callableDescriptor),
|
canBeUsedInAnnotation = isPropertyCompileTimeConstant(callableDescriptor),
|
||||||
@@ -712,7 +722,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
isUnsignedNumberLiteral = false,
|
isUnsignedNumberLiteral = false,
|
||||||
isUnsignedLongNumberLiteral = false,
|
isUnsignedLongNumberLiteral = false,
|
||||||
usesVariableAsConstant = true,
|
usesVariableAsConstant = true,
|
||||||
usesNonConstValAsConstant = !callableDescriptor.isConst
|
usesNonConstValAsConstant = !callableDescriptor.isConst,
|
||||||
|
isConvertableConstVal = isConvertableConstVal
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -973,11 +984,18 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
isUnsigned: Boolean = false,
|
isUnsigned: Boolean = false,
|
||||||
isUnsignedLong: Boolean = false,
|
isUnsignedLong: Boolean = false,
|
||||||
usesVariableAsConstant: Boolean = false,
|
usesVariableAsConstant: Boolean = false,
|
||||||
usesNonConstValAsConstant: Boolean = false
|
usesNonConstValAsConstant: Boolean = false,
|
||||||
|
isConvertableConstVal: Boolean = false
|
||||||
): TypedCompileTimeConstant<T> =
|
): TypedCompileTimeConstant<T> =
|
||||||
wrap(
|
wrap(
|
||||||
CompileTimeConstant.Parameters(
|
CompileTimeConstant.Parameters(
|
||||||
canBeUsedInAnnotation, isPure, isUnsigned, isUnsignedLong, usesVariableAsConstant, usesNonConstValAsConstant
|
canBeUsedInAnnotation,
|
||||||
|
isPure,
|
||||||
|
isUnsigned,
|
||||||
|
isUnsignedLong,
|
||||||
|
usesVariableAsConstant,
|
||||||
|
usesNonConstValAsConstant,
|
||||||
|
isConvertableConstVal
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -251,6 +251,10 @@ class InsertImplicitCasts(context: GeneratorContext) : IrElementTransformerVoid(
|
|||||||
KotlinBuiltIns.isByte(this) ||
|
KotlinBuiltIns.isByte(this) ||
|
||||||
KotlinBuiltIns.isShort(this) ||
|
KotlinBuiltIns.isShort(this) ||
|
||||||
KotlinBuiltIns.isInt(this) ||
|
KotlinBuiltIns.isInt(this) ||
|
||||||
KotlinBuiltIns.isLong(this)
|
KotlinBuiltIns.isLong(this) ||
|
||||||
|
KotlinBuiltIns.isUByte(this) ||
|
||||||
|
KotlinBuiltIns.isUShort(this) ||
|
||||||
|
KotlinBuiltIns.isUInt(this) ||
|
||||||
|
KotlinBuiltIns.isULong(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+68
@@ -0,0 +1,68 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// FILE: annotation.kt
|
||||||
|
|
||||||
|
package kotlin.internal
|
||||||
|
|
||||||
|
annotation class ImplicitIntegerCoercion
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
import kotlin.internal.ImplicitIntegerCoercion
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
const val IMPLICIT_INT = 255
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
const val EXPLICIT_INT: Int = 255
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
const val LONG_CONST = 255L
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
val NON_CONST = 255
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
const val BIGGER_THAN_UBYTE = 256
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
const val UINT_CONST = 42u
|
||||||
|
|
||||||
|
fun takeUByte(@ImplicitIntegerCoercion u: UByte) {}
|
||||||
|
fun takeUShort(@ImplicitIntegerCoercion u: UShort) {}
|
||||||
|
fun takeUInt(@ImplicitIntegerCoercion u: UInt) {}
|
||||||
|
fun takeULong(@ImplicitIntegerCoercion u: ULong) {}
|
||||||
|
|
||||||
|
fun takeUBytes(@ImplicitIntegerCoercion vararg u: UByte) {}
|
||||||
|
|
||||||
|
fun takeLong(@ImplicitIntegerCoercion l: Long) {}
|
||||||
|
|
||||||
|
fun takeUIntWithoutAnnotaion(u: UInt) {}
|
||||||
|
|
||||||
|
fun takeIntWithoutAnnotation(i: Int) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
takeUByte(IMPLICIT_INT)
|
||||||
|
takeUByte(EXPLICIT_INT)
|
||||||
|
|
||||||
|
takeUShort(IMPLICIT_INT)
|
||||||
|
takeUShort(BIGGER_THAN_UBYTE)
|
||||||
|
|
||||||
|
takeUInt(IMPLICIT_INT)
|
||||||
|
|
||||||
|
takeULong(IMPLICIT_INT)
|
||||||
|
|
||||||
|
takeUBytes(IMPLICIT_INT, EXPLICIT_INT, 42u)
|
||||||
|
|
||||||
|
takeLong(IMPLICIT_INT)
|
||||||
|
|
||||||
|
takeIntWithoutAnnotation(IMPLICIT_INT)
|
||||||
|
|
||||||
|
takeUIntWithoutAnnotaion(UINT_CONST)
|
||||||
|
|
||||||
|
takeUByte(<!TYPE_MISMATCH!>LONG_CONST<!>)
|
||||||
|
takeUByte(<!TYPE_MISMATCH!>NON_CONST<!>)
|
||||||
|
takeUByte(<!TYPE_MISMATCH!>BIGGER_THAN_UBYTE<!>)
|
||||||
|
takeUByte(<!TYPE_MISMATCH!>UINT_CONST<!>)
|
||||||
|
takeUIntWithoutAnnotaion(<!TYPE_MISMATCH!>IMPLICIT_INT<!>)
|
||||||
|
}
|
||||||
Vendored
+303
@@ -0,0 +1,303 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
@kotlin.internal.ImplicitIntegerCoercion public const val BIGGER_THAN_UBYTE: kotlin.Int = 256
|
||||||
|
@kotlin.internal.ImplicitIntegerCoercion public const val EXPLICIT_INT: kotlin.Int = 255
|
||||||
|
@kotlin.internal.ImplicitIntegerCoercion public const val IMPLICIT_INT: kotlin.Int = 255
|
||||||
|
@kotlin.internal.ImplicitIntegerCoercion public const val LONG_CONST: kotlin.Long = 255.toLong()
|
||||||
|
@kotlin.internal.ImplicitIntegerCoercion public val NON_CONST: kotlin.Int = 255
|
||||||
|
@kotlin.internal.ImplicitIntegerCoercion public const val UINT_CONST: kotlin.UInt = 42.toUInt()
|
||||||
|
public fun takeIntWithoutAnnotation(/*0*/ i: kotlin.Int): kotlin.Unit
|
||||||
|
public fun takeLong(/*0*/ @kotlin.internal.ImplicitIntegerCoercion l: kotlin.Long): kotlin.Unit
|
||||||
|
public fun takeUByte(/*0*/ @kotlin.internal.ImplicitIntegerCoercion u: kotlin.UByte): kotlin.Unit
|
||||||
|
public fun takeUBytes(/*0*/ @kotlin.internal.ImplicitIntegerCoercion vararg u: kotlin.UByte /*kotlin.UByteArray*/): kotlin.Unit
|
||||||
|
public fun takeUInt(/*0*/ @kotlin.internal.ImplicitIntegerCoercion u: kotlin.UInt): kotlin.Unit
|
||||||
|
public fun takeUIntWithoutAnnotaion(/*0*/ u: kotlin.UInt): kotlin.Unit
|
||||||
|
public fun takeULong(/*0*/ @kotlin.internal.ImplicitIntegerCoercion u: kotlin.ULong): kotlin.Unit
|
||||||
|
public fun takeUShort(/*0*/ @kotlin.internal.ImplicitIntegerCoercion u: kotlin.UShort): kotlin.Unit
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
|
|
||||||
|
package kotlin {
|
||||||
|
|
||||||
|
package kotlin.annotation {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.collections {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.comparisons {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.concurrent {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.coroutines {
|
||||||
|
|
||||||
|
package kotlin.coroutines.experimental {
|
||||||
|
|
||||||
|
package kotlin.coroutines.experimental.intrinsics {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.coroutines.experimental.jvm {
|
||||||
|
|
||||||
|
package kotlin.coroutines.experimental.jvm.internal {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.experimental {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.internal {
|
||||||
|
|
||||||
|
public final annotation class ImplicitIntegerCoercion : kotlin.Annotation {
|
||||||
|
public constructor ImplicitIntegerCoercion()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.internal.contracts {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.io {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.jvm {
|
||||||
|
|
||||||
|
package kotlin.jvm.functions {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.jvm.internal {
|
||||||
|
|
||||||
|
package kotlin.jvm.internal.markers {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.jvm.internal.unsafe {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.math {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.properties {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.ranges {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect {
|
||||||
|
|
||||||
|
package kotlin.reflect.full {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.components {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.builtins {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.builtins.functions {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.builtins.jvm {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.descriptors {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.descriptors.annotations {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.descriptors.deserialization {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.descriptors.impl {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.incremental {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.incremental.components {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.java {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.java.components {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.java.descriptors {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.java.lazy {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.java.lazy.types {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.java.sources {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.java.structure {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.java.typeEnhancement {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.kotlin {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.load.kotlin.header {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.metadata {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.metadata.builtins {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.metadata.deserialization {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.metadata.jvm {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.metadata.jvm.deserialization {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.name {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.protobuf {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.renderer {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.resolve {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.resolve.calls {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.resolve.calls.inference {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.resolve.constants {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.resolve.descriptorUtil {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.resolve.jvm {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.resolve.scopes {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.resolve.scopes.receivers {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.serialization {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.serialization.deserialization {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.serialization.deserialization.builtins {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.storage {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.types {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.types.checker {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.types.error {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.types.typeUtil {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.types.typesApproximation {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.util {
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.util.capitalizeDecapitalize {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.util.collectionUtils {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.impl.utils {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.pcollections {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal.structure {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.script {
|
||||||
|
|
||||||
|
package kotlin.script.dependencies {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.script.experimental {
|
||||||
|
|
||||||
|
package kotlin.script.experimental.dependencies {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.script.experimental.location {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.script.extensions {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.script.templates {
|
||||||
|
|
||||||
|
package kotlin.script.templates.standard {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.sequences {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.system {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.test {
|
||||||
|
}
|
||||||
|
|
||||||
|
package kotlin.text {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
// WITH_UNSIGNED
|
||||||
|
|
||||||
|
// FILE: signedToUnsignedConversions_annotation.kt
|
||||||
|
|
||||||
|
package kotlin.internal
|
||||||
|
|
||||||
|
annotation class ImplicitIntegerCoercion
|
||||||
|
|
||||||
|
// FILE: signedToUnsignedConversions_test.kt
|
||||||
|
|
||||||
|
import kotlin.internal.ImplicitIntegerCoercion
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
const val IMPLICIT_INT = 255
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
const val EXPLICIT_INT: Int = 255
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
const val LONG_CONST = 255L
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
val NON_CONST = 255
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
const val BIGGER_THAN_UBYTE = 256
|
||||||
|
|
||||||
|
@ImplicitIntegerCoercion
|
||||||
|
const val UINT_CONST = 42u
|
||||||
|
|
||||||
|
fun takeUByte(@ImplicitIntegerCoercion u: UByte) {}
|
||||||
|
fun takeUShort(@ImplicitIntegerCoercion u: UShort) {}
|
||||||
|
fun takeUInt(@ImplicitIntegerCoercion u: UInt) {}
|
||||||
|
fun takeULong(@ImplicitIntegerCoercion u: ULong) {}
|
||||||
|
|
||||||
|
fun takeUBytes(@ImplicitIntegerCoercion vararg u: UByte) {}
|
||||||
|
|
||||||
|
fun takeLong(@ImplicitIntegerCoercion l: Long) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
takeUByte(IMPLICIT_INT)
|
||||||
|
takeUByte(EXPLICIT_INT)
|
||||||
|
|
||||||
|
takeUShort(IMPLICIT_INT)
|
||||||
|
takeUShort(BIGGER_THAN_UBYTE)
|
||||||
|
|
||||||
|
takeUInt(IMPLICIT_INT)
|
||||||
|
|
||||||
|
takeULong(IMPLICIT_INT)
|
||||||
|
|
||||||
|
takeUBytes(IMPLICIT_INT, EXPLICIT_INT, 42u)
|
||||||
|
|
||||||
|
takeLong(IMPLICIT_INT)
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
FILE fqName:kotlin.internal fileName:/signedToUnsignedConversions_annotation.kt
|
||||||
|
CLASS ANNOTATION_CLASS name:ImplicitIntegerCoercion modality:FINAL visibility:public flags: superTypes:[kotlin.Annotation]
|
||||||
|
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:kotlin.internal.ImplicitIntegerCoercion flags:
|
||||||
|
CONSTRUCTOR visibility:public <> () returnType:kotlin.internal.ImplicitIntegerCoercion flags:primary
|
||||||
|
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags:
|
||||||
|
overridden:
|
||||||
|
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags:
|
||||||
|
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
|
||||||
|
VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags:
|
||||||
|
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags:
|
||||||
|
overridden:
|
||||||
|
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags:
|
||||||
|
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
|
||||||
|
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags:
|
||||||
|
overridden:
|
||||||
|
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags:
|
||||||
|
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
|
||||||
+136
@@ -0,0 +1,136 @@
|
|||||||
|
FILE fqName:<root> fileName:/signedToUnsignedConversions_test.kt
|
||||||
|
PROPERTY name:IMPLICIT_INT visibility:public modality:FINAL flags:const,val
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
FIELD PROPERTY_BACKING_FIELD name:IMPLICIT_INT type:kotlin.Int visibility:public flags:final
|
||||||
|
EXPRESSION_BODY
|
||||||
|
CONST Int type=kotlin.Int value=255
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-IMPLICIT_INT> visibility:public modality:FINAL <> () returnType:kotlin.Int flags:
|
||||||
|
correspondingProperty: PROPERTY name:IMPLICIT_INT visibility:public modality:FINAL flags:const,val
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='<get-IMPLICIT_INT>(): Int'
|
||||||
|
GET_FIELD 'IMPLICIT_INT: Int' type=kotlin.Int origin=null
|
||||||
|
PROPERTY name:EXPLICIT_INT visibility:public modality:FINAL flags:const,val
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
FIELD PROPERTY_BACKING_FIELD name:EXPLICIT_INT type:kotlin.Int visibility:public flags:final
|
||||||
|
EXPRESSION_BODY
|
||||||
|
CONST Int type=kotlin.Int value=255
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-EXPLICIT_INT> visibility:public modality:FINAL <> () returnType:kotlin.Int flags:
|
||||||
|
correspondingProperty: PROPERTY name:EXPLICIT_INT visibility:public modality:FINAL flags:const,val
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='<get-EXPLICIT_INT>(): Int'
|
||||||
|
GET_FIELD 'EXPLICIT_INT: Int' type=kotlin.Int origin=null
|
||||||
|
PROPERTY name:LONG_CONST visibility:public modality:FINAL flags:const,val
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
FIELD PROPERTY_BACKING_FIELD name:LONG_CONST type:kotlin.Long visibility:public flags:final
|
||||||
|
EXPRESSION_BODY
|
||||||
|
CONST Long type=kotlin.Long value=255
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-LONG_CONST> visibility:public modality:FINAL <> () returnType:kotlin.Long flags:
|
||||||
|
correspondingProperty: PROPERTY name:LONG_CONST visibility:public modality:FINAL flags:const,val
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='<get-LONG_CONST>(): Long'
|
||||||
|
GET_FIELD 'LONG_CONST: Long' type=kotlin.Long origin=null
|
||||||
|
PROPERTY name:NON_CONST visibility:public modality:FINAL flags:val
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
FIELD PROPERTY_BACKING_FIELD name:NON_CONST type:kotlin.Int visibility:public flags:final
|
||||||
|
EXPRESSION_BODY
|
||||||
|
CONST Int type=kotlin.Int value=255
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-NON_CONST> visibility:public modality:FINAL <> () returnType:kotlin.Int flags:
|
||||||
|
correspondingProperty: PROPERTY name:NON_CONST visibility:public modality:FINAL flags:val
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='<get-NON_CONST>(): Int'
|
||||||
|
GET_FIELD 'NON_CONST: Int' type=kotlin.Int origin=null
|
||||||
|
PROPERTY name:BIGGER_THAN_UBYTE visibility:public modality:FINAL flags:const,val
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
FIELD PROPERTY_BACKING_FIELD name:BIGGER_THAN_UBYTE type:kotlin.Int visibility:public flags:final
|
||||||
|
EXPRESSION_BODY
|
||||||
|
CONST Int type=kotlin.Int value=256
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-BIGGER_THAN_UBYTE> visibility:public modality:FINAL <> () returnType:kotlin.Int flags:
|
||||||
|
correspondingProperty: PROPERTY name:BIGGER_THAN_UBYTE visibility:public modality:FINAL flags:const,val
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='<get-BIGGER_THAN_UBYTE>(): Int'
|
||||||
|
GET_FIELD 'BIGGER_THAN_UBYTE: Int' type=kotlin.Int origin=null
|
||||||
|
PROPERTY name:UINT_CONST visibility:public modality:FINAL flags:const,val
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
FIELD PROPERTY_BACKING_FIELD name:UINT_CONST type:kotlin.UInt visibility:public flags:final
|
||||||
|
EXPRESSION_BODY
|
||||||
|
CONST Int type=kotlin.UInt value=42
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-UINT_CONST> visibility:public modality:FINAL <> () returnType:kotlin.UInt flags:
|
||||||
|
correspondingProperty: PROPERTY name:UINT_CONST visibility:public modality:FINAL flags:const,val
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='<get-UINT_CONST>(): UInt'
|
||||||
|
GET_FIELD 'UINT_CONST: UInt' type=kotlin.UInt origin=null
|
||||||
|
FUN name:takeUByte visibility:public modality:FINAL <> (u:kotlin.UByte) returnType:kotlin.Unit flags:
|
||||||
|
VALUE_PARAMETER name:u index:0 type:kotlin.UByte flags:
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
BLOCK_BODY
|
||||||
|
FUN name:takeUShort visibility:public modality:FINAL <> (u:kotlin.UShort) returnType:kotlin.Unit flags:
|
||||||
|
VALUE_PARAMETER name:u index:0 type:kotlin.UShort flags:
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
BLOCK_BODY
|
||||||
|
FUN name:takeUInt visibility:public modality:FINAL <> (u:kotlin.UInt) returnType:kotlin.Unit flags:
|
||||||
|
VALUE_PARAMETER name:u index:0 type:kotlin.UInt flags:
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
BLOCK_BODY
|
||||||
|
FUN name:takeULong visibility:public modality:FINAL <> (u:kotlin.ULong) returnType:kotlin.Unit flags:
|
||||||
|
VALUE_PARAMETER name:u index:0 type:kotlin.ULong flags:
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
BLOCK_BODY
|
||||||
|
FUN name:takeUBytes visibility:public modality:FINAL <> (u:kotlin.UByteArray) returnType:kotlin.Unit flags:
|
||||||
|
VALUE_PARAMETER name:u index:0 type:kotlin.UByteArray varargElementType:kotlin.UByte flags:vararg
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
BLOCK_BODY
|
||||||
|
FUN name:takeLong visibility:public modality:FINAL <> (l:kotlin.Long) returnType:kotlin.Unit flags:
|
||||||
|
VALUE_PARAMETER name:l index:0 type:kotlin.Long flags:
|
||||||
|
annotations:
|
||||||
|
CALL 'constructor ImplicitIntegerCoercion()' type=kotlin.internal.ImplicitIntegerCoercion origin=null
|
||||||
|
BLOCK_BODY
|
||||||
|
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit flags:
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL 'takeUByte(UByte): Unit' type=kotlin.Unit origin=null
|
||||||
|
u: TYPE_OP type=kotlin.UByte origin=IMPLICIT_INTEGER_COERCION typeOperand=kotlin.UByte
|
||||||
|
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:UByte modality:FINAL visibility:public flags: superTypes:[kotlin.Comparable<kotlin.UByte>]
|
||||||
|
CALL '<get-IMPLICIT_INT>(): Int' type=kotlin.Int origin=GET_PROPERTY
|
||||||
|
CALL 'takeUByte(UByte): Unit' type=kotlin.Unit origin=null
|
||||||
|
u: TYPE_OP type=kotlin.UByte origin=IMPLICIT_INTEGER_COERCION typeOperand=kotlin.UByte
|
||||||
|
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:UByte modality:FINAL visibility:public flags: superTypes:[kotlin.Comparable<kotlin.UByte>]
|
||||||
|
CALL '<get-EXPLICIT_INT>(): Int' type=kotlin.Int origin=GET_PROPERTY
|
||||||
|
CALL 'takeUShort(UShort): Unit' type=kotlin.Unit origin=null
|
||||||
|
u: TYPE_OP type=kotlin.UShort origin=IMPLICIT_INTEGER_COERCION typeOperand=kotlin.UShort
|
||||||
|
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:UShort modality:FINAL visibility:public flags: superTypes:[kotlin.Comparable<kotlin.UShort>]
|
||||||
|
CALL '<get-IMPLICIT_INT>(): Int' type=kotlin.Int origin=GET_PROPERTY
|
||||||
|
CALL 'takeUShort(UShort): Unit' type=kotlin.Unit origin=null
|
||||||
|
u: TYPE_OP type=kotlin.UShort origin=IMPLICIT_INTEGER_COERCION typeOperand=kotlin.UShort
|
||||||
|
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:UShort modality:FINAL visibility:public flags: superTypes:[kotlin.Comparable<kotlin.UShort>]
|
||||||
|
CALL '<get-BIGGER_THAN_UBYTE>(): Int' type=kotlin.Int origin=GET_PROPERTY
|
||||||
|
CALL 'takeUInt(UInt): Unit' type=kotlin.Unit origin=null
|
||||||
|
u: TYPE_OP type=kotlin.UInt origin=IMPLICIT_INTEGER_COERCION typeOperand=kotlin.UInt
|
||||||
|
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:UInt modality:FINAL visibility:public flags: superTypes:[kotlin.Comparable<kotlin.UInt>]
|
||||||
|
CALL '<get-IMPLICIT_INT>(): Int' type=kotlin.Int origin=GET_PROPERTY
|
||||||
|
CALL 'takeULong(ULong): Unit' type=kotlin.Unit origin=null
|
||||||
|
u: TYPE_OP type=kotlin.ULong origin=IMPLICIT_INTEGER_COERCION typeOperand=kotlin.ULong
|
||||||
|
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:ULong modality:FINAL visibility:public flags: superTypes:[kotlin.Comparable<kotlin.ULong>]
|
||||||
|
CALL '<get-IMPLICIT_INT>(): Int' type=kotlin.Int origin=GET_PROPERTY
|
||||||
|
CALL 'takeUBytes(vararg UByte): Unit' type=kotlin.Unit origin=null
|
||||||
|
u: VARARG type=kotlin.UByteArray varargElementType=kotlin.UByte
|
||||||
|
TYPE_OP type=kotlin.UByte origin=IMPLICIT_INTEGER_COERCION typeOperand=kotlin.UByte
|
||||||
|
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:UByte modality:FINAL visibility:public flags: superTypes:[kotlin.Comparable<kotlin.UByte>]
|
||||||
|
CALL '<get-IMPLICIT_INT>(): Int' type=kotlin.Int origin=GET_PROPERTY
|
||||||
|
TYPE_OP type=kotlin.UByte origin=IMPLICIT_INTEGER_COERCION typeOperand=kotlin.UByte
|
||||||
|
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:UByte modality:FINAL visibility:public flags: superTypes:[kotlin.Comparable<kotlin.UByte>]
|
||||||
|
CALL '<get-EXPLICIT_INT>(): Int' type=kotlin.Int origin=GET_PROPERTY
|
||||||
|
CONST Byte type=kotlin.UByte value=42
|
||||||
|
CALL 'takeLong(Long): Unit' type=kotlin.Unit origin=null
|
||||||
|
l: TYPE_OP type=kotlin.Long origin=IMPLICIT_INTEGER_COERCION typeOperand=kotlin.Long
|
||||||
|
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Long modality:FINAL visibility:public flags: superTypes:[kotlin.Number; kotlin.Comparable<kotlin.Long>; java.io.Serializable]
|
||||||
|
CALL '<get-IMPLICIT_INT>(): Int' type=kotlin.Int origin=GET_PROPERTY
|
||||||
+1
-1
@@ -66,7 +66,7 @@ class ConstraintSystemTestData(
|
|||||||
val matcher = INTEGER_VALUE_TYPE_PATTERN.matcher(name)
|
val matcher = INTEGER_VALUE_TYPE_PATTERN.matcher(name)
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
val number = matcher.group(1)!!
|
val number = matcher.group(1)!!
|
||||||
val parameters = CompileTimeConstant.Parameters(false, false, false, false, false, false)
|
val parameters = CompileTimeConstant.Parameters(false, false, false, false, false, false, false)
|
||||||
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
IntegerValueTypeConstructor(number.toLong(), functionFoo.module, parameters),
|
IntegerValueTypeConstructor(number.toLong(), functionFoo.module, parameters),
|
||||||
|
|||||||
+18
@@ -83,4 +83,22 @@ public class DiagnosticsWithUnsignedTypesGenerated extends AbstractDiagnosticsWi
|
|||||||
public void testWrongLongSuffixForULong() throws Exception {
|
public void testWrongLongSuffixForULong() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithUnsignedTypes/wrongLongSuffixForULong.kt");
|
runTest("compiler/testData/diagnostics/testsWithUnsignedTypes/wrongLongSuffixForULong.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/testsWithUnsignedTypes/conversions")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Conversions extends AbstractDiagnosticsWithUnsignedTypes {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInConversions() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithUnsignedTypes/conversions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("conversionOfSignedToUnsigned.kt")
|
||||||
|
public void testConversionOfSignedToUnsigned() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithUnsignedTypes/conversions/conversionOfSignedToUnsigned.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1032,6 +1032,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
runTest("compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.kt");
|
runTest("compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("signedToUnsignedConversions.kt")
|
||||||
|
public void testSignedToUnsignedConversions() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/expressions/signedToUnsignedConversions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("simpleOperators.kt")
|
@TestMetadata("simpleOperators.kt")
|
||||||
public void testSimpleOperators() throws Exception {
|
public void testSimpleOperators() throws Exception {
|
||||||
runTest("compiler/testData/ir/irText/expressions/simpleOperators.kt");
|
runTest("compiler/testData/ir/irText/expressions/simpleOperators.kt");
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ interface CompileTimeConstant<out T> {
|
|||||||
// `isUnsignedLongNumberLiteral` means that this constant represents simple number literal with `{uU}{lL}` suffix (123uL, 0xFEUL)
|
// `isUnsignedLongNumberLiteral` means that this constant represents simple number literal with `{uU}{lL}` suffix (123uL, 0xFEUL)
|
||||||
val isUnsignedLongNumberLiteral: Boolean,
|
val isUnsignedLongNumberLiteral: Boolean,
|
||||||
val usesVariableAsConstant: Boolean,
|
val usesVariableAsConstant: Boolean,
|
||||||
val usesNonConstValAsConstant: Boolean
|
val usesNonConstValAsConstant: Boolean,
|
||||||
|
// `isConvertableConstVal` means that this is `const val` that has `ImplicitIntegerCoercion` annotation
|
||||||
|
val isConvertableConstVal: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean
|
override fun equals(other: Any?): Boolean
|
||||||
|
|||||||
+26
-5
@@ -39,17 +39,38 @@ class IntegerValueTypeConstructor(
|
|||||||
// 'getPrimitiveNumberType' returns first of supertypes that is a subtype of expected type
|
// 'getPrimitiveNumberType' returns first of supertypes that is a subtype of expected type
|
||||||
// for expected type 'Any' result type 'Int' should be returned
|
// for expected type 'Any' result type 'Int' should be returned
|
||||||
val isUnsigned = parameters.isUnsignedNumberLiteral
|
val isUnsigned = parameters.isUnsignedNumberLiteral
|
||||||
|
val isConvertable = parameters.isConvertableConstVal
|
||||||
|
|
||||||
if (isUnsigned) {
|
if (isUnsigned || isConvertable) {
|
||||||
assert(hasUnsignedTypesInModuleDependencies(module)) {
|
assert(hasUnsignedTypesInModuleDependencies(module)) {
|
||||||
"Unsigned types should be on classpath to create an unsigned type constructor"
|
"Unsigned types should be on classpath to create an unsigned type constructor"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkBoundsAndAddSuperType(value, if (isUnsigned) unsignedType(KotlinBuiltIns.FQ_NAMES.uInt) else builtIns.intType)
|
when {
|
||||||
checkBoundsAndAddSuperType(value, if (isUnsigned) unsignedType(KotlinBuiltIns.FQ_NAMES.uByte) else builtIns.byteType)
|
isConvertable -> {
|
||||||
checkBoundsAndAddSuperType(value, if (isUnsigned) unsignedType(KotlinBuiltIns.FQ_NAMES.uShort) else builtIns.shortType)
|
addSignedSuperTypes()
|
||||||
supertypes.add(if (isUnsigned) unsignedType(KotlinBuiltIns.FQ_NAMES.uLong) else builtIns.longType)
|
addUnsignedSuperTypes()
|
||||||
|
}
|
||||||
|
|
||||||
|
isUnsigned -> addUnsignedSuperTypes()
|
||||||
|
|
||||||
|
else -> addSignedSuperTypes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addSignedSuperTypes() {
|
||||||
|
checkBoundsAndAddSuperType(value, builtIns.intType)
|
||||||
|
checkBoundsAndAddSuperType(value, builtIns.byteType)
|
||||||
|
checkBoundsAndAddSuperType(value, builtIns.shortType)
|
||||||
|
supertypes.add(builtIns.longType)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addUnsignedSuperTypes() {
|
||||||
|
checkBoundsAndAddSuperType(value, unsignedType(KotlinBuiltIns.FQ_NAMES.uInt))
|
||||||
|
checkBoundsAndAddSuperType(value, unsignedType(KotlinBuiltIns.FQ_NAMES.uByte))
|
||||||
|
checkBoundsAndAddSuperType(value, unsignedType(KotlinBuiltIns.FQ_NAMES.uShort))
|
||||||
|
supertypes.add(unsignedType(KotlinBuiltIns.FQ_NAMES.uLong))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkBoundsAndAddSuperType(value: Long, kotlinType: KotlinType) {
|
private fun checkBoundsAndAddSuperType(value: Long, kotlinType: KotlinType) {
|
||||||
|
|||||||
Reference in New Issue
Block a user