mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-16 15:52:18 +00:00
[FIR] Desugar unary plus and minus as part of integer literal
#KT-42016
This commit is contained in:
@@ -4,5 +4,5 @@ FILE: nonCommutativeRepeat.kt
|
||||
R|<local>/x| = R|<local>/x|.R|kotlin/Int.minus|(Int(1)).R|kotlin/Int.minus|(Int(1))
|
||||
R|<local>/x| = R|<local>/x|.R|kotlin/Int.div|(Int(1))
|
||||
R|<local>/x| = Int(1).R|kotlin/Int.div|(R|<local>/x|)
|
||||
R|<local>/x| = Int(1).R|kotlin/Int.unaryMinus|().R|kotlin/Int.plus|(R|<local>/x|)
|
||||
R|<local>/x| = Int(-1).R|kotlin/Int.plus|(R|<local>/x|)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ FILE: NoWarning.kt
|
||||
lval a: R|kotlin/ranges/IntProgression| = Int(4).R|kotlin/ranges/downTo|(Int(3))
|
||||
lval v: R|kotlin/Int| = Int(1)
|
||||
when () {
|
||||
Int(5).R|kotlin/Int.unaryMinus|().R|kotlin/ranges/downTo|(Int(6).R|kotlin/Int.unaryMinus|()).R|kotlin/collections/contains|<R|kotlin/Int|>(R|<local>/v|) -> {
|
||||
Int(-5).R|kotlin/ranges/downTo|(Int(-6)).R|kotlin/collections/contains|<R|kotlin/Int|>(R|<local>/v|) -> {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ FILE: NoWarning.kt
|
||||
lval a: R|kotlin/ranges/IntRange| = Int(3).R|kotlin/ranges/until|(Int(4))
|
||||
lval v: R|kotlin/Int| = Int(1)
|
||||
when () {
|
||||
Int(5).R|kotlin/Int.unaryMinus|().R|kotlin/ranges/until|(Int(4).R|kotlin/Int.unaryMinus|()).R|kotlin/ranges/IntRange.contains|(R|<local>/v|) -> {
|
||||
Int(-5).R|kotlin/ranges/until|(Int(-4)).R|kotlin/ranges/IntRange.contains|(R|<local>/v|) -> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ FILE: Warning.kt
|
||||
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
|
||||
}
|
||||
|
||||
lval a: R|kotlin/ranges/IntProgression| = Int(3).R|kotlin/Int.unaryMinus|().R|kotlin/ranges/downTo|(Int(4))
|
||||
lval a: R|kotlin/ranges/IntProgression| = Int(-3).R|kotlin/ranges/downTo|(Int(4))
|
||||
lval v: R|kotlin/Int| = Int(1)
|
||||
when () {
|
||||
Int(0).R|kotlin/ranges/downTo|(Int(6)).R|kotlin/collections/contains|<R|kotlin/Int|>(R|<local>/v|) -> {
|
||||
@@ -36,7 +36,7 @@ FILE: Warning.kt
|
||||
lval a: R|kotlin/ranges/IntRange| = Int(4).R|kotlin/ranges/until|(Int(3))
|
||||
lval v: R|kotlin/Int| = Int(1)
|
||||
when () {
|
||||
Int(5).R|kotlin/Int.unaryMinus|().R|kotlin/ranges/until|(Int(5).R|kotlin/Int.unaryMinus|()).R|kotlin/ranges/IntRange.contains|(R|<local>/v|) -> {
|
||||
Int(-5).R|kotlin/ranges/until|(Int(-5)).R|kotlin/ranges/IntRange.contains|(R|<local>/v|) -> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ FILE: operatorsOverLiterals.kt
|
||||
R|/takeByte|(Byte(1).R|kotlin/Byte.plus|(Byte(1)))
|
||||
<Inapplicable(INAPPLICABLE): /takeByte>#(Int(1).R|kotlin/Int.plus|(Int(127)))
|
||||
R|/takeByte|(Byte(1).R|kotlin/Byte.minus|(Byte(1)))
|
||||
<Inapplicable(INAPPLICABLE): /takeByte>#(Int(100).R|kotlin/Int.unaryMinus|().R|kotlin/Int.minus|(Int(100)))
|
||||
<Inapplicable(INAPPLICABLE): /takeByte>#(Int(-100).R|kotlin/Int.minus|(Int(100)))
|
||||
R|/takeByte|(Byte(10).R|kotlin/Byte.times|(Byte(10)))
|
||||
<Inapplicable(INAPPLICABLE): /takeByte>#(Int(100).R|kotlin/Int.times|(Int(100)))
|
||||
<Unresolved name: taleByte>#(Int(10).R|kotlin/Int.div|(Int(10)))
|
||||
@@ -46,8 +46,8 @@ FILE: operatorsOverLiterals.kt
|
||||
<Inapplicable(INAPPLICABLE): /takeByte>#(Int(512).R|kotlin/Int.xor|(Int(511)))
|
||||
}
|
||||
public final fun test_5(): R|kotlin/Unit| {
|
||||
R|/takeByte|(Byte(1).R|kotlin/Byte.unaryMinus|())
|
||||
R|/takeByte|(Byte(1).R|kotlin/Byte.unaryPlus|())
|
||||
R|/takeByte|(Byte(-1))
|
||||
R|/takeByte|(Byte(1))
|
||||
R|/takeByte|(Byte(1).R|<local>/inv|())
|
||||
}
|
||||
public final fun test_6(): R|kotlin/Unit| {
|
||||
|
||||
@@ -6,8 +6,8 @@ FILE: jvm.kt
|
||||
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
lval res1: R|kotlin/Boolean| = this@R|/A|.R|/Some.foo|(Int(1))
|
||||
lval res2: R|kotlin/Boolean| = this@R|/A|.R|/Some.foo|(Int(1).R|kotlin/Int.unaryMinus|())
|
||||
lval res3: R|ft<kotlin/Array<ft<kotlin/String, kotlin/String?>!>, kotlin/Array<out ft<kotlin/String, kotlin/String?>!>?>!| = this@R|/A|.R|/Some.bar|(R|kotlin/intArrayOf|(vararg(Int(0), Int(2), Int(2).R|kotlin/Int.unaryMinus|())))
|
||||
lval res2: R|kotlin/Boolean| = this@R|/A|.R|/Some.foo|(Int(-1))
|
||||
lval res3: R|ft<kotlin/Array<ft<kotlin/String, kotlin/String?>!>, kotlin/Array<out ft<kotlin/String, kotlin/String?>!>?>!| = this@R|/A|.R|/Some.bar|(R|kotlin/intArrayOf|(vararg(Int(0), Int(2), Int(-2))))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -368,13 +368,25 @@ class ExpressionsConverter(
|
||||
prefix = unaryExpression.tokenType == PREFIX_EXPRESSION
|
||||
) { getAsFirExpression(this) }
|
||||
}
|
||||
val receiver = getAsFirExpression<FirExpression>(argument, "No operand")
|
||||
if (operationToken == PLUS || operationToken == MINUS) {
|
||||
if (receiver is FirConstExpression<*> && receiver.kind == FirConstKind.IntegerLiteral) {
|
||||
val value = receiver.value as Long
|
||||
val convertedValue = when (operationToken) {
|
||||
MINUS -> -value
|
||||
PLUS -> value
|
||||
else -> error("Should not be here")
|
||||
}
|
||||
return buildConstExpression(unaryExpression.toFirSourceElement(), FirConstKind.IntegerLiteral, convertedValue)
|
||||
}
|
||||
}
|
||||
buildFunctionCall {
|
||||
source = unaryExpression.toFirSourceElement()
|
||||
calleeReference = buildSimpleNamedReference {
|
||||
source = this@buildFunctionCall.source
|
||||
name = conventionCallName
|
||||
}
|
||||
explicitReceiver = getAsFirExpression(argument, "No operand")
|
||||
explicitReceiver = receiver
|
||||
}
|
||||
}
|
||||
else -> throw IllegalStateException("Unexpected expression: ${unaryExpression.asText}")
|
||||
|
||||
@@ -1746,13 +1746,26 @@ class RawFirBuilder(
|
||||
prefix = expression is KtPrefixExpression,
|
||||
) { (this as KtExpression).toFirExpression("Incorrect expression inside inc/dec") }
|
||||
}
|
||||
|
||||
val receiver = argument.toFirExpression("No operand")
|
||||
if (operationToken == PLUS || operationToken == MINUS) {
|
||||
if (receiver is FirConstExpression<*> && receiver.kind == FirConstKind.IntegerLiteral) {
|
||||
val value = receiver.value as Long
|
||||
val convertedValue = when (operationToken) {
|
||||
MINUS -> -value
|
||||
PLUS -> value
|
||||
else -> error("Should not be here")
|
||||
}
|
||||
return buildConstExpression(expression.toFirPsiSourceElement(), FirConstKind.IntegerLiteral, convertedValue)
|
||||
}
|
||||
}
|
||||
buildFunctionCall {
|
||||
source = expression.toFirSourceElement()
|
||||
calleeReference = buildSimpleNamedReference {
|
||||
source = expression.operationReference.toFirSourceElement()
|
||||
name = conventionCallName
|
||||
}
|
||||
explicitReceiver = argument.toFirExpression("No operand")
|
||||
explicitReceiver = receiver
|
||||
}
|
||||
}
|
||||
else -> throw IllegalStateException("Unexpected expression: ${expression.text}")
|
||||
|
||||
@@ -16,14 +16,14 @@ fun test() {
|
||||
<!INAPPLICABLE_CANDIDATE!>fooInt<!>(p3)
|
||||
fooInt(p4)
|
||||
<!INAPPLICABLE_CANDIDATE!>fooInt<!>(p5)
|
||||
fooInt(p6)
|
||||
<!INAPPLICABLE_CANDIDATE!>fooInt<!>(p6)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>fooLong<!>(p1)
|
||||
fooLong(p2)
|
||||
<!INAPPLICABLE_CANDIDATE!>fooLong<!>(p3)
|
||||
<!INAPPLICABLE_CANDIDATE!>fooLong<!>(p4)
|
||||
<!INAPPLICABLE_CANDIDATE!>fooLong<!>(p5)
|
||||
<!INAPPLICABLE_CANDIDATE!>fooLong<!>(p6)
|
||||
fooLong(p6)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>fooShort<!>(p1)
|
||||
<!INAPPLICABLE_CANDIDATE!>fooShort<!>(p2)
|
||||
@@ -38,4 +38,4 @@ fun test() {
|
||||
<!INAPPLICABLE_CANDIDATE!>fooByte<!>(p4)
|
||||
<!INAPPLICABLE_CANDIDATE!>fooByte<!>(p5)
|
||||
<!INAPPLICABLE_CANDIDATE!>fooByte<!>(p6)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,7 @@ FILE fqName:<root> fileName:/literals.kt
|
||||
PROPERTY name:test2 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Int visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CONST Int type=kotlin.Int value=1
|
||||
CONST Int type=kotlin.Int value=-1
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
|
||||
@@ -79,7 +79,7 @@ fun case_4() {
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><Int>(-2147483649)
|
||||
-2147483649 checkType { <!NONE_APPLICABLE!>check<!><Byte>() }
|
||||
-2147483649 checkType { <!NONE_APPLICABLE!>check<!><Short>() }
|
||||
-2147483649 checkType { check<Int>() }
|
||||
-2147483649 checkType { <!NONE_APPLICABLE!>check<!><Int>() }
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 5
|
||||
@@ -96,7 +96,7 @@ fun case_5() {
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><Int>(-9223372036854775807)
|
||||
-9223372036854775807 checkType { <!NONE_APPLICABLE!>check<!><Byte>() }
|
||||
-9223372036854775807 checkType { <!NONE_APPLICABLE!>check<!><Short>() }
|
||||
-9223372036854775807 checkType { check<Int>() }
|
||||
-9223372036854775807 checkType { <!NONE_APPLICABLE!>check<!><Int>() }
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 6
|
||||
|
||||
@@ -68,7 +68,7 @@ fun case_4() {
|
||||
checkSubtype<Int>(-2147483648)
|
||||
checkSubtype<Long>(-2147483648)
|
||||
|
||||
-2147483649 checkType { <!NONE_APPLICABLE!>check<!><Long>() }
|
||||
-2147483649 checkType { check<Long>() }
|
||||
checkSubtype<Long>(-2147483649)
|
||||
}
|
||||
|
||||
@@ -77,6 +77,6 @@ fun case_5() {
|
||||
9223372036854775807 checkType { check<Long>() }
|
||||
checkSubtype<Long>(9223372036854775807)
|
||||
|
||||
-9223372036854775807 checkType { <!NONE_APPLICABLE!>check<!><Long>() }
|
||||
-9223372036854775807 checkType { check<Long>() }
|
||||
checkSubtype<Long>(-9223372036854775807)
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ fun case_4() {
|
||||
checkSubtype<Int>(-0x80000000)
|
||||
checkSubtype<Long>(-0x80000000)
|
||||
|
||||
-0x80000001 checkType { <!NONE_APPLICABLE!>check<!><Long>() }
|
||||
-0x80000001 checkType { check<Long>() }
|
||||
checkSubtype<Long>(-0x80000001)
|
||||
}
|
||||
|
||||
@@ -77,6 +77,6 @@ fun case_5() {
|
||||
0X7FFFFFFFFFFFFFFF checkType { check<Long>() }
|
||||
checkSubtype<Long>(0X7FFFFFFFFFFFFFFF)
|
||||
|
||||
-0X7FFFFFFFFFFFFFFF checkType { <!NONE_APPLICABLE!>check<!><Long>() }
|
||||
-0X7FFFFFFFFFFFFFFF checkType { check<Long>() }
|
||||
checkSubtype<Long>(-0X7FFFFFFFFFFFFFFF)
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ fun case_4() {
|
||||
checkSubtype<Int>(-0B10000000000000000000000000000000)
|
||||
checkSubtype<Long>(-0B10000000000000000000000000000000)
|
||||
|
||||
-0b10000000000000000000000000000001 checkType { <!NONE_APPLICABLE!>check<!><Long>() }
|
||||
-0b10000000000000000000000000000001 checkType { check<Long>() }
|
||||
checkSubtype<Long>(-0b10000000000000000000000000000001)
|
||||
}
|
||||
|
||||
@@ -77,6 +77,6 @@ fun case_5() {
|
||||
0b111111111111111111111111111111111111111111111111111111111111111 checkType { check<Long>() }
|
||||
checkSubtype<Long>(0b111111111111111111111111111111111111111111111111111111111111111)
|
||||
|
||||
-0B111111111111111111111111111111111111111111111111111111111111111 checkType { <!NONE_APPLICABLE!>check<!><Long>() }
|
||||
-0B111111111111111111111111111111111111111111111111111111111111111 checkType { check<Long>() }
|
||||
checkSubtype<Long>(-0B111111111111111111111111111111111111111111111111111111111111111)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user