Psi2Ir: Fold constants when generating IR
This is necessary to avoid stack overflow errors on large constant expressions.
This commit is contained in:
committed by
Dmitry Petrov
parent
e87d816994
commit
8c9ad81c76
+26
-11
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
||||
@@ -110,7 +111,10 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
} else
|
||||
throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor")
|
||||
irProperty.getter =
|
||||
FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(getter, ktDeclarationContainer)
|
||||
FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(
|
||||
getter,
|
||||
ktDeclarationContainer
|
||||
)
|
||||
|
||||
if (propertyDescriptor.isVar) {
|
||||
val setter = propertyDescriptor.setter
|
||||
@@ -130,7 +134,10 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
} else
|
||||
throw AssertionError("Property declared in primary constructor has no setter: $propertyDescriptor")
|
||||
irProperty.setter =
|
||||
FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(setter, ktDeclarationContainer)
|
||||
FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(
|
||||
setter,
|
||||
ktDeclarationContainer
|
||||
)
|
||||
}
|
||||
|
||||
irProperty.linkCorrespondingPropertySymbol()
|
||||
@@ -173,17 +180,25 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
irProperty.backingField =
|
||||
if (propertyDescriptor.actuallyHasBackingField(context.bindingContext))
|
||||
generatePropertyBackingField(ktProperty, propertyDescriptor) { irField ->
|
||||
ktProperty.initializer?.let { ktInitializer ->
|
||||
ktProperty.initializer?.let evaluateInitializer@{ ktInitializer ->
|
||||
val compileTimeConst = propertyDescriptor.compileTimeInitializer
|
||||
if (propertyDescriptor.isConst && compileTimeConst != null)
|
||||
context.irFactory.createExpressionBody(
|
||||
context.constantValueGenerator.generateConstantValueAsExpression(
|
||||
ktInitializer.startOffsetSkippingComments, ktInitializer.endOffset,
|
||||
compileTimeConst
|
||||
if (compileTimeConst != null) {
|
||||
val constantInfo = context.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, ktInitializer)
|
||||
if (propertyDescriptor.isConst ||
|
||||
(constantInfo?.usesNonConstValAsConstant == false &&
|
||||
(!constantInfo.usesVariableAsConstant ||
|
||||
context.languageVersionSettings.supportsFeature(LanguageFeature.InlineConstVals)))
|
||||
) {
|
||||
return@evaluateInitializer context.irFactory.createExpressionBody(
|
||||
context.constantValueGenerator.generateConstantValueAsExpression(
|
||||
ktInitializer.startOffsetSkippingComments, ktInitializer.endOffset,
|
||||
compileTimeConst
|
||||
)
|
||||
)
|
||||
)
|
||||
else
|
||||
declarationGenerator.generateInitializerBody(irField.symbol, ktInitializer)
|
||||
}
|
||||
}
|
||||
|
||||
declarationGenerator.generateInitializerBody(irField.symbol, ktInitializer)
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ object Definitions {
|
||||
get
|
||||
|
||||
val ktValue: String
|
||||
field = super.#CONSTANT
|
||||
field = "constant"
|
||||
get
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ FILE fqName:interop fileName:/Definitions.kt
|
||||
PROPERTY name:ktValue visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:ktValue type:kotlin.String visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:CONSTANT type:kotlin.String visibility:public [final,static]' type=kotlin.String origin=GET_PROPERTY
|
||||
CONST String type=kotlin.String value="constant"
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-ktValue> visibility:public modality:FINAL <> ($this:interop.Definitions) returnType:kotlin.String
|
||||
correspondingProperty: PROPERTY name:ktValue visibility:public modality:FINAL [val]
|
||||
$this: VALUE_PARAMETER name:<this> type:interop.Definitions
|
||||
|
||||
+3
-3
@@ -11,15 +11,15 @@ val test3: Byte
|
||||
get
|
||||
|
||||
val test4: Long
|
||||
field = 42.unaryMinus()
|
||||
field = -42L
|
||||
get
|
||||
|
||||
val test5: Short
|
||||
field = 42.unaryMinus()
|
||||
field = -42S
|
||||
get
|
||||
|
||||
val test6: Byte
|
||||
field = 42.unaryMinus()
|
||||
field = -42B
|
||||
get
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -29,8 +29,7 @@ FILE fqName:<root> fileName:/primitivesImplicitConversions.kt
|
||||
PROPERTY name:test4 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test4 type:kotlin.Long 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=42
|
||||
CONST Long type=kotlin.Long value=-42
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test4> visibility:public modality:FINAL <> () returnType:kotlin.Long
|
||||
correspondingProperty: PROPERTY name:test4 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
@@ -39,8 +38,7 @@ FILE fqName:<root> fileName:/primitivesImplicitConversions.kt
|
||||
PROPERTY name:test5 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test5 type:kotlin.Short 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=42
|
||||
CONST Short type=kotlin.Short value=-42
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test5> visibility:public modality:FINAL <> () returnType:kotlin.Short
|
||||
correspondingProperty: PROPERTY name:test5 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
@@ -49,8 +47,7 @@ FILE fqName:<root> fileName:/primitivesImplicitConversions.kt
|
||||
PROPERTY name:test6 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test6 type:kotlin.Byte 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=42
|
||||
CONST Byte type=kotlin.Byte value=-42
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test6> visibility:public modality:FINAL <> () returnType:kotlin.Byte
|
||||
correspondingProperty: PROPERTY name:test6 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
val test: Int
|
||||
field = Companion.<get-MIN_VALUE>()
|
||||
get
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
FILE fqName:<root> fileName:/constFromBuiltins.kt
|
||||
PROPERTY name:test visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test type:kotlin.Int visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun <get-MIN_VALUE> (): kotlin.Int declared in kotlin.Int.Companion' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Companion modality:FINAL visibility:public [companion] superTypes:[kotlin.Any]' type=kotlin.Int.Companion
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test type:kotlin.Int visibility:private [final,static]' type=kotlin.Int origin=null
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// DUMP_EXTERNAL_CLASS: kotlin.Int
|
||||
|
||||
val test = Int.MIN_VALUE
|
||||
@@ -1,4 +1,4 @@
|
||||
val test: Int
|
||||
field = Companion.<get-MIN_VALUE>()
|
||||
field = -2147483648
|
||||
get
|
||||
|
||||
|
||||
+1
-2
@@ -2,8 +2,7 @@ FILE fqName:<root> fileName:/constFromBuiltins.kt
|
||||
PROPERTY name:test visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test type:kotlin.Int visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun <get-MIN_VALUE> (): kotlin.Int declared in kotlin.Int.Companion' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Companion modality:FINAL visibility:public [companion] superTypes:[kotlin.Any]' type=kotlin.Int.Companion
|
||||
CONST Int type=kotlin.Int value=-2147483648
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
val test: Int
|
||||
field = 2.plus(other = 2)
|
||||
get
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
FILE fqName:<root> fileName:/simple.kt
|
||||
PROPERTY name:test visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test type:kotlin.Int visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUS
|
||||
$this: CONST Int type=kotlin.Int value=2
|
||||
other: CONST Int type=kotlin.Int value=2
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test type:kotlin.Int visibility:private [final,static]' type=kotlin.Int origin=null
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DUMP_DEPENDENCIES
|
||||
|
||||
val test = 2 + 2
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
val test: Int
|
||||
field = 2.plus(other = 2)
|
||||
field = 4
|
||||
get
|
||||
|
||||
|
||||
+1
-3
@@ -2,9 +2,7 @@ FILE fqName:<root> fileName:/simple.kt
|
||||
PROPERTY name:test visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test type:kotlin.Int visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUS
|
||||
$this: CONST Int type=kotlin.Int value=2
|
||||
other: CONST Int type=kotlin.Int value=2
|
||||
CONST Int type=kotlin.Int value=4
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
|
||||
Reference in New Issue
Block a user