Implement new logic of approximation of integer literals in position of receiver
#KT-38895 In Progress
This commit is contained in:
committed by
TeamCityServer
parent
6afb905ad6
commit
bee2a69e21
+6
@@ -19087,6 +19087,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("newLiteralOperatorsResolution_newResolve.kt")
|
||||
public void testNewLiteralOperatorsResolution_newResolve() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_newResolve.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("newLiteralOperatorsResolution_warning.kt")
|
||||
public void testNewLiteralOperatorsResolution_warning() throws Exception {
|
||||
|
||||
+53
-18
@@ -279,9 +279,10 @@ class ConstantExpressionEvaluator(
|
||||
fun evaluateExpression(
|
||||
expression: KtExpression,
|
||||
trace: BindingTrace,
|
||||
expectedType: KotlinType? = TypeUtils.NO_EXPECTED_TYPE
|
||||
expectedType: KotlinType? = TypeUtils.NO_EXPECTED_TYPE,
|
||||
isIndependentContext: Boolean = false
|
||||
): CompileTimeConstant<*>? {
|
||||
val visitor = ConstantExpressionEvaluatorVisitor(this, trace)
|
||||
val visitor = ConstantExpressionEvaluatorVisitor(this, trace, isIndependentContext)
|
||||
val constant = visitor.evaluate(expression, expectedType) ?: return null
|
||||
|
||||
checkExperimentalityOfConstantLiteral(expression, constant, expectedType, trace)
|
||||
@@ -369,10 +370,12 @@ private val DIVISION_OPERATION_NAMES =
|
||||
|
||||
private class ConstantExpressionEvaluatorVisitor(
|
||||
private val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
||||
private val trace: BindingTrace
|
||||
private val trace: BindingTrace,
|
||||
private val isIndependentContext: Boolean
|
||||
) : KtVisitor<CompileTimeConstant<*>?, KotlinType>() {
|
||||
private val languageVersionSettings = constantExpressionEvaluator.languageVersionSettings
|
||||
private val builtIns = constantExpressionEvaluator.module.builtIns
|
||||
private val defaultValueForDontCreateIntegerLiteralType = languageVersionSettings.supportsFeature(LanguageFeature.ApproximateIntegerLiteralTypesInReceiverPosition)
|
||||
|
||||
fun evaluate(expression: KtExpression, expectedType: KotlinType?): CompileTimeConstant<*>? {
|
||||
val recordedCompileTimeConstant = ConstantExpressionEvaluator.getPossiblyErrorConstant(expression, trace.bindingContext)
|
||||
@@ -472,7 +475,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
isUnsignedLongNumberLiteral = isUnsignedLong,
|
||||
usesVariableAsConstant = false,
|
||||
usesNonConstValAsConstant = false,
|
||||
isConvertableConstVal = false
|
||||
isConvertableConstVal = false,
|
||||
dontCreateILT = defaultValueForDontCreateIntegerLiteralType && isIndependentContext
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -522,7 +526,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
canBeUsedInAnnotation = canBeUsedInAnnotation,
|
||||
usesVariableAsConstant = usesVariableAsConstant,
|
||||
usesNonConstValAsConstant = usesNonConstantVariableAsConstant,
|
||||
isConvertableConstVal = false
|
||||
isConvertableConstVal = false,
|
||||
dontCreateILT = false
|
||||
)
|
||||
)
|
||||
else null
|
||||
@@ -586,7 +591,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
isUnsignedLongNumberLiteral = false,
|
||||
usesVariableAsConstant = leftConstant.usesVariableAsConstant || rightConstant.usesVariableAsConstant,
|
||||
usesNonConstValAsConstant = leftConstant.usesNonConstValAsConstant || rightConstant.usesNonConstValAsConstant,
|
||||
isConvertableConstVal = false
|
||||
isConvertableConstVal = false,
|
||||
dontCreateILT = false
|
||||
)
|
||||
)
|
||||
} else {
|
||||
@@ -605,7 +611,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
private fun evaluateCall(
|
||||
callExpression: KtExpression,
|
||||
receiverExpression: KtExpression,
|
||||
expectedType: KotlinType?
|
||||
expectedType: KotlinType?,
|
||||
isUnaryPlusMinus: Boolean = false
|
||||
): CompileTimeConstant<*>? {
|
||||
val resolvedCall = callExpression.getResolvedCall(trace.bindingContext) ?: return null
|
||||
if (!KotlinBuiltIns.isUnderKotlinPackage(resolvedCall.resultingDescriptor)) return null
|
||||
@@ -632,9 +639,12 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation,
|
||||
!isNumberConversionMethod && isArgumentPure,
|
||||
false, false,
|
||||
usesVariableAsConstant, usesNonConstValAsConstant,
|
||||
false
|
||||
isUnsignedNumberLiteral = false,
|
||||
isUnsignedLongNumberLiteral = false,
|
||||
usesVariableAsConstant,
|
||||
usesNonConstValAsConstant,
|
||||
isConvertableConstVal = false,
|
||||
dontCreateILT = !isUnaryPlusMinus && defaultValueForDontCreateIntegerLiteralType && !hasIntegerLiteralType(receiverExpression)
|
||||
)
|
||||
)
|
||||
} else if (argumentsEntrySet.size == 1) {
|
||||
@@ -667,7 +677,14 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
val usesNonConstValAsConstant =
|
||||
usesNonConstValAsConstant(argumentForReceiver.expression) || usesNonConstValAsConstant(argumentForParameter.expression)
|
||||
val parameters = CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation, areArgumentsPure, false, false, usesVariableAsConstant, usesNonConstValAsConstant, false
|
||||
canBeUsedInAnnotation,
|
||||
areArgumentsPure,
|
||||
isUnsignedNumberLiteral = false,
|
||||
isUnsignedLongNumberLiteral = false,
|
||||
usesVariableAsConstant,
|
||||
usesNonConstValAsConstant,
|
||||
isConvertableConstVal = false,
|
||||
dontCreateILT = defaultValueForDontCreateIntegerLiteralType && !hasIntegerLiteralType(receiverExpression)
|
||||
)
|
||||
return when (resultingDescriptorName) {
|
||||
OperatorNameConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression)?.wrap(parameters)
|
||||
@@ -693,6 +710,9 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
private fun isPureConstant(expression: KtExpression) =
|
||||
ConstantExpressionEvaluator.getConstant(expression, trace.bindingContext)?.isPure ?: false
|
||||
|
||||
private fun hasIntegerLiteralType(expression: KtExpression): Boolean =
|
||||
ConstantExpressionEvaluator.getConstant(expression, trace.bindingContext)?.hasIntegerLiteralType ?: false
|
||||
|
||||
private fun evaluateUnaryAndCheck(receiver: OperationArgument, name: String, callExpression: KtExpression): Any? {
|
||||
return evaluateUnaryAndCheck(name, receiver.ctcType, receiver.value) {
|
||||
trace.report(Errors.INTEGER_OVERFLOW.on(callExpression.getStrictParentOfType<KtExpression>() ?: callExpression))
|
||||
@@ -716,8 +736,13 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
|
||||
override fun visitUnaryExpression(expression: KtUnaryExpression, expectedType: KotlinType?): CompileTimeConstant<*>? {
|
||||
val leftExpression = expression.baseExpression ?: return null
|
||||
|
||||
return evaluateCall(expression.operationReference, leftExpression, expectedType)
|
||||
val tokenType = expression.operationToken
|
||||
return evaluateCall(
|
||||
expression.operationReference,
|
||||
leftExpression,
|
||||
expectedType,
|
||||
isUnaryPlusMinus = tokenType == KtTokens.PLUS || tokenType == KtTokens.MINUS
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, expectedType: KotlinType?): CompileTimeConstant<*>? {
|
||||
@@ -747,7 +772,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
isUnsignedLongNumberLiteral = false,
|
||||
usesVariableAsConstant = true,
|
||||
usesNonConstValAsConstant = !callableDescriptor.isConst,
|
||||
isConvertableConstVal = isConvertableConstVal
|
||||
isConvertableConstVal = isConvertableConstVal,
|
||||
dontCreateILT = true
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -981,7 +1007,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
value: Long,
|
||||
parameters: CompileTimeConstant.Parameters,
|
||||
expectedType: KotlinType
|
||||
): CompileTimeConstant<*>? {
|
||||
): CompileTimeConstant<*> {
|
||||
if (parameters.isUnsignedNumberLiteral && !checkAccessibilityOfUnsignedTypes()) {
|
||||
return UnsignedErrorValueTypeConstant(value, parameters)
|
||||
}
|
||||
@@ -991,7 +1017,9 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
}
|
||||
|
||||
if (TypeUtils.noExpectedType(expectedType) || expectedType.isError) {
|
||||
return createIntegerValueTypeConstant(
|
||||
return if (parameters.dontCreateILT) {
|
||||
value.createSimpleIntCompileTimeConst(parameters)
|
||||
} else createIntegerValueTypeConstant(
|
||||
value,
|
||||
constantExpressionEvaluator.module,
|
||||
parameters,
|
||||
@@ -1005,6 +1033,11 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
return integerValue.wrap(parameters)
|
||||
}
|
||||
|
||||
return value.createSimpleIntCompileTimeConst(parameters)
|
||||
}
|
||||
|
||||
private fun Long.createSimpleIntCompileTimeConst(parameters: CompileTimeConstant.Parameters): TypedCompileTimeConstant<*> {
|
||||
val value = this
|
||||
return if (parameters.isUnsignedNumberLiteral) {
|
||||
when (value) {
|
||||
value.toInt().fromUIntToLong() -> UIntValue(value.toInt())
|
||||
@@ -1035,7 +1068,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
isUnsignedLong: Boolean = false,
|
||||
usesVariableAsConstant: Boolean = false,
|
||||
usesNonConstValAsConstant: Boolean = false,
|
||||
isConvertableConstVal: Boolean = false
|
||||
isConvertableConstVal: Boolean = false,
|
||||
dontCreateILT: Boolean = false
|
||||
): TypedCompileTimeConstant<T> =
|
||||
wrap(
|
||||
CompileTimeConstant.Parameters(
|
||||
@@ -1045,7 +1079,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
isUnsignedLong,
|
||||
usesVariableAsConstant,
|
||||
usesNonConstValAsConstant,
|
||||
isConvertableConstVal
|
||||
isConvertableConstVal,
|
||||
dontCreateILT
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
+11
-5
@@ -172,7 +172,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
KotlinTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, null, null, context);
|
||||
checkNull(expression, context, typeInfo.getType());
|
||||
|
||||
components.constantExpressionEvaluator.evaluateExpression(expression, context.trace, context.expectedType);
|
||||
components.constantExpressionEvaluator.evaluateExpression(
|
||||
expression, context.trace, context.expectedType, evaluateIntegerConstantInIndependentMode(context)
|
||||
);
|
||||
return components.dataFlowAnalyzer.checkType(typeInfo, expression, context); // TODO : Extensions to this
|
||||
}
|
||||
|
||||
@@ -207,7 +209,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
|
||||
CompileTimeConstant<?> compileTimeConstant = components.constantExpressionEvaluator.evaluateExpression(
|
||||
expression, context.trace, context.expectedType
|
||||
expression, context.trace, context.expectedType, evaluateIntegerConstantInIndependentMode(context)
|
||||
);
|
||||
|
||||
if (compileTimeConstant instanceof UnsignedErrorValueTypeConstant) {
|
||||
@@ -793,7 +795,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
|
||||
CompileTimeConstant<?> value = components.constantExpressionEvaluator.evaluateExpression(
|
||||
expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType
|
||||
expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType, evaluateIntegerConstantInIndependentMode(context)
|
||||
);
|
||||
if (value != null) {
|
||||
return components.dataFlowAnalyzer.createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType);
|
||||
@@ -1086,7 +1088,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
result = TypeInfoFactoryKt.noTypeInfo(context);
|
||||
}
|
||||
CompileTimeConstant<?> value = components.constantExpressionEvaluator.evaluateExpression(
|
||||
expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType
|
||||
expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType, evaluateIntegerConstantInIndependentMode(context)
|
||||
);
|
||||
if (value != null) {
|
||||
return components.dataFlowAnalyzer.createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType);
|
||||
@@ -1595,7 +1597,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
for (KtStringTemplateEntry entry : expression.getEntries()) {
|
||||
entry.accept(visitor);
|
||||
}
|
||||
components.constantExpressionEvaluator.evaluateExpression(expression, context.trace, contextWithExpectedType.expectedType);
|
||||
components.constantExpressionEvaluator.evaluateExpression(expression, context.trace, contextWithExpectedType.expectedType, evaluateIntegerConstantInIndependentMode(context));
|
||||
return components.dataFlowAnalyzer.checkType(visitor.typeInfo.replaceType(components.builtIns.getStringType()),
|
||||
expression,
|
||||
contextWithExpectedType);
|
||||
@@ -1798,4 +1800,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
return BindingContextUtils.getRecordedTypeInfo(expression, context.trace.getBindingContext());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean evaluateIntegerConstantInIndependentMode(ExpressionTypingContext context) {
|
||||
return context.contextDependency == INDEPENDENT && context.languageVersionSettings.supportsFeature(LanguageFeature.ApproximateIntegerLiteralTypesInReceiverPosition);
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+116
@@ -0,0 +1,116 @@
|
||||
// LANGUAGE: +ApproximateIntegerLiteralTypesInReceiverPosition
|
||||
// WITH_STDLIB
|
||||
// ISSUE: KT-38895
|
||||
|
||||
fun takeByte(b: Byte) {}
|
||||
fun takeInt(b: Int) {}
|
||||
fun takeLong(b: Long) {}
|
||||
|
||||
fun testByteBinaryOperators() {
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 + 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 - 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 * 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 / 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 % 1<!>)
|
||||
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.plus(1)<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.minus(1)<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.times(1)<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.div(1)<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.rem(1)<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 shl 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 shr 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 ushr 1<!>)
|
||||
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 and 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 or 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 xor 1<!>)
|
||||
}
|
||||
|
||||
fun testByteUnaryOperators() {
|
||||
// No mismatch
|
||||
takeByte(+1)
|
||||
takeByte(-1)
|
||||
|
||||
// Mismatch
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.unaryPlus()<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.unaryMinus()<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.inv()<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>1.inc()<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>1.dec()<!>)
|
||||
}
|
||||
|
||||
fun testLongBinaryOperators() {
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 + 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 - 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 * 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 / 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 % 1<!>)
|
||||
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.plus(1)<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.minus(1)<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.times(1)<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.div(1)<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.rem(1)<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shl 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shr 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 ushr 1<!>)
|
||||
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 and 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 or 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 xor 1<!>)
|
||||
|
||||
// positive
|
||||
takeLong(2 * 100000000000)
|
||||
}
|
||||
|
||||
fun testLongUnaryOperators() {
|
||||
// No mismatch
|
||||
takeLong(+1)
|
||||
takeLong(-1)
|
||||
|
||||
// Mismatch
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.unaryPlus()<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.unaryMinus()<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.inv()<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>1.inc()<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>1.dec()<!>)
|
||||
}
|
||||
|
||||
fun testIntBinaryOperators() {
|
||||
takeInt(2 + 1)
|
||||
takeInt(2 - 1)
|
||||
takeInt(2 * 1)
|
||||
takeInt(2 / 1)
|
||||
takeInt(2 % 1)
|
||||
|
||||
takeInt(2.plus(1))
|
||||
takeInt(2.minus(1))
|
||||
takeInt(2.times(1))
|
||||
takeInt(2.div(1))
|
||||
takeInt(2.rem(1))
|
||||
takeInt(2 shl 1)
|
||||
takeInt(2 shr 1)
|
||||
takeInt(2 ushr 1)
|
||||
|
||||
takeInt(2 and 1)
|
||||
takeInt(2 or 1)
|
||||
takeInt(2 xor 1)
|
||||
}
|
||||
|
||||
fun testIntUnaryOperators() {
|
||||
takeInt(+1)
|
||||
takeInt(-1)
|
||||
|
||||
takeInt(2.unaryPlus())
|
||||
takeInt(2.unaryMinus())
|
||||
takeInt(2.inv())
|
||||
takeInt(1.inc())
|
||||
takeInt(1.dec())
|
||||
}
|
||||
|
||||
fun testNoOperators() {
|
||||
takeByte(1)
|
||||
takeInt(1)
|
||||
takeLong(1)
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
// LANGUAGE: +ApproximateIntegerLiteralTypesInReceiverPosition
|
||||
// WITH_STDLIB
|
||||
// ISSUE: KT-38895
|
||||
|
||||
fun takeByte(b: Byte) {}
|
||||
fun takeInt(b: Int) {}
|
||||
fun takeLong(b: Long) {}
|
||||
|
||||
fun testByteBinaryOperators() {
|
||||
takeByte(<!TYPE_MISMATCH!>2 + 1<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2 - 1<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2 * 1<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2 / 1<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2 % 1<!>)
|
||||
|
||||
takeByte(<!TYPE_MISMATCH!>2.plus(1)<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2.minus(1)<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2.times(1)<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2.div(1)<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2.rem(1)<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2 shl 1<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2 shr 1<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2 ushr 1<!>)
|
||||
|
||||
takeByte(<!TYPE_MISMATCH!>2 and 1<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2 or 1<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2 xor 1<!>)
|
||||
}
|
||||
|
||||
fun testByteUnaryOperators() {
|
||||
// No mismatch
|
||||
takeByte(+1)
|
||||
takeByte(-1)
|
||||
|
||||
// Mismatch
|
||||
takeByte(<!TYPE_MISMATCH!>2.unaryPlus()<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2.unaryMinus()<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>2.inv()<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>1.inc()<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>1.dec()<!>)
|
||||
}
|
||||
|
||||
fun testLongBinaryOperators() {
|
||||
takeLong(<!TYPE_MISMATCH!>2 + 1<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2 - 1<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2 * 1<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2 / 1<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2 % 1<!>)
|
||||
|
||||
takeLong(<!TYPE_MISMATCH!>2.plus(1)<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2.minus(1)<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2.times(1)<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2.div(1)<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2.rem(1)<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2 shl 1<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2 shr 1<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2 ushr 1<!>)
|
||||
|
||||
takeLong(<!TYPE_MISMATCH!>2 and 1<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2 or 1<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2 xor 1<!>)
|
||||
|
||||
// positive
|
||||
takeLong(2 * 100000000000)
|
||||
}
|
||||
|
||||
fun testLongUnaryOperators() {
|
||||
// No mismatch
|
||||
takeLong(+1)
|
||||
takeLong(-1)
|
||||
|
||||
// Mismatch
|
||||
takeLong(<!TYPE_MISMATCH!>2.unaryPlus()<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2.unaryMinus()<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>2.inv()<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>1.inc()<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>1.dec()<!>)
|
||||
}
|
||||
|
||||
fun testIntBinaryOperators() {
|
||||
takeInt(2 + 1)
|
||||
takeInt(2 - 1)
|
||||
takeInt(2 * 1)
|
||||
takeInt(2 / 1)
|
||||
takeInt(2 % 1)
|
||||
|
||||
takeInt(2.plus(1))
|
||||
takeInt(2.minus(1))
|
||||
takeInt(2.times(1))
|
||||
takeInt(2.div(1))
|
||||
takeInt(2.rem(1))
|
||||
takeInt(2 shl 1)
|
||||
takeInt(2 shr 1)
|
||||
takeInt(2 ushr 1)
|
||||
|
||||
takeInt(2 and 1)
|
||||
takeInt(2 or 1)
|
||||
takeInt(2 xor 1)
|
||||
}
|
||||
|
||||
fun testIntUnaryOperators() {
|
||||
takeInt(+1)
|
||||
takeInt(-1)
|
||||
|
||||
takeInt(2.unaryPlus())
|
||||
takeInt(2.unaryMinus())
|
||||
takeInt(2.inv())
|
||||
takeInt(1.inc())
|
||||
takeInt(1.dec())
|
||||
}
|
||||
|
||||
fun testNoOperators() {
|
||||
takeByte(1)
|
||||
takeInt(1)
|
||||
takeLong(1)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
public fun takeByte(/*0*/ b: kotlin.Byte): kotlin.Unit
|
||||
public fun takeInt(/*0*/ b: kotlin.Int): kotlin.Unit
|
||||
public fun takeLong(/*0*/ b: kotlin.Long): kotlin.Unit
|
||||
public fun testByteBinaryOperators(): kotlin.Unit
|
||||
public fun testByteUnaryOperators(): kotlin.Unit
|
||||
public fun testIntBinaryOperators(): kotlin.Unit
|
||||
public fun testIntUnaryOperators(): kotlin.Unit
|
||||
public fun testLongBinaryOperators(): kotlin.Unit
|
||||
public fun testLongUnaryOperators(): kotlin.Unit
|
||||
public fun testNoOperators(): kotlin.Unit
|
||||
Generated
+6
@@ -19093,6 +19093,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("newLiteralOperatorsResolution_newResolve.kt")
|
||||
public void testNewLiteralOperatorsResolution_newResolve() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_newResolve.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("newLiteralOperatorsResolution_warning.kt")
|
||||
public void testNewLiteralOperatorsResolution_warning() throws Exception {
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ class ConstraintSystemTestData(
|
||||
val matcher = INTEGER_VALUE_TYPE_PATTERN.matcher(name)
|
||||
if (matcher.find()) {
|
||||
val number = matcher.group(1)!!
|
||||
val parameters = CompileTimeConstant.Parameters(false, false, false, false, false, false, false)
|
||||
val parameters = CompileTimeConstant.Parameters(false, false, false, false, false, false, false, false)
|
||||
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||
Annotations.EMPTY,
|
||||
IntegerValueTypeConstructor(number.toLong(), functionFoo.module, parameters),
|
||||
|
||||
@@ -46,6 +46,8 @@ interface CompileTimeConstant<out T> {
|
||||
|
||||
val isUnsignedNumberLiteral: Boolean get() = parameters.isUnsignedNumberLiteral
|
||||
|
||||
val hasIntegerLiteralType: Boolean
|
||||
|
||||
data class Parameters(
|
||||
val canBeUsedInAnnotation: Boolean,
|
||||
val isPure: Boolean,
|
||||
@@ -56,7 +58,8 @@ interface CompileTimeConstant<out T> {
|
||||
val usesVariableAsConstant: Boolean,
|
||||
val usesNonConstValAsConstant: Boolean,
|
||||
// `isConvertableConstVal` means that this is `const val` that has `ImplicitIntegerCoercion` annotation
|
||||
val isConvertableConstVal: Boolean
|
||||
val isConvertableConstVal: Boolean,
|
||||
val dontCreateILT: Boolean
|
||||
)
|
||||
|
||||
override fun equals(other: Any?): Boolean
|
||||
@@ -90,6 +93,9 @@ class TypedCompileTimeConstant<out T>(
|
||||
result = 31 * result + type.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override val hasIntegerLiteralType: Boolean
|
||||
get() = false
|
||||
}
|
||||
|
||||
fun createIntegerValueTypeConstant(
|
||||
@@ -120,6 +126,9 @@ class UnsignedErrorValueTypeConstant(
|
||||
override fun equals(other: Any?) = other is UnsignedErrorValueTypeConstant && value == other.value
|
||||
|
||||
override fun hashCode() = value.hashCode()
|
||||
|
||||
override val hasIntegerLiteralType: Boolean
|
||||
get() = false
|
||||
}
|
||||
|
||||
class IntegerValueTypeConstant(
|
||||
@@ -139,7 +148,8 @@ class IntegerValueTypeConstant(
|
||||
isUnsignedLongNumberLiteral = parameters.isUnsignedLongNumberLiteral,
|
||||
usesVariableAsConstant = parameters.usesVariableAsConstant,
|
||||
usesNonConstValAsConstant = parameters.usesNonConstValAsConstant,
|
||||
isConvertableConstVal = parameters.isConvertableConstVal
|
||||
isConvertableConstVal = parameters.isConvertableConstVal,
|
||||
dontCreateILT = false
|
||||
)
|
||||
|
||||
return IntegerValueTypeConstant(value, module, newParameters, newInferenceEnabled, convertedFromSigned = true)
|
||||
@@ -153,7 +163,8 @@ class IntegerValueTypeConstant(
|
||||
isUnsignedLongNumberLiteral = parameters.isUnsignedLongNumberLiteral,
|
||||
usesVariableAsConstant = parameters.usesVariableAsConstant,
|
||||
usesNonConstValAsConstant = parameters.usesNonConstValAsConstant,
|
||||
isConvertableConstVal = parameters.isConvertableConstVal
|
||||
isConvertableConstVal = parameters.isConvertableConstVal,
|
||||
dontCreateILT = false
|
||||
)
|
||||
|
||||
return IntegerValueTypeConstant(value, module, newParameters, newInferenceEnabled, convertedFromSigned = true)
|
||||
@@ -202,4 +213,6 @@ class IntegerValueTypeConstant(
|
||||
|
||||
override fun hashCode() = 31 * value.hashCode() + parameters.hashCode()
|
||||
|
||||
override val hasIntegerLiteralType: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user