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