Enum classes lowering.
This commit is contained in:
@@ -1246,7 +1246,8 @@ public class KotlinTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||||
if (containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY) {
|
if (descriptor.getKind() != CallableMemberDescriptor.Kind.SYNTHESIZED &&
|
||||||
|
(containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY)) {
|
||||||
writeParameter(
|
writeParameter(
|
||||||
sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getStringType(), descriptor);
|
sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getStringType(), descriptor);
|
||||||
writeParameter(
|
writeParameter(
|
||||||
|
|||||||
@@ -23,8 +23,11 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
|||||||
interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
|
interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||||
object CLASS_STATIC_INITIALIZER : IrDeclarationOriginImpl("CLASS_STATIC_INITIALIZER")
|
object CLASS_STATIC_INITIALIZER : IrDeclarationOriginImpl("CLASS_STATIC_INITIALIZER")
|
||||||
object DEFAULT_IMPLS : IrDeclarationOriginImpl("DEFAULT_IMPL")
|
object DEFAULT_IMPLS : IrDeclarationOriginImpl("DEFAULT_IMPL")
|
||||||
|
object FIELD_FOR_ENUM_ENTRY : IrDeclarationOriginImpl("FIELD_FOR_ENUM_ENTRY")
|
||||||
|
object FIELD_FOR_ENUM_VALUES : IrDeclarationOriginImpl("FIELD_FOR_ENUM_VALUES")
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JvmLoweredStatementOrigin : IrStatementOrigin {
|
interface JvmLoweredStatementOrigin : IrStatementOrigin {
|
||||||
object DEFAULT_IMPLS_DELEGATION : IrStatementOrigin.IrStatementOriginImpl("DEFAULT_IMPL_DELEGATION")
|
object DEFAULT_IMPLS_DELEGATION : IrStatementOrigin.IrStatementOriginImpl("DEFAULT_IMPL_DELEGATION")
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -16,12 +16,17 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm
|
package org.jetbrains.kotlin.backend.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.JvmFileClassProvider
|
import org.jetbrains.kotlin.backend.jvm.descriptors.SpecialDescriptorsFactory
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||||
|
|
||||||
class JvmBackendContext(
|
class JvmBackendContext(
|
||||||
val state: GenerationState,
|
val state: GenerationState,
|
||||||
val jvmFileClassProvider: JvmFileClassProvider,
|
val psiSourceManager: PsiSourceManager,
|
||||||
val irBuiltIns: IrBuiltIns
|
val irBuiltIns: IrBuiltIns
|
||||||
)
|
) {
|
||||||
|
val builtIns = state.module.builtIns
|
||||||
|
val specialDescriptorsFactory = SpecialDescriptorsFactory(psiSourceManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,14 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm
|
package org.jetbrains.kotlin.backend.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.JvmFileClassProvider
|
|
||||||
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
|
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
|
||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
|
||||||
|
|
||||||
object JvmBackendFacade {
|
object JvmBackendFacade {
|
||||||
fun compileCorrectFiles(state: GenerationState, errorHandler: CompilationErrorHandler) {
|
fun compileCorrectFiles(state: GenerationState, errorHandler: CompilationErrorHandler) {
|
||||||
@@ -38,12 +35,11 @@ object JvmBackendFacade {
|
|||||||
|
|
||||||
val psi2ir = Psi2IrTranslator()
|
val psi2ir = Psi2IrTranslator()
|
||||||
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext)
|
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext)
|
||||||
val jvmBackendContext = createJvmBackendContext(psi2ir, state, psi2irContext.irBuiltIns)
|
|
||||||
|
|
||||||
val jvmBackend = JvmBackend(jvmBackendContext)
|
|
||||||
|
|
||||||
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files)
|
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files)
|
||||||
|
|
||||||
|
val jvmBackendContext = JvmBackendContext(state, psi2irContext.sourceManager, psi2irContext.irBuiltIns)
|
||||||
|
val jvmBackend = JvmBackend(jvmBackendContext)
|
||||||
|
|
||||||
for (irFile in irModuleFragment.files) {
|
for (irFile in irModuleFragment.files) {
|
||||||
try {
|
try {
|
||||||
jvmBackend.generateFile(irFile)
|
jvmBackend.generateFile(irFile)
|
||||||
@@ -55,12 +51,4 @@ object JvmBackendFacade {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createJvmBackendContext(psi2ir: Psi2IrTranslator, state: GenerationState, irBuiltIns: IrBuiltIns): JvmBackendContext {
|
|
||||||
val jvmFileClassProvider = JvmFileClassProvider()
|
|
||||||
psi2ir.add(jvmFileClassProvider)
|
|
||||||
|
|
||||||
val jvmBackendContext = JvmBackendContext(state, jvmFileClassProvider, irBuiltIns)
|
|
||||||
|
|
||||||
return jvmBackendContext
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,38 +17,62 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm
|
package org.jetbrains.kotlin.backend.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.*
|
import org.jetbrains.kotlin.backend.jvm.lower.*
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
|
|
||||||
class JvmLower(val context: JvmBackendContext) {
|
class JvmLower(val context: JvmBackendContext) {
|
||||||
fun lower(irFile: IrFile) {
|
fun lower(irFile: IrFile) {
|
||||||
FileClassLowering(context.jvmFileClassProvider).lower(irFile)
|
// TODO run lowering passes as callbacks in bottom-up visitor
|
||||||
|
FileClassLowering(context).lower(irFile)
|
||||||
PropertiesLowering().lower(irFile)
|
PropertiesLowering().lower(irFile)
|
||||||
InitializersLowering().runOnNormalizedFile(irFile)
|
InterfaceLowering(context.state).runOnFile(irFile)
|
||||||
InterfaceLowering(context.state).runOnNormalizedFile(irFile)
|
InterfaceDelegationLowering(context.state).runOnFile(irFile)
|
||||||
InterfaceDelegationLowering(context.state).runOnNormalizedFile(irFile)
|
EnumClassLowering(context).runOnFile(irFile)
|
||||||
|
InitializersLowering().runOnFile(irFile)
|
||||||
|
SingletonReferencesLowering(context).runOnFile(irFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FileLoweringPass {
|
interface FileLoweringPass {
|
||||||
fun lower(irFile: IrFile
|
fun lower(irFile: IrFile)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ClassLoweringPass {
|
interface ClassLoweringPass {
|
||||||
fun lower(irClass: IrClass)
|
fun lower(irClass: IrClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ClassLoweringPass.runOnNormalizedFile(irFile: IrFile) {
|
interface BodyLoweringPass {
|
||||||
fun runPostfix(irDeclarationContainer: IrDeclarationContainer) {
|
fun lower(irBody: IrBody)
|
||||||
irDeclarationContainer.declarations.forEach {
|
}
|
||||||
if (it is IrClass) {
|
|
||||||
runPostfix(it)
|
fun ClassLoweringPass.runOnFile(irFile: IrFile) {
|
||||||
lower(it)
|
irFile.acceptVoid(object : IrElementVisitorVoid {
|
||||||
}
|
override fun visitElement(element: IrElement) {
|
||||||
}
|
element.acceptChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
runPostfix(irFile)
|
override fun visitClass(declaration: IrClass) {
|
||||||
|
declaration.acceptChildrenVoid(this)
|
||||||
|
lower(declaration)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun BodyLoweringPass.runOnFile(irFile: IrFile) {
|
||||||
|
irFile.acceptVoid(object : IrElementVisitorVoid {
|
||||||
|
override fun visitElement(element: IrElement) {
|
||||||
|
element.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitBody(body: IrBody) {
|
||||||
|
body.acceptChildrenVoid(this)
|
||||||
|
lower(body)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
+2
-1
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_THROWABLE_TYPE
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_THROWABLE_TYPE
|
||||||
@@ -195,7 +196,7 @@ class ExpressionCodegen(
|
|||||||
|
|
||||||
|
|
||||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: BlockInfo): StackValue {
|
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: BlockInfo): StackValue {
|
||||||
return none()
|
throw AssertionError("IrInstanceInitializerCall should've been lowered before code generation: ${expression.render()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: BlockInfo): StackValue {
|
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: BlockInfo): StackValue {
|
||||||
|
|||||||
+73
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.jvm.descriptors
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
|
interface JvmSpecialDescriptor {
|
||||||
|
val extraFlags: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
class JvmPropertyDescriptorImpl(
|
||||||
|
containingDeclaration: DeclarationDescriptor,
|
||||||
|
original: PropertyDescriptor?,
|
||||||
|
annotations: Annotations,
|
||||||
|
modality: Modality,
|
||||||
|
visibility: Visibility,
|
||||||
|
override val extraFlags: Int,
|
||||||
|
isVar: Boolean,
|
||||||
|
name: Name,
|
||||||
|
kind: CallableMemberDescriptor.Kind,
|
||||||
|
source: SourceElement,
|
||||||
|
isLateInit: Boolean,
|
||||||
|
isConst: Boolean
|
||||||
|
) : JvmSpecialDescriptor, PropertyDescriptorImpl(
|
||||||
|
containingDeclaration, original, annotations, modality, visibility, isVar,
|
||||||
|
name, kind, source, isLateInit, isConst
|
||||||
|
) {
|
||||||
|
override fun createSubstitutedCopy(newOwner: DeclarationDescriptor, newModality: Modality, newVisibility: Visibility, original: PropertyDescriptor?, kind: CallableMemberDescriptor.Kind): PropertyDescriptorImpl =
|
||||||
|
JvmPropertyDescriptorImpl(
|
||||||
|
newOwner, original, annotations, newModality, newVisibility, extraFlags, isVar, name, kind,
|
||||||
|
SourceElement.NO_SOURCE, isLateInit, isConst
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun createVal(
|
||||||
|
name: Name,
|
||||||
|
type: KotlinType,
|
||||||
|
containingDeclaration: DeclarationDescriptor,
|
||||||
|
annotations: Annotations,
|
||||||
|
modality: Modality,
|
||||||
|
visibility: Visibility,
|
||||||
|
extraFlags: Int,
|
||||||
|
source: SourceElement
|
||||||
|
): PropertyDescriptorImpl =
|
||||||
|
JvmPropertyDescriptorImpl(
|
||||||
|
containingDeclaration, null, annotations, modality, visibility, extraFlags, false, name,
|
||||||
|
CallableMemberDescriptor.Kind.SYNTHESIZED, source, false, false
|
||||||
|
).setTypeNoReceivers(type)
|
||||||
|
|
||||||
|
private fun PropertyDescriptorImpl.setTypeNoReceivers(type: KotlinType): PropertyDescriptorImpl {
|
||||||
|
setType(type, emptyList(), null as ReceiverParameterDescriptor?, null as ReceiverParameterDescriptor?)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.jvm.descriptors
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmPropertyDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
|
import org.jetbrains.kotlin.ir.SourceManager
|
||||||
|
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||||
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class SpecialDescriptorsFactory(val psiSourceManager: PsiSourceManager) {
|
||||||
|
private val enumEntryFieldDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>()
|
||||||
|
|
||||||
|
fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor =
|
||||||
|
enumEntryFieldDescriptors.getOrPut(enumEntryDescriptor) {
|
||||||
|
createEnumEntryFieldDescriptor(enumEntryDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createFileClassDescriptor(fileEntry: SourceManager.FileEntry, packageFragment: PackageFragmentDescriptor): FileClassDescriptor {
|
||||||
|
val ktFile = psiSourceManager.getKtFile(fileEntry as PsiSourceManager.PsiFileEntry)
|
||||||
|
?: throw AssertionError("Unexpected file entry: $fileEntry")
|
||||||
|
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(ktFile)
|
||||||
|
val sourceElement = KotlinSourceElement(ktFile)
|
||||||
|
return FileClassDescriptorImpl(fileClassInfo.fileClassFqName.shortName(), packageFragment, sourceElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createEnumEntryFieldDescriptor(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor {
|
||||||
|
assert(enumEntryDescriptor.kind == ClassKind.ENUM_ENTRY) { "Should be enum entry: $enumEntryDescriptor" }
|
||||||
|
|
||||||
|
val enumClassDescriptor = enumEntryDescriptor.containingDeclaration as ClassDescriptor
|
||||||
|
assert(enumClassDescriptor.kind == ClassKind.ENUM_CLASS) { "Should be enum class: $enumClassDescriptor"}
|
||||||
|
|
||||||
|
return JvmPropertyDescriptorImpl.createVal(
|
||||||
|
enumEntryDescriptor.name,
|
||||||
|
enumClassDescriptor.defaultType,
|
||||||
|
enumClassDescriptor,
|
||||||
|
enumEntryDescriptor.annotations,
|
||||||
|
Modality.FINAL,
|
||||||
|
Visibilities.PUBLIC,
|
||||||
|
Opcodes.ACC_ENUM,
|
||||||
|
enumEntryDescriptor.source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
|||||||
|
|
||||||
class ArrayOf : IntrinsicMethod() {
|
class ArrayOf : IntrinsicMethod() {
|
||||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
return IrIntrinsicFunction.create(expression, signature, context, signature.returnType) {
|
||||||
//do nothing all generated as vararg
|
//do nothing all generated as vararg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,12 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
|||||||
|
|
||||||
class Clone : IntrinsicMethod() {
|
class Clone : IntrinsicMethod() {
|
||||||
|
|
||||||
/*TODO return type*/
|
|
||||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||||
|
val resultType = context.state.typeMapper.mapType(expression.type)
|
||||||
val opcode = if (expression is IrCall && expression.superQualifier != null) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
|
val opcode = if (expression is IrCall && expression.superQualifier != null) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
|
||||||
it.visitMethodInsn(opcode, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
|
it.visitMethodInsn(opcode, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
|
||||||
|
it.checkcast(resultType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||||
|
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||||
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
|
class IrEnumValueOf : IntrinsicMethod() {
|
||||||
|
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||||
|
val enumType = context.state.typeMapper.mapType(expression.descriptor.returnType!!)
|
||||||
|
val newSignature = context.state.typeMapper.mapSignatureSkipGeneric(expression.descriptor as FunctionDescriptor, OwnerKind.IMPLEMENTATION)
|
||||||
|
val stringType = AsmTypes.JAVA_STRING_TYPE;
|
||||||
|
|
||||||
|
return object : IrIntrinsicFunction(expression, newSignature, context, listOf(stringType)) {
|
||||||
|
override fun invoke(v: InstructionAdapter, codegen: ExpressionCodegen, data: BlockInfo): StackValue {
|
||||||
|
v.tconst(enumType)
|
||||||
|
codegen.gen(expression.getValueArgument(0)!!, stringType, data)
|
||||||
|
v.invokestatic("java/lang/Enum", "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;", false);
|
||||||
|
v.checkcast(enumType)
|
||||||
|
return StackValue.onStack(enumType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -36,12 +36,13 @@ class IrIntrinsicMethods(irBuiltIns: IrBuiltIns) {
|
|||||||
irMapping.put(irBuiltIns.lteq0, compare)
|
irMapping.put(irBuiltIns.lteq0, compare)
|
||||||
irMapping.put(irBuiltIns.gt0, compare)
|
irMapping.put(irBuiltIns.gt0, compare)
|
||||||
irMapping.put(irBuiltIns.gteq0, compare)
|
irMapping.put(irBuiltIns.gteq0, compare)
|
||||||
|
irMapping.put(irBuiltIns.enumValueOf, IrEnumValueOf())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getIntrinsic(descriptor: CallableMemberDescriptor): IntrinsicMethod? {
|
fun getIntrinsic(descriptor: CallableMemberDescriptor): IntrinsicMethod? {
|
||||||
return intrinsics.getIntrinsic(descriptor) ?:
|
return intrinsics.getIntrinsic(descriptor) ?:
|
||||||
(if (descriptor is PropertyAccessorDescriptor) intrinsics.getIntrinsic(descriptor.correspondingProperty) else null) ?:
|
(if (descriptor is PropertyAccessorDescriptor) intrinsics.getIntrinsic(descriptor.correspondingProperty) else null) ?:
|
||||||
irMapping[descriptor]
|
irMapping[descriptor.original]
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+430
@@ -0,0 +1,430 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
|
import gnu.trove.TObjectIntHashMap
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.ClassLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmPropertyDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.dump
|
||||||
|
import org.jetbrains.kotlin.ir.util.transform
|
||||||
|
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.psi2ir.findSingleFunction
|
||||||
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||||
|
override fun lower(irClass: IrClass) {
|
||||||
|
val classDescriptor = irClass.descriptor
|
||||||
|
if (classDescriptor.kind != ClassKind.ENUM_CLASS) return
|
||||||
|
|
||||||
|
EnumClassTransformer(irClass).run()
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface EnumConstructorCallTransformer {
|
||||||
|
fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
private val unsubstitutedArrayOfFun = context.builtIns.findSingleFunction(Name.identifier("arrayOf"))
|
||||||
|
|
||||||
|
private fun createArrayOfExpression(arrayElementType: KotlinType, arrayElements: List<IrExpression>): IrExpression {
|
||||||
|
val typeParameter0 = unsubstitutedArrayOfFun.typeParameters[0]
|
||||||
|
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameter0.typeConstructor to TypeProjectionImpl(arrayElementType)))
|
||||||
|
val substitutedArrayOfFun = unsubstitutedArrayOfFun.substitute(typeSubstitutor)
|
||||||
|
|
||||||
|
val typeArguments = mapOf(typeParameter0 to arrayElementType)
|
||||||
|
|
||||||
|
val valueParameter0 = substitutedArrayOfFun.valueParameters[0]
|
||||||
|
val arg0VarargType = valueParameter0.type
|
||||||
|
val arg0VarargElementType = valueParameter0.varargElementType!!
|
||||||
|
val arg0 = IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arg0VarargType, arg0VarargElementType, arrayElements)
|
||||||
|
|
||||||
|
return IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, substitutedArrayOfFun, typeArguments).apply {
|
||||||
|
putValueArgument(0, arg0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class EnumClassTransformer(val irClass: IrClass) {
|
||||||
|
private val enumEntryOrdinals = TObjectIntHashMap<ClassDescriptor>()
|
||||||
|
private val loweredEnumConstructors = HashMap<ClassConstructorDescriptor, ClassConstructorDescriptor>()
|
||||||
|
private val loweredEnumConstructorParameters = HashMap<ValueParameterDescriptor, ValueParameterDescriptor>()
|
||||||
|
private val enumEntriesByField = HashMap<PropertyDescriptor, ClassDescriptor>()
|
||||||
|
private val enumEntryFields = ArrayList<PropertyDescriptor>()
|
||||||
|
|
||||||
|
private lateinit var valuesFieldDescriptor: PropertyDescriptor
|
||||||
|
private lateinit var valuesFunctionDescriptor: FunctionDescriptor
|
||||||
|
private lateinit var valueOfFunctionDescriptor: FunctionDescriptor
|
||||||
|
|
||||||
|
fun run() {
|
||||||
|
assignOrdinalsToEnumEntries()
|
||||||
|
lowerEnumConstructors(irClass)
|
||||||
|
lowerEnumEntries()
|
||||||
|
setupSynthesizedEnumClassMembers()
|
||||||
|
lowerEnumClassBody()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assignOrdinalsToEnumEntries() {
|
||||||
|
var ordinal = 0
|
||||||
|
irClass.declarations.forEach {
|
||||||
|
if (it is IrEnumEntry) {
|
||||||
|
enumEntryOrdinals.put(it.descriptor, ordinal)
|
||||||
|
ordinal++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lowerEnumConstructors(irClass: IrClass) {
|
||||||
|
irClass.declarations.transform { declaration ->
|
||||||
|
if (declaration is IrConstructor)
|
||||||
|
transformEnumConstructor(declaration)
|
||||||
|
else
|
||||||
|
declaration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformEnumConstructor(enumConstructor: IrConstructor): IrConstructor {
|
||||||
|
val constructorDescriptor = enumConstructor.descriptor
|
||||||
|
val loweredConstructorDescriptor = lowerEnumConstructor(constructorDescriptor)
|
||||||
|
val loweredEnumConstructor = IrConstructorImpl(
|
||||||
|
enumConstructor.startOffset, enumConstructor.endOffset, enumConstructor.origin,
|
||||||
|
loweredConstructorDescriptor,
|
||||||
|
enumConstructor.body!! // will be transformed later
|
||||||
|
)
|
||||||
|
return loweredEnumConstructor
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lowerEnumConstructor(constructorDescriptor: ClassConstructorDescriptor): ClassConstructorDescriptor {
|
||||||
|
val loweredConstructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||||
|
constructorDescriptor.containingDeclaration,
|
||||||
|
constructorDescriptor.annotations,
|
||||||
|
constructorDescriptor.isPrimary,
|
||||||
|
constructorDescriptor.source
|
||||||
|
)
|
||||||
|
|
||||||
|
val valueParameters =
|
||||||
|
listOf(
|
||||||
|
loweredConstructorDescriptor.createSpecialParameter(0, "name", context.builtIns.stringType),
|
||||||
|
loweredConstructorDescriptor.createSpecialParameter(1, "ordinal", context.builtIns.intType)
|
||||||
|
) +
|
||||||
|
constructorDescriptor.valueParameters.map {
|
||||||
|
lowerConstructorValueParameter(loweredConstructorDescriptor, it)
|
||||||
|
}
|
||||||
|
loweredConstructorDescriptor.initialize(valueParameters, Visibilities.PROTECTED)
|
||||||
|
|
||||||
|
loweredConstructorDescriptor.returnType = constructorDescriptor.returnType
|
||||||
|
|
||||||
|
loweredEnumConstructors[constructorDescriptor] = loweredConstructorDescriptor
|
||||||
|
|
||||||
|
return loweredConstructorDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ClassConstructorDescriptor.createSpecialParameter(index: Int, name: String, type: KotlinType): ValueParameterDescriptor =
|
||||||
|
ValueParameterDescriptorImpl(
|
||||||
|
this, null,
|
||||||
|
index,
|
||||||
|
Annotations.EMPTY,
|
||||||
|
Name.identifier(name),
|
||||||
|
type,
|
||||||
|
false, false, false, false, null, SourceElement.NO_SOURCE
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun lowerConstructorValueParameter(
|
||||||
|
loweredConstructorDescriptor: ClassConstructorDescriptor,
|
||||||
|
valueParameterDescriptor: ValueParameterDescriptor
|
||||||
|
): ValueParameterDescriptor {
|
||||||
|
val loweredValueParameterDescriptor = valueParameterDescriptor.copy(
|
||||||
|
loweredConstructorDescriptor,
|
||||||
|
valueParameterDescriptor.name,
|
||||||
|
valueParameterDescriptor.index + 2
|
||||||
|
)
|
||||||
|
loweredEnumConstructorParameters[valueParameterDescriptor] = loweredValueParameterDescriptor
|
||||||
|
return loweredValueParameterDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lowerEnumEntries() {
|
||||||
|
irClass.declarations.transformFlat { declaration ->
|
||||||
|
if (declaration is IrEnumEntry) {
|
||||||
|
createFieldForEnumEntry(declaration).singletonList() +
|
||||||
|
lowerEnumEntryClass(declaration.correspondingClass).singletonOrEmptyList()
|
||||||
|
}
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lowerEnumEntryClass(enumEntryClass: IrClass?): IrClass? {
|
||||||
|
if (enumEntryClass == null) return null
|
||||||
|
|
||||||
|
lowerEnumConstructors(enumEntryClass)
|
||||||
|
|
||||||
|
return enumEntryClass
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createFieldForEnumEntry(enumEntry: IrEnumEntry): IrField {
|
||||||
|
val fieldPropertyDescriptor = context.specialDescriptorsFactory.getFieldDescriptorForEnumEntry(enumEntry.descriptor)
|
||||||
|
|
||||||
|
enumEntriesByField[fieldPropertyDescriptor] = enumEntry.descriptor
|
||||||
|
enumEntryFields.add(fieldPropertyDescriptor)
|
||||||
|
|
||||||
|
val enumEntryInitializer = enumEntry.initializerExpression
|
||||||
|
return IrFieldImpl(
|
||||||
|
enumEntry.startOffset, enumEntry.endOffset, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY,
|
||||||
|
fieldPropertyDescriptor,
|
||||||
|
IrExpressionBodyImpl(enumEntryInitializer.startOffset, enumEntryInitializer.endOffset, enumEntryInitializer)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupSynthesizedEnumClassMembers() {
|
||||||
|
val irField = createSyntheticValuesFieldDeclaration()
|
||||||
|
|
||||||
|
irClass.declarations.add(irField)
|
||||||
|
|
||||||
|
valuesFunctionDescriptor = findFunctionDescriptorForMemberWithSyntheticBodyKind(IrSyntheticBodyKind.ENUM_VALUES)
|
||||||
|
valueOfFunctionDescriptor = findFunctionDescriptorForMemberWithSyntheticBodyKind(IrSyntheticBodyKind.ENUM_VALUEOF)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findFunctionDescriptorForMemberWithSyntheticBodyKind(kind: IrSyntheticBodyKind): FunctionDescriptor =
|
||||||
|
irClass.declarations
|
||||||
|
.first {
|
||||||
|
it is IrFunction &&
|
||||||
|
it.body.let { body ->
|
||||||
|
body is IrSyntheticBody && body.kind == kind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.descriptor as FunctionDescriptor
|
||||||
|
|
||||||
|
|
||||||
|
private fun createSyntheticValuesFieldDeclaration(): IrFieldImpl {
|
||||||
|
val valuesArrayType = context.builtIns.getArrayType(Variance.INVARIANT, irClass.descriptor.defaultType)
|
||||||
|
valuesFieldDescriptor = createSyntheticValuesFieldDescriptor(valuesArrayType)
|
||||||
|
|
||||||
|
val irValuesInitializer = createSyntheticValuesFieldInitializerExpression()
|
||||||
|
|
||||||
|
val irField = IrFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_VALUES,
|
||||||
|
valuesFieldDescriptor,
|
||||||
|
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irValuesInitializer))
|
||||||
|
return irField
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createSyntheticValuesFieldInitializerExpression(): IrExpression =
|
||||||
|
createArrayOfExpression(
|
||||||
|
irClass.descriptor.defaultType,
|
||||||
|
enumEntryFields.map { fieldDescriptor ->
|
||||||
|
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fieldDescriptor)
|
||||||
|
})
|
||||||
|
|
||||||
|
private fun createSyntheticValuesFieldDescriptor(valuesArrayType: SimpleType): PropertyDescriptorImpl {
|
||||||
|
return JvmPropertyDescriptorImpl.createVal(
|
||||||
|
Name.identifier("\$VALUES"),
|
||||||
|
valuesArrayType,
|
||||||
|
irClass.descriptor,
|
||||||
|
Annotations.EMPTY,
|
||||||
|
Modality.FINAL, Visibilities.PRIVATE, Opcodes.ACC_SYNTHETIC,
|
||||||
|
irClass.descriptor.source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lowerEnumClassBody() {
|
||||||
|
irClass.transformChildrenVoid(EnumClassBodyTransformer())
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class InEnumClassConstructor(val enumClassConstructor: ClassConstructorDescriptor) :
|
||||||
|
EnumConstructorCallTransformer {
|
||||||
|
override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression {
|
||||||
|
val startOffset = enumConstructorCall.startOffset
|
||||||
|
val endOffset = enumConstructorCall.endOffset
|
||||||
|
val origin = enumConstructorCall.origin
|
||||||
|
|
||||||
|
val result = IrDelegatingConstructorCallImpl(startOffset, endOffset, enumConstructorCall.descriptor)
|
||||||
|
|
||||||
|
assert(result.descriptor.valueParameters.size == 2) {
|
||||||
|
"Enum(String, Int) constructor call expected:\n${result.dump()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
val nameParameter = enumClassConstructor.valueParameters.getOrElse(0) {
|
||||||
|
throw AssertionError("No 'name' parameter in enum constructor: $enumClassConstructor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val ordinalParameter = enumClassConstructor.valueParameters.getOrElse(1) {
|
||||||
|
throw AssertionError("No 'ordinal' parameter in enum constructor: $enumClassConstructor")
|
||||||
|
}
|
||||||
|
|
||||||
|
result.putValueArgument(0, IrGetVariableImpl(startOffset, endOffset, nameParameter, origin))
|
||||||
|
result.putValueArgument(1, IrGetVariableImpl(startOffset, endOffset, ordinalParameter, origin))
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract inner class InEnumEntry(private val enumEntry: ClassDescriptor) : EnumConstructorCallTransformer {
|
||||||
|
override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression {
|
||||||
|
val name = enumEntry.name.asString()
|
||||||
|
val ordinal = enumEntryOrdinals[enumEntry]
|
||||||
|
|
||||||
|
val descriptor = enumConstructorCall.descriptor
|
||||||
|
val startOffset = enumConstructorCall.startOffset
|
||||||
|
val endOffset = enumConstructorCall.endOffset
|
||||||
|
|
||||||
|
val loweredConstructor = loweredEnumConstructors.getOrElse(descriptor) {
|
||||||
|
throw AssertionError("Constructor called in enum entry initializer should've been lowered: $descriptor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = createConstructorCall(startOffset, endOffset, loweredConstructor)
|
||||||
|
|
||||||
|
result.putValueArgument(0, IrConstImpl.string(startOffset, endOffset, context.builtIns.stringType, name))
|
||||||
|
result.putValueArgument(1, IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, ordinal))
|
||||||
|
|
||||||
|
descriptor.valueParameters.forEach { valueParameter ->
|
||||||
|
val i = valueParameter.index
|
||||||
|
result.putValueArgument(i + 2, enumConstructorCall.getValueArgument(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: ClassConstructorDescriptor): IrMemberAccessExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class InEnumEntryClassConstructor(enumEntry: ClassDescriptor) : InEnumEntry(enumEntry) {
|
||||||
|
override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: ClassConstructorDescriptor) =
|
||||||
|
IrDelegatingConstructorCallImpl(startOffset, endOffset, loweredConstructor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class InEnumEntryInitializer(enumEntry: ClassDescriptor) : InEnumEntry(enumEntry) {
|
||||||
|
override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: ClassConstructorDescriptor) =
|
||||||
|
IrCallImpl(startOffset, endOffset, loweredConstructor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class EnumClassBodyTransformer : IrElementTransformerVoid() {
|
||||||
|
private var enumConstructorCallTransformer: EnumConstructorCallTransformer? = null
|
||||||
|
|
||||||
|
override fun visitField(declaration: IrField): IrStatement {
|
||||||
|
val enumEntry = enumEntriesByField[declaration.descriptor] ?:
|
||||||
|
return declaration
|
||||||
|
|
||||||
|
assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}"}
|
||||||
|
|
||||||
|
enumConstructorCallTransformer = InEnumEntryInitializer(enumEntry)
|
||||||
|
|
||||||
|
val result = super.visitField(declaration)
|
||||||
|
|
||||||
|
enumConstructorCallTransformer = null
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitConstructor(declaration: IrConstructor): IrStatement {
|
||||||
|
val constructorDescriptor = declaration.descriptor
|
||||||
|
val containingClass = constructorDescriptor.containingDeclaration
|
||||||
|
|
||||||
|
// TODO local (non-enum) class in enum class constructor?
|
||||||
|
val previous = enumConstructorCallTransformer
|
||||||
|
|
||||||
|
if (containingClass.kind == ClassKind.ENUM_ENTRY) {
|
||||||
|
assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}"}
|
||||||
|
enumConstructorCallTransformer = InEnumEntryClassConstructor(containingClass)
|
||||||
|
}
|
||||||
|
else if (containingClass.kind == ClassKind.ENUM_CLASS) {
|
||||||
|
assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}"}
|
||||||
|
enumConstructorCallTransformer = InEnumClassConstructor(constructorDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = super.visitConstructor(declaration)
|
||||||
|
|
||||||
|
enumConstructorCallTransformer = previous
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression {
|
||||||
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
|
val callTransformer = enumConstructorCallTransformer ?:
|
||||||
|
throw AssertionError("Enum constructor call outside of enum entry initialization or enum class constructor:\n" +
|
||||||
|
irClass.dump())
|
||||||
|
|
||||||
|
return callTransformer.transform(expression)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitGetVariable(expression: IrGetVariable): IrExpression =
|
||||||
|
loweredEnumConstructorParameters[expression.descriptor]?.let { loweredParameter ->
|
||||||
|
IrGetVariableImpl(expression.startOffset, expression.endOffset, loweredParameter, expression.origin)
|
||||||
|
} ?: expression
|
||||||
|
|
||||||
|
override fun visitSyntheticBody(body: IrSyntheticBody): IrBody {
|
||||||
|
return when (body.kind) {
|
||||||
|
IrSyntheticBodyKind.ENUM_VALUES ->
|
||||||
|
createEnumValuesBody(valuesFieldDescriptor)
|
||||||
|
IrSyntheticBodyKind.ENUM_VALUEOF ->
|
||||||
|
createEnumValueOfBody()
|
||||||
|
else ->
|
||||||
|
body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createEnumValueOfBody(): IrBody {
|
||||||
|
val unsubstitutedValueOf = context.irBuiltIns.enumValueOf
|
||||||
|
val typeParameterT = unsubstitutedValueOf.typeParameters[0]
|
||||||
|
val enumClassType = irClass.descriptor.defaultType
|
||||||
|
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameterT.typeConstructor to TypeProjectionImpl(enumClassType)))
|
||||||
|
val substitutedValueOf = unsubstitutedValueOf.substitute(typeSubstitutor)
|
||||||
|
|
||||||
|
val irValueOfCall = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, substitutedValueOf, mapOf(typeParameterT to enumClassType))
|
||||||
|
irValueOfCall.putValueArgument(
|
||||||
|
0, IrGetVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunctionDescriptor.valueParameters[0]))
|
||||||
|
|
||||||
|
return IrBlockBodyImpl(
|
||||||
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
|
listOf(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunctionDescriptor, irValueOfCall))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createEnumValuesBody(valuesFieldDescriptor: PropertyDescriptor): IrBody {
|
||||||
|
val cloneFun = valuesFieldDescriptor.type.memberScope.findSingleFunction(Name.identifier("clone"))
|
||||||
|
|
||||||
|
val irCloneValues = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, cloneFun).apply {
|
||||||
|
dispatchReceiver = IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valuesFieldDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
return IrBlockBodyImpl(
|
||||||
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
|
listOf(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valuesFunctionDescriptor, irCloneValues))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+3
-2
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.FileLoweringPass
|
import org.jetbrains.kotlin.backend.jvm.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
@@ -24,7 +25,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class FileClassLowering(val jvmFileClassProvider: JvmFileClassProvider) : FileLoweringPass {
|
class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
val classes = ArrayList<IrClass>()
|
val classes = ArrayList<IrClass>()
|
||||||
val fileClassMembers = ArrayList<IrDeclaration>()
|
val fileClassMembers = ArrayList<IrDeclaration>()
|
||||||
@@ -38,7 +39,7 @@ class FileClassLowering(val jvmFileClassProvider: JvmFileClassProvider) : FileLo
|
|||||||
|
|
||||||
if (fileClassMembers.isEmpty()) return
|
if (fileClassMembers.isEmpty()) return
|
||||||
|
|
||||||
val fileClassDescriptor = jvmFileClassProvider.createFileClassDescriptor(irFile.fileEntry, irFile.packageFragmentDescriptor)
|
val fileClassDescriptor = context.specialDescriptorsFactory.createFileClassDescriptor(irFile.fileEntry, irFile.packageFragmentDescriptor)
|
||||||
val irFileClass = IrClassImpl(0, irFile.fileEntry.maxOffset, IrDeclarationOrigin.DEFINED, fileClassDescriptor, fileClassMembers)
|
val irFileClass = IrClassImpl(0, irFile.fileEntry.maxOffset, IrDeclarationOrigin.DEFINED, fileClassDescriptor, fileClassMembers)
|
||||||
classes.add(irFileClass)
|
classes.add(irFileClass)
|
||||||
|
|
||||||
|
|||||||
+2
-5
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -79,7 +80,7 @@ class InitializersLowering : ClassLoweringPass {
|
|||||||
null, null
|
null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
if (declaration.descriptor.isStatic()) {
|
if (DescriptorUtils.isStaticDeclaration(declaration.descriptor)) {
|
||||||
staticInitializerStatements.add(irSetField)
|
staticInitializerStatements.add(irSetField)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -91,10 +92,6 @@ class InitializersLowering : ClassLoweringPass {
|
|||||||
instanceInitializerStatements.addAll(declaration.body.statements)
|
instanceInitializerStatements.addAll(declaration.body.statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CallableMemberDescriptor.isStatic() =
|
|
||||||
AsmUtil.isStaticMethod(classMemberOwnerKind, this) // TODO what about properties?
|
|
||||||
|
|
||||||
|
|
||||||
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) {
|
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) {
|
||||||
for (irDeclaration in irClass.declarations) {
|
for (irDeclaration in irClass.declarations) {
|
||||||
if (irDeclaration !is IrConstructor) continue
|
if (irDeclaration !is IrConstructor) continue
|
||||||
|
|||||||
-65
@@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
|
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.SourceManager
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
|
||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
|
||||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
|
||||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
|
||||||
import java.lang.AssertionError
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class JvmFileClassProvider : Psi2IrTranslator.PostprocessingStep {
|
|
||||||
override fun postprocess(context: GeneratorContext, irElement: IrElement) {
|
|
||||||
when (irElement) {
|
|
||||||
is IrModuleFragment ->
|
|
||||||
irElement.files.forEach { postprocess(context, it) }
|
|
||||||
is IrFile ->
|
|
||||||
recordFileClassInfo(context, irElement)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val fileClassInfoByFileEntry = HashMap<SourceManager.FileEntry, JvmFileClassInfo>()
|
|
||||||
private val sourceElementByFileEntry = HashMap<SourceManager.FileEntry, SourceElement>()
|
|
||||||
|
|
||||||
private fun recordFileClassInfo(context: GeneratorContext, irFile: IrFile) {
|
|
||||||
context.sourceManager.getKtFile(irFile)?.let { ktFile ->
|
|
||||||
sourceElementByFileEntry[irFile.fileEntry] = KotlinSourceElement(ktFile)
|
|
||||||
}
|
|
||||||
val jvmFileClassInfo = context.sourceManager.getFileClassInfo(irFile) ?: return
|
|
||||||
fileClassInfoByFileEntry[irFile.fileEntry] = jvmFileClassInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PsiSourceManager.getFileClassInfo(irFile: IrFile): JvmFileClassInfo? {
|
|
||||||
val file = getKtFile(irFile) ?: return null
|
|
||||||
return JvmFileClassUtil.getFileClassInfoNoResolve(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createFileClassDescriptor(fileEntry: SourceManager.FileEntry, packageFragment: PackageFragmentDescriptor): FileClassDescriptor {
|
|
||||||
val fileClassInfo = fileClassInfoByFileEntry[fileEntry] ?: throw AssertionError("No file class info for ${fileEntry.name})")
|
|
||||||
val sourceElement = sourceElementByFileEntry[fileEntry] ?: SourceElement.NO_SOURCE
|
|
||||||
return FileClassDescriptorImpl(fileClassInfo.fileClassFqName.shortName(), packageFragment, sourceElement)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+14
-21
@@ -18,13 +18,12 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.FileLoweringPass
|
import org.jetbrains.kotlin.backend.jvm.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class PropertiesLowering : IrElementTransformerVoid(), FileLoweringPass {
|
class PropertiesLowering : IrElementTransformerVoid(), FileLoweringPass {
|
||||||
@@ -34,29 +33,23 @@ class PropertiesLowering : IrElementTransformerVoid(), FileLoweringPass {
|
|||||||
|
|
||||||
override fun visitFile(declaration: IrFile): IrFile {
|
override fun visitFile(declaration: IrFile): IrFile {
|
||||||
declaration.transformChildrenVoid(this)
|
declaration.transformChildrenVoid(this)
|
||||||
transformDeclarations(declaration.declarations)
|
declaration.declarations.transformFlat { lowerProperty(it) }
|
||||||
return declaration
|
return declaration
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass): IrStatement {
|
override fun visitClass(declaration: IrClass): IrStatement {
|
||||||
declaration.transformChildrenVoid(this)
|
declaration.transformChildrenVoid(this)
|
||||||
transformDeclarations(declaration.declarations)
|
declaration.declarations.transformFlat { lowerProperty(it) }
|
||||||
return declaration
|
return declaration
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun transformDeclarations(declarations: MutableList<IrDeclaration>) {
|
private fun lowerProperty(declaration: IrDeclaration): List<IrDeclaration>? =
|
||||||
val newDeclarations = ArrayList<IrDeclaration>()
|
if (declaration is IrProperty)
|
||||||
for (declaration in declarations) {
|
ArrayList<IrDeclaration>(3).apply {
|
||||||
if (declaration is IrProperty) {
|
addIfNotNull(declaration.backingField)
|
||||||
newDeclarations.addIfNotNull(declaration.backingField)
|
addIfNotNull(declaration.getter)
|
||||||
newDeclarations.addIfNotNull(declaration.getter)
|
addIfNotNull(declaration.setter)
|
||||||
newDeclarations.addIfNotNull(declaration.setter)
|
}
|
||||||
}
|
else
|
||||||
else {
|
null
|
||||||
newDeclarations.add(declaration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
declarations.clear()
|
|
||||||
declarations.addAll(newDeclarations)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.BodyLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrGetEnumValue
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
|
class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLoweringPass, IrElementTransformerVoid() {
|
||||||
|
override fun lower(irBody: IrBody) {
|
||||||
|
irBody.transformChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression {
|
||||||
|
val enumValueFieldDescriptor = context.specialDescriptorsFactory.getFieldDescriptorForEnumEntry(expression.descriptor)
|
||||||
|
return IrGetFieldImpl(expression.startOffset, expression.endOffset, enumValueFieldDescriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.psi2ir
|
package org.jetbrains.kotlin.psi2ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
@@ -70,3 +72,9 @@ inline fun ClassDescriptor.findFirstFunction(name: String, predicate: (CallableM
|
|||||||
|
|
||||||
inline fun MemberScope.findFirstFunction(name: String, predicate: (CallableMemberDescriptor) -> Boolean) =
|
inline fun MemberScope.findFirstFunction(name: String, predicate: (CallableMemberDescriptor) -> Boolean) =
|
||||||
getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).first(predicate)
|
getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).first(predicate)
|
||||||
|
|
||||||
|
fun MemberScope.findSingleFunction(name: Name): FunctionDescriptor =
|
||||||
|
getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).single()
|
||||||
|
|
||||||
|
fun KotlinBuiltIns.findSingleFunction(name: Name): FunctionDescriptor =
|
||||||
|
builtInsPackageScope.findSingleFunction(name)
|
||||||
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
|||||||
import java.lang.AssertionError
|
import java.lang.AssertionError
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context: GeneratorContext): GeneratorWithScope {
|
class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context: GeneratorContext) : GeneratorWithScope {
|
||||||
override val scope = Scope(scopeOwner)
|
override val scope = Scope(scopeOwner)
|
||||||
private val loopTable = HashMap<KtLoopExpression, IrLoop>()
|
private val loopTable = HashMap<KtLoopExpression, IrLoop>()
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
|
|||||||
|
|
||||||
fun generatePropertyInitializerBody(ktInitializer: KtExpression): IrExpressionBody =
|
fun generatePropertyInitializerBody(ktInitializer: KtExpression): IrExpressionBody =
|
||||||
IrExpressionBodyImpl(ktInitializer.startOffset, ktInitializer.endOffset,
|
IrExpressionBodyImpl(ktInitializer.startOffset, ktInitializer.endOffset,
|
||||||
createStatementGenerator().generateExpression(ktInitializer))
|
createStatementGenerator().generateExpression(ktInitializer))
|
||||||
|
|
||||||
fun generateLambdaBody(ktFun: KtFunctionLiteral): IrBody {
|
fun generateLambdaBody(ktFun: KtFunctionLiteral): IrBody {
|
||||||
val statementGenerator = createStatementGenerator()
|
val statementGenerator = createStatementGenerator()
|
||||||
@@ -231,7 +231,7 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
|
|||||||
|
|
||||||
private fun generateEnumSuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktElement: KtElement) {
|
private fun generateEnumSuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktElement: KtElement) {
|
||||||
val enumConstructor = context.builtIns.enum.constructors.single()
|
val enumConstructor = context.builtIns.enum.constructors.single()
|
||||||
irBlockBody.statements.add(IrEnumConstructorCallImpl(ktElement.startOffset, ktElement.endOffset, enumConstructor, null))
|
irBlockBody.statements.add(IrEnumConstructorCallImpl(ktElement.startOffset, ktElement.endOffset, enumConstructor))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateEnumEntrySuperConstructorCall(ktEnumEntry: KtEnumEntry, enumEntryDescriptor: ClassDescriptor): IrExpression {
|
private fun generateEnumEntrySuperConstructorCall(ktEnumEntry: KtEnumEntry, enumEntryDescriptor: ClassDescriptor): IrExpression {
|
||||||
@@ -253,8 +253,7 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
|
|||||||
fun generateEnumEntryInitializer(ktEnumEntry: KtEnumEntry, enumEntryDescriptor: ClassDescriptor): IrExpression {
|
fun generateEnumEntryInitializer(ktEnumEntry: KtEnumEntry, enumEntryDescriptor: ClassDescriptor): IrExpression {
|
||||||
if (ktEnumEntry.declarations.isNotEmpty()) {
|
if (ktEnumEntry.declarations.isNotEmpty()) {
|
||||||
val enumEntryConstructor = enumEntryDescriptor.unsubstitutedPrimaryConstructor!!
|
val enumEntryConstructor = enumEntryDescriptor.unsubstitutedPrimaryConstructor!!
|
||||||
return IrEnumConstructorCallImpl(ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
return IrEnumConstructorCallImpl(ktEnumEntry.startOffset, ktEnumEntry.endOffset, enumEntryConstructor)
|
||||||
enumEntryConstructor, enumEntryDescriptor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return generateEnumConstructorCallOrSuperCall(ktEnumEntry, enumEntryDescriptor.containingDeclaration as ClassDescriptor, enumEntryDescriptor)
|
return generateEnumConstructorCallOrSuperCall(ktEnumEntry, enumEntryDescriptor.containingDeclaration as ClassDescriptor, enumEntryDescriptor)
|
||||||
@@ -278,8 +277,7 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
|
|||||||
|
|
||||||
// No-argument enum entry constructor
|
// No-argument enum entry constructor
|
||||||
val enumClassConstructor = enumClassDescriptor.unsubstitutedPrimaryConstructor!!
|
val enumClassConstructor = enumClassDescriptor.unsubstitutedPrimaryConstructor!!
|
||||||
return IrEnumConstructorCallImpl(ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
return IrEnumConstructorCallImpl(ktEnumEntry.startOffset, ktEnumEntry.endOffset, enumClassConstructor)
|
||||||
enumClassConstructor, enumEntryOrNull)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
|||||||
|
|
||||||
fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder) : IrExpression {
|
fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder) : IrExpression {
|
||||||
val descriptor = call.descriptor
|
val descriptor = call.descriptor
|
||||||
if (descriptor !is ConstructorDescriptor) throw AssertionError("Constructor expected: $descriptor")
|
if (descriptor !is ClassConstructorDescriptor) throw AssertionError("Class constructor expected: $descriptor")
|
||||||
|
|
||||||
return call.callReceiver.call { dispatchReceiver, extensionReceiver ->
|
return call.callReceiver.call { dispatchReceiver, extensionReceiver ->
|
||||||
val irCall = IrDelegatingConstructorCallImpl(startOffset, endOffset, descriptor, getTypeArguments(call.original))
|
val irCall = IrDelegatingConstructorCallImpl(startOffset, endOffset, descriptor, getTypeArguments(call.original))
|
||||||
@@ -78,7 +78,7 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
|||||||
return call.callReceiver.call { dispatchReceiver, extensionReceiver ->
|
return call.callReceiver.call { dispatchReceiver, extensionReceiver ->
|
||||||
if (dispatchReceiver != null) throw AssertionError("Dispatch receiver should be null: $dispatchReceiver")
|
if (dispatchReceiver != null) throw AssertionError("Dispatch receiver should be null: $dispatchReceiver")
|
||||||
if (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver")
|
if (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver")
|
||||||
val irCall = IrEnumConstructorCallImpl(startOffset, endOffset, constructorDescriptor, enumEntryDescriptor)
|
val irCall = IrEnumConstructorCallImpl(startOffset, endOffset, constructorDescriptor)
|
||||||
addParametersToCall(startOffset, endOffset, call, irCall, constructorDescriptor.returnType)
|
addParametersToCall(startOffset, endOffset, call, irCall, constructorDescriptor.returnType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.psi2ir.generators
|
package org.jetbrains.kotlin.psi2ir.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||||
@@ -88,7 +89,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
if (ktConstructor.isConstructorDelegatingToSuper(context.bindingContext)) {
|
if (ktConstructor.isConstructorDelegatingToSuper(context.bindingContext)) {
|
||||||
return generateSecondaryConstructorWithNestedInitializers(ktConstructor)
|
return generateSecondaryConstructorWithNestedInitializers(ktConstructor)
|
||||||
}
|
}
|
||||||
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor)
|
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor) as ClassConstructorDescriptor
|
||||||
val irConstructor = IrConstructorImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor)
|
val irConstructor = IrConstructorImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor)
|
||||||
val bodyGenerator = createBodyGenerator(constructorDescriptor)
|
val bodyGenerator = createBodyGenerator(constructorDescriptor)
|
||||||
bodyGenerator.generateDefaultParameters(ktConstructor, irConstructor)
|
bodyGenerator.generateDefaultParameters(ktConstructor, irConstructor)
|
||||||
@@ -98,7 +99,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
|
|
||||||
|
|
||||||
private fun generateSecondaryConstructorWithNestedInitializers(ktConstructor: KtSecondaryConstructor): IrFunction {
|
private fun generateSecondaryConstructorWithNestedInitializers(ktConstructor: KtSecondaryConstructor): IrFunction {
|
||||||
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor)
|
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor) as ClassConstructorDescriptor
|
||||||
val irConstructor = IrConstructorImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor)
|
val irConstructor = IrConstructorImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor)
|
||||||
val bodyGenerator = createBodyGenerator(constructorDescriptor)
|
val bodyGenerator = createBodyGenerator(constructorDescriptor)
|
||||||
bodyGenerator.generateDefaultParameters(ktConstructor, irConstructor)
|
bodyGenerator.generateDefaultParameters(ktConstructor, irConstructor)
|
||||||
|
|||||||
@@ -16,13 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.declarations
|
package org.jetbrains.kotlin.ir.declarations
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
|
|
||||||
|
|
||||||
interface IrConstructor : IrFunction {
|
interface IrConstructor : IrFunction {
|
||||||
override val declarationKind: IrDeclarationKind
|
override val declarationKind: IrDeclarationKind
|
||||||
get() = IrDeclarationKind.CONSTRUCTOR
|
get() = IrDeclarationKind.CONSTRUCTOR
|
||||||
|
|
||||||
override val descriptor: ConstructorDescriptor
|
override val descriptor: ClassConstructorDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.declarations
|
package org.jetbrains.kotlin.ir.declarations
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||||
|
|
||||||
interface IrDeclarationContainer {
|
interface IrDeclarationContainer {
|
||||||
val declarations: MutableList<IrDeclaration>
|
val declarations: MutableList<IrDeclaration>
|
||||||
}
|
}
|
||||||
+6
-4
@@ -16,16 +16,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.declarations.impl
|
package org.jetbrains.kotlin.ir.declarations.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
|
||||||
class IrConstructorImpl(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, override val descriptor: ConstructorDescriptor) :
|
class IrConstructorImpl(
|
||||||
IrFunctionBase(startOffset, endOffset, origin), IrConstructor {
|
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
||||||
|
override val descriptor: ClassConstructorDescriptor
|
||||||
|
) : IrFunctionBase(startOffset, endOffset, origin), IrConstructor {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ConstructorDescriptor,
|
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassConstructorDescriptor,
|
||||||
body: IrBody
|
body: IrBody
|
||||||
) : this(startOffset, endOffset, origin, descriptor) {
|
) : this(startOffset, endOffset, origin, descriptor) {
|
||||||
this.body = body
|
this.body = body
|
||||||
|
|||||||
@@ -17,32 +17,27 @@
|
|||||||
package org.jetbrains.kotlin.ir.descriptors
|
package org.jetbrains.kotlin.ir.descriptors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.KotlinTypeFactory
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitution
|
import org.jetbrains.kotlin.types.TypeSubstitution
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
class BuiltinsOperatorsBuilder(val packageFragment: PackageFragmentDescriptor, val builtIns: KotlinBuiltIns) {
|
||||||
val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtIns.builtInsModule)
|
|
||||||
|
|
||||||
val bool = builtIns.booleanType
|
val bool = builtIns.booleanType
|
||||||
val any = builtIns.anyType
|
val any = builtIns.anyType
|
||||||
val anyN = builtIns.nullableAnyType
|
val anyN = builtIns.nullableAnyType
|
||||||
val int = builtIns.intType
|
val int = builtIns.intType
|
||||||
val nothing = builtIns.nothingType
|
val nothing = builtIns.nothingType
|
||||||
|
|
||||||
val eqeqeq: FunctionDescriptor = defineOperator("EQEQEQ", bool, listOf(anyN, anyN))
|
fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrBuiltinOperatorDescriptor {
|
||||||
val eqeq: FunctionDescriptor = defineOperator("EQEQ", bool, listOf(anyN, anyN))
|
|
||||||
val lt0: FunctionDescriptor = defineOperator("LT0", bool, listOf(int))
|
|
||||||
val lteq0: FunctionDescriptor = defineOperator("LTEQ0", bool, listOf(int))
|
|
||||||
val gt0: FunctionDescriptor = defineOperator("GT0", bool, listOf(int))
|
|
||||||
val gteq0: FunctionDescriptor = defineOperator("GTEQ0", bool, listOf(int))
|
|
||||||
val throwNpe: FunctionDescriptor = defineOperator("THROW_NPE", nothing, listOf())
|
|
||||||
val booleanNot: FunctionDescriptor = defineOperator("NOT", bool, listOf(bool))
|
|
||||||
|
|
||||||
private fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrBuiltinOperatorDescriptor {
|
|
||||||
val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragment, Name.identifier(name), returnType)
|
val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragment, Name.identifier(name), returnType)
|
||||||
for ((i, valueParameterType) in valueParameterTypes.withIndex()) {
|
for ((i, valueParameterType) in valueParameterTypes.withIndex()) {
|
||||||
operatorDescriptor.addValueParameter(
|
operatorDescriptor.addValueParameter(
|
||||||
@@ -50,7 +45,44 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
|||||||
}
|
}
|
||||||
return operatorDescriptor
|
return operatorDescriptor
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun ClassDescriptor.findSingleFunction(name: String): FunctionDescriptor =
|
|
||||||
getMemberScope(TypeSubstitution.EMPTY).getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS).single()
|
class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
||||||
|
private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtIns.builtInsModule, KOTLIN_INTERNAL_IR_FQN)
|
||||||
|
private val builder = BuiltinsOperatorsBuilder(packageFragment, builtIns)
|
||||||
|
|
||||||
|
val eqeqeq: FunctionDescriptor = builder.run { defineOperator("EQEQEQ", bool, listOf(anyN, anyN)) }
|
||||||
|
val eqeq: FunctionDescriptor = builder.run { defineOperator("EQEQ", bool, listOf(anyN, anyN)) }
|
||||||
|
val lt0: FunctionDescriptor = builder.run { defineOperator("LT0", bool, listOf(int)) }
|
||||||
|
val lteq0: FunctionDescriptor = builder.run { defineOperator("LTEQ0", bool, listOf(int)) }
|
||||||
|
val gt0: FunctionDescriptor = builder.run { defineOperator("GT0", bool, listOf(int)) }
|
||||||
|
val gteq0: FunctionDescriptor = builder.run { defineOperator("GTEQ0", bool, listOf(int)) }
|
||||||
|
val throwNpe: FunctionDescriptor = builder.run { defineOperator("THROW_NPE", nothing, listOf()) }
|
||||||
|
val booleanNot: FunctionDescriptor = builder.run { defineOperator("NOT", bool, listOf(bool)) }
|
||||||
|
|
||||||
|
val enumValueOf: FunctionDescriptor =
|
||||||
|
SimpleFunctionDescriptorImpl.create(
|
||||||
|
packageFragment,
|
||||||
|
Annotations.EMPTY,
|
||||||
|
Name.identifier("enumValueOf"),
|
||||||
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
|
org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE
|
||||||
|
).apply {
|
||||||
|
val typeParameterT = TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||||
|
this, Annotations.EMPTY, true, Variance.INVARIANT, Name.identifier("T"), 0
|
||||||
|
)
|
||||||
|
|
||||||
|
val valueParameterName = ValueParameterDescriptorImpl(
|
||||||
|
this, null, 0, Annotations.EMPTY, Name.identifier("name"), builtIns.stringType,
|
||||||
|
false, false, false, false, null, org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE
|
||||||
|
)
|
||||||
|
|
||||||
|
val returnType = KotlinTypeFactory.simpleType(Annotations.EMPTY, typeParameterT.typeConstructor, listOf(), false)
|
||||||
|
|
||||||
|
initialize(null, null, listOf(typeParameterT), listOf(valueParameterName), returnType, Modality.FINAL, Visibilities.PUBLIC)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val KOTLIN_INTERNAL_IR_FQN = FqName("kotlin.internal.ir")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -25,9 +25,13 @@ import org.jetbrains.kotlin.types.TypeSubstitutor
|
|||||||
|
|
||||||
interface IrBuiltinsPackageFragmentDescriptor : PackageFragmentDescriptor
|
interface IrBuiltinsPackageFragmentDescriptor : PackageFragmentDescriptor
|
||||||
|
|
||||||
class IrBuiltinsPackageFragmentDescriptorImpl(val containingModule: ModuleDescriptor) : IrBuiltinsPackageFragmentDescriptor {
|
class IrBuiltinsPackageFragmentDescriptorImpl(
|
||||||
override val fqName: FqName get() = FqName("kotlin.internal.ir")
|
val containingModule: ModuleDescriptor,
|
||||||
override fun getName(): Name = Name.identifier("ir")
|
override val fqName: FqName
|
||||||
|
) : IrBuiltinsPackageFragmentDescriptor {
|
||||||
|
private val shortName = fqName.shortName()
|
||||||
|
|
||||||
|
override fun getName(): Name = shortName
|
||||||
|
|
||||||
override fun getContainingDeclaration(): ModuleDescriptor = containingModule
|
override fun getContainingDeclaration(): ModuleDescriptor = containingModule
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.ir.expressions
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
|
|
||||||
interface IrBody : IrElement {
|
interface IrBody : IrElement {
|
||||||
@@ -29,10 +28,6 @@ interface IrExpressionBody : IrBody {
|
|||||||
var expression: IrExpression
|
var expression: IrExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IrStatementContainer {
|
|
||||||
val statements: MutableList<IrStatement>
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IrBlockBody : IrBody, IrStatementContainer
|
interface IrBlockBody : IrBody, IrStatementContainer
|
||||||
|
|
||||||
interface IrSyntheticBody : IrBody {
|
interface IrSyntheticBody : IrBody {
|
||||||
|
|||||||
+2
-2
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.expressions
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
|
|
||||||
interface IrDelegatingConstructorCall : IrMemberAccessExpression {
|
interface IrDelegatingConstructorCall : IrMemberAccessExpression {
|
||||||
override val descriptor: ConstructorDescriptor
|
override val descriptor: ClassConstructorDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-8
@@ -16,15 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.expressions
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
|
||||||
|
|
||||||
|
|
||||||
interface IrEnumConstructorCall : IrMemberAccessExpression {
|
interface IrEnumConstructorCall : IrMemberAccessExpression {
|
||||||
override val descriptor: ConstructorDescriptor
|
override val descriptor: ClassConstructorDescriptor
|
||||||
val enumEntryDescriptor: ClassDescriptor?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val IrEnumConstructorCall.isSuper: Boolean
|
|
||||||
get() = enumEntryDescriptor == null
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
|
||||||
|
interface IrStatementContainer {
|
||||||
|
val statements: MutableList<IrStatement>
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy
|
import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
@@ -35,6 +36,13 @@ class IrCallImpl(
|
|||||||
override val origin: IrStatementOrigin? = null,
|
override val origin: IrStatementOrigin? = null,
|
||||||
override val superQualifier: ClassDescriptor? = null
|
override val superQualifier: ClassDescriptor? = null
|
||||||
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, type, descriptor.valueParameters.size, typeArguments), IrCallWithShallowCopy {
|
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, type, descriptor.valueParameters.size, typeArguments), IrCallWithShallowCopy {
|
||||||
|
constructor(
|
||||||
|
startOffset: Int, endOffset: Int, descriptor: CallableDescriptor,
|
||||||
|
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null,
|
||||||
|
origin: IrStatementOrigin? = null,
|
||||||
|
superQualifier: ClassDescriptor? = null
|
||||||
|
) : this(startOffset, endOffset, descriptor.returnType!!, descriptor, typeArguments, origin, superQualifier)
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitCall(this, data)
|
visitor.visitCall(this, data)
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.expressions.impl
|
package org.jetbrains.kotlin.ir.expressions.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
class IrDelegatingConstructorCallImpl(
|
class IrDelegatingConstructorCallImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
override val descriptor: ConstructorDescriptor,
|
override val descriptor: ClassConstructorDescriptor,
|
||||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?
|
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
|
||||||
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size, typeArguments),
|
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size, typeArguments),
|
||||||
IrDelegatingConstructorCall {
|
IrDelegatingConstructorCall {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||||
|
|||||||
+2
-4
@@ -16,8 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.expressions.impl
|
package org.jetbrains.kotlin.ir.expressions.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrEnumConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrEnumConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
@@ -25,8 +24,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
|||||||
class IrEnumConstructorCallImpl(
|
class IrEnumConstructorCallImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
override val descriptor: ConstructorDescriptor,
|
override val descriptor: ClassConstructorDescriptor
|
||||||
override val enumEntryDescriptor: ClassDescriptor? = null
|
|
||||||
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size, null),
|
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size, null),
|
||||||
IrEnumConstructorCall {
|
IrEnumConstructorCall {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrReturn
|
import org.jetbrains.kotlin.ir.expressions.IrReturn
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class IrReturnImpl(
|
class IrReturnImpl(
|
||||||
@@ -30,6 +31,9 @@ class IrReturnImpl(
|
|||||||
override val returnTarget: CallableDescriptor,
|
override val returnTarget: CallableDescriptor,
|
||||||
override var value: IrExpression
|
override var value: IrExpression
|
||||||
) : IrExpressionBase(startOffset, endOffset, type), IrReturn {
|
) : IrExpressionBase(startOffset, endOffset, type), IrReturn {
|
||||||
|
constructor(startOffset: Int, endOffset: Int, returnTarget: CallableDescriptor, value: IrExpression) :
|
||||||
|
this(startOffset, endOffset, returnTarget.builtIns.nothingType, returnTarget, value)
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitReturn(this, data)
|
visitor.visitReturn(this, data)
|
||||||
|
|
||||||
|
|||||||
+3
@@ -34,4 +34,7 @@ class IrSyntheticBodyImpl(startOffset: Int, endOffset: Int, override val kind: I
|
|||||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||||
// no children
|
// no children
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
"IrSyntheticBodyImpl($kind)"
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
|
|||||||
protected open fun mapClassDeclaration(descriptor: ClassDescriptor) = descriptor
|
protected open fun mapClassDeclaration(descriptor: ClassDescriptor) = descriptor
|
||||||
protected open fun mapTypeAliasDeclaration(descriptor: TypeAliasDescriptor) = descriptor
|
protected open fun mapTypeAliasDeclaration(descriptor: TypeAliasDescriptor) = descriptor
|
||||||
protected open fun mapFunctionDeclaration(descriptor: FunctionDescriptor) = descriptor
|
protected open fun mapFunctionDeclaration(descriptor: FunctionDescriptor) = descriptor
|
||||||
protected open fun mapConstructorDeclaration(descriptor: ConstructorDescriptor) = descriptor
|
protected open fun mapConstructorDeclaration(descriptor: ClassConstructorDescriptor) = descriptor
|
||||||
protected open fun mapPropertyDeclaration(descriptor: PropertyDescriptor) = descriptor
|
protected open fun mapPropertyDeclaration(descriptor: PropertyDescriptor) = descriptor
|
||||||
protected open fun mapLocalPropertyDeclaration(descriptor: VariableDescriptorWithAccessors) = descriptor
|
protected open fun mapLocalPropertyDeclaration(descriptor: VariableDescriptorWithAccessors) = descriptor
|
||||||
protected open fun mapEnumEntryDeclaration(descriptor: ClassDescriptor) = descriptor
|
protected open fun mapEnumEntryDeclaration(descriptor: ClassDescriptor) = descriptor
|
||||||
@@ -52,9 +52,8 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
|
|||||||
protected open fun mapPropertyReference(descriptor: PropertyDescriptor) = descriptor
|
protected open fun mapPropertyReference(descriptor: PropertyDescriptor) = descriptor
|
||||||
protected open fun mapReceiverParameterReference(descriptor: ReceiverParameterDescriptor) = descriptor
|
protected open fun mapReceiverParameterReference(descriptor: ReceiverParameterDescriptor) = descriptor
|
||||||
protected open fun mapCallee(descriptor: CallableDescriptor) = descriptor
|
protected open fun mapCallee(descriptor: CallableDescriptor) = descriptor
|
||||||
protected open fun mapDelegatedConstructorCallee(descriptor: ConstructorDescriptor) = descriptor
|
protected open fun mapDelegatedConstructorCallee(descriptor: ClassConstructorDescriptor) = descriptor
|
||||||
protected open fun mapEnumConstructorCallee(descriptor: ConstructorDescriptor) = descriptor
|
protected open fun mapEnumConstructorCallee(descriptor: ClassConstructorDescriptor) = descriptor
|
||||||
protected open fun mapEnumEntryInConstructor(descriptor: ClassDescriptor?) = descriptor
|
|
||||||
protected open fun mapCallableReference(descriptor: CallableDescriptor) = descriptor
|
protected open fun mapCallableReference(descriptor: CallableDescriptor) = descriptor
|
||||||
protected open fun mapClassifierReference(descriptor: ClassifierDescriptor) = descriptor
|
protected open fun mapClassifierReference(descriptor: ClassifierDescriptor) = descriptor
|
||||||
protected open fun mapReturnTarget(descriptor: CallableDescriptor) = mapCallee(descriptor)
|
protected open fun mapReturnTarget(descriptor: CallableDescriptor) = mapCallee(descriptor)
|
||||||
@@ -346,8 +345,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
|
|||||||
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall =
|
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall =
|
||||||
IrEnumConstructorCallImpl(
|
IrEnumConstructorCallImpl(
|
||||||
expression.startOffset, expression.endOffset,
|
expression.startOffset, expression.endOffset,
|
||||||
mapEnumConstructorCallee(expression.descriptor),
|
mapEnumConstructorCallee(expression.descriptor)
|
||||||
mapEnumEntryInConstructor(expression.enumEntryDescriptor)
|
|
||||||
).transformValueArguments(expression)
|
).transformValueArguments(expression)
|
||||||
|
|
||||||
override fun visitGetClass(expression: IrGetClass): IrGetClass =
|
override fun visitGetClass(expression: IrGetClass): IrGetClass =
|
||||||
|
|||||||
@@ -119,11 +119,7 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
|||||||
"DELEGATING_CONSTRUCTOR_CALL '${expression.descriptor.ref()}'"
|
"DELEGATING_CONSTRUCTOR_CALL '${expression.descriptor.ref()}'"
|
||||||
|
|
||||||
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: Nothing?): String =
|
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: Nothing?): String =
|
||||||
"ENUM_CONSTRUCTOR_CALL '${expression.descriptor.ref()}' " +
|
"ENUM_CONSTRUCTOR_CALL '${expression.descriptor.ref()}'"
|
||||||
expression.enumEntryDescriptor.let { enumEntryDescriptor ->
|
|
||||||
if (enumEntryDescriptor == null) "super"
|
|
||||||
else enumEntryDescriptor.ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: Nothing?): String =
|
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: Nothing?): String =
|
||||||
"INSTANCE_INITIALIZER_CALL classDescriptor='${expression.classDescriptor.ref()}'"
|
"INSTANCE_INITIALIZER_CALL classDescriptor='${expression.classDescriptor.ref()}'"
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ir.util
|
||||||
|
|
||||||
|
inline fun <T> MutableList<T>.transform(transformation: (T) -> T) {
|
||||||
|
forEachIndexed { i, item ->
|
||||||
|
set(i, transformation(item))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms a mutable list in place.
|
||||||
|
* Each element `it` is replaced with a result of `transformation(it)`,
|
||||||
|
* `null` means "keep existing element" (to avoid creating excessive singleton lists).
|
||||||
|
*/
|
||||||
|
inline fun <T> MutableList<T>.transformFlat(transformation: (T) -> List<T>?) {
|
||||||
|
var i = 0
|
||||||
|
while (i < size) {
|
||||||
|
val item = get(i)
|
||||||
|
|
||||||
|
val transformed = transformation(item)
|
||||||
|
|
||||||
|
if (transformed == null) {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
addAll(i, transformed)
|
||||||
|
i += transformed.size
|
||||||
|
removeAt(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
enum class Test { OK }
|
||||||
|
|
||||||
|
fun box() = Test.OK.toString()
|
||||||
+1
-1
@@ -14,7 +14,7 @@ FILE /classes.kt
|
|||||||
CLASS ENUM_CLASS TestEnumClass
|
CLASS ENUM_CLASS TestEnumClass
|
||||||
CONSTRUCTOR private constructor TestEnumClass()
|
CONSTRUCTOR private constructor TestEnumClass()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)' super
|
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnumClass'
|
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnumClass'
|
||||||
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<TestEnumClass>
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<TestEnumClass>
|
||||||
SYNTHETIC_BODY kind=ENUM_VALUES
|
SYNTHETIC_BODY kind=ENUM_VALUES
|
||||||
|
|||||||
+15
-15
@@ -2,12 +2,12 @@ FILE /enum.kt
|
|||||||
CLASS ENUM_CLASS TestEnum1
|
CLASS ENUM_CLASS TestEnum1
|
||||||
CONSTRUCTOR private constructor TestEnum1()
|
CONSTRUCTOR private constructor TestEnum1()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)' super
|
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum1'
|
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum1'
|
||||||
ENUM_ENTRY enum entry TEST1
|
ENUM_ENTRY enum entry TEST1
|
||||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum1()' TEST1
|
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum1()'
|
||||||
ENUM_ENTRY enum entry TEST2
|
ENUM_ENTRY enum entry TEST2
|
||||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum1()' TEST2
|
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum1()'
|
||||||
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<TestEnum1>
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<TestEnum1>
|
||||||
SYNTHETIC_BODY kind=ENUM_VALUES
|
SYNTHETIC_BODY kind=ENUM_VALUES
|
||||||
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun valueOf(value: kotlin.String): TestEnum1
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun valueOf(value: kotlin.String): TestEnum1
|
||||||
@@ -15,7 +15,7 @@ FILE /enum.kt
|
|||||||
CLASS ENUM_CLASS TestEnum2
|
CLASS ENUM_CLASS TestEnum2
|
||||||
CONSTRUCTOR private constructor TestEnum2(x: kotlin.Int)
|
CONSTRUCTOR private constructor TestEnum2(x: kotlin.Int)
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)' super
|
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum2'
|
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum2'
|
||||||
PROPERTY public final val x: kotlin.Int
|
PROPERTY public final val x: kotlin.Int
|
||||||
FIELD PROPERTY_BACKING_FIELD public final val x: kotlin.Int
|
FIELD PROPERTY_BACKING_FIELD public final val x: kotlin.Int
|
||||||
@@ -27,13 +27,13 @@ FILE /enum.kt
|
|||||||
GET_FIELD 'x: Int' type=kotlin.Int origin=null
|
GET_FIELD 'x: Int' type=kotlin.Int origin=null
|
||||||
receiver: THIS of 'TestEnum2' type=TestEnum2
|
receiver: THIS of 'TestEnum2' type=TestEnum2
|
||||||
ENUM_ENTRY enum entry TEST1
|
ENUM_ENTRY enum entry TEST1
|
||||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum2(Int)' TEST1
|
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum2(Int)'
|
||||||
x: CONST Int type=kotlin.Int value='1'
|
x: CONST Int type=kotlin.Int value='1'
|
||||||
ENUM_ENTRY enum entry TEST2
|
ENUM_ENTRY enum entry TEST2
|
||||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum2(Int)' TEST2
|
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum2(Int)'
|
||||||
x: CONST Int type=kotlin.Int value='2'
|
x: CONST Int type=kotlin.Int value='2'
|
||||||
ENUM_ENTRY enum entry TEST3
|
ENUM_ENTRY enum entry TEST3
|
||||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum2(Int)' TEST3
|
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum2(Int)'
|
||||||
x: CONST Int type=kotlin.Int value='3'
|
x: CONST Int type=kotlin.Int value='3'
|
||||||
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<TestEnum2>
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<TestEnum2>
|
||||||
SYNTHETIC_BODY kind=ENUM_VALUES
|
SYNTHETIC_BODY kind=ENUM_VALUES
|
||||||
@@ -42,14 +42,14 @@ FILE /enum.kt
|
|||||||
CLASS ENUM_CLASS TestEnum3
|
CLASS ENUM_CLASS TestEnum3
|
||||||
CONSTRUCTOR private constructor TestEnum3()
|
CONSTRUCTOR private constructor TestEnum3()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)' super
|
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum3'
|
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum3'
|
||||||
ENUM_ENTRY enum entry TEST
|
ENUM_ENTRY enum entry TEST
|
||||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TEST()' TEST
|
init: ENUM_CONSTRUCTOR_CALL 'constructor TEST()'
|
||||||
class: CLASS ENUM_ENTRY TEST
|
class: CLASS ENUM_ENTRY TEST
|
||||||
CONSTRUCTOR private constructor TEST()
|
CONSTRUCTOR private constructor TEST()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ENUM_CONSTRUCTOR_CALL 'constructor TestEnum3()' super
|
ENUM_CONSTRUCTOR_CALL 'constructor TestEnum3()'
|
||||||
INSTANCE_INITIALIZER_CALL classDescriptor='TEST'
|
INSTANCE_INITIALIZER_CALL classDescriptor='TEST'
|
||||||
FUN public open override fun foo(): kotlin.Unit
|
FUN public open override fun foo(): kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
@@ -63,7 +63,7 @@ FILE /enum.kt
|
|||||||
CLASS ENUM_CLASS TestEnum4
|
CLASS ENUM_CLASS TestEnum4
|
||||||
CONSTRUCTOR private constructor TestEnum4(x: kotlin.Int)
|
CONSTRUCTOR private constructor TestEnum4(x: kotlin.Int)
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)' super
|
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum4'
|
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum4'
|
||||||
PROPERTY public final val x: kotlin.Int
|
PROPERTY public final val x: kotlin.Int
|
||||||
FIELD PROPERTY_BACKING_FIELD public final val x: kotlin.Int
|
FIELD PROPERTY_BACKING_FIELD public final val x: kotlin.Int
|
||||||
@@ -75,11 +75,11 @@ FILE /enum.kt
|
|||||||
GET_FIELD 'x: Int' type=kotlin.Int origin=null
|
GET_FIELD 'x: Int' type=kotlin.Int origin=null
|
||||||
receiver: THIS of 'TestEnum4' type=TestEnum4
|
receiver: THIS of 'TestEnum4' type=TestEnum4
|
||||||
ENUM_ENTRY enum entry TEST1
|
ENUM_ENTRY enum entry TEST1
|
||||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TEST1()' TEST1
|
init: ENUM_CONSTRUCTOR_CALL 'constructor TEST1()'
|
||||||
class: CLASS ENUM_ENTRY TEST1
|
class: CLASS ENUM_ENTRY TEST1
|
||||||
CONSTRUCTOR private constructor TEST1()
|
CONSTRUCTOR private constructor TEST1()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ENUM_CONSTRUCTOR_CALL 'constructor TestEnum4(Int)' super
|
ENUM_CONSTRUCTOR_CALL 'constructor TestEnum4(Int)'
|
||||||
x: CONST Int type=kotlin.Int value='1'
|
x: CONST Int type=kotlin.Int value='1'
|
||||||
INSTANCE_INITIALIZER_CALL classDescriptor='TEST1'
|
INSTANCE_INITIALIZER_CALL classDescriptor='TEST1'
|
||||||
FUN public open override fun foo(): kotlin.Unit
|
FUN public open override fun foo(): kotlin.Unit
|
||||||
@@ -87,11 +87,11 @@ FILE /enum.kt
|
|||||||
CALL 'println(Any?): Unit' type=kotlin.Unit origin=null
|
CALL 'println(Any?): Unit' type=kotlin.Unit origin=null
|
||||||
message: GET_ENUM 'TEST1' type=TestEnum4
|
message: GET_ENUM 'TEST1' type=TestEnum4
|
||||||
ENUM_ENTRY enum entry TEST2
|
ENUM_ENTRY enum entry TEST2
|
||||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TEST2()' TEST2
|
init: ENUM_CONSTRUCTOR_CALL 'constructor TEST2()'
|
||||||
class: CLASS ENUM_ENTRY TEST2
|
class: CLASS ENUM_ENTRY TEST2
|
||||||
CONSTRUCTOR private constructor TEST2()
|
CONSTRUCTOR private constructor TEST2()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ENUM_CONSTRUCTOR_CALL 'constructor TestEnum4(Int)' super
|
ENUM_CONSTRUCTOR_CALL 'constructor TestEnum4(Int)'
|
||||||
x: CONST Int type=kotlin.Int value='2'
|
x: CONST Int type=kotlin.Int value='2'
|
||||||
INSTANCE_INITIALIZER_CALL classDescriptor='TEST2'
|
INSTANCE_INITIALIZER_CALL classDescriptor='TEST2'
|
||||||
PROPERTY public final val z: kotlin.Int
|
PROPERTY public final val z: kotlin.Int
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
enum class Test1(val x: Int) {
|
||||||
|
ZERO, ONE(1);
|
||||||
|
constructor() : this(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Test2(val x: Int) {
|
||||||
|
ZERO {
|
||||||
|
override fun foo() {
|
||||||
|
println("ZERO")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ONE(1) {
|
||||||
|
override fun foo() {
|
||||||
|
println("ONE")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
constructor() : this(0)
|
||||||
|
abstract fun foo()
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
FILE /enumWithSecondaryCtor.kt
|
||||||
|
CLASS ENUM_CLASS Test1
|
||||||
|
CONSTRUCTOR private constructor Test1(x: kotlin.Int)
|
||||||
|
BLOCK_BODY
|
||||||
|
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||||
|
INSTANCE_INITIALIZER_CALL classDescriptor='Test1'
|
||||||
|
PROPERTY public final val x: kotlin.Int
|
||||||
|
FIELD PROPERTY_BACKING_FIELD public final val x: kotlin.Int
|
||||||
|
EXPRESSION_BODY
|
||||||
|
GET_VAR 'value-parameter x: Int' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-x>(): kotlin.Int
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='<get-x>(): Int'
|
||||||
|
GET_FIELD 'x: Int' type=kotlin.Int origin=null
|
||||||
|
receiver: THIS of 'Test1' type=Test1
|
||||||
|
ENUM_ENTRY enum entry ZERO
|
||||||
|
init: ENUM_CONSTRUCTOR_CALL 'constructor Test1(Int)'
|
||||||
|
ENUM_ENTRY enum entry ONE
|
||||||
|
init: ENUM_CONSTRUCTOR_CALL 'constructor Test1(Int)'
|
||||||
|
x: CONST Int type=kotlin.Int value='1'
|
||||||
|
CONSTRUCTOR private constructor Test1()
|
||||||
|
BLOCK_BODY
|
||||||
|
DELEGATING_CONSTRUCTOR_CALL 'constructor Test1(Int)'
|
||||||
|
x: CONST Int type=kotlin.Int value='0'
|
||||||
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<Test1>
|
||||||
|
SYNTHETIC_BODY kind=ENUM_VALUES
|
||||||
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun valueOf(value: kotlin.String): Test1
|
||||||
|
SYNTHETIC_BODY kind=ENUM_VALUEOF
|
||||||
|
CLASS ENUM_CLASS Test2
|
||||||
|
CONSTRUCTOR private constructor Test2(x: kotlin.Int)
|
||||||
|
BLOCK_BODY
|
||||||
|
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||||
|
INSTANCE_INITIALIZER_CALL classDescriptor='Test2'
|
||||||
|
PROPERTY public final val x: kotlin.Int
|
||||||
|
FIELD PROPERTY_BACKING_FIELD public final val x: kotlin.Int
|
||||||
|
EXPRESSION_BODY
|
||||||
|
GET_VAR 'value-parameter x: Int' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-x>(): kotlin.Int
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='<get-x>(): Int'
|
||||||
|
GET_FIELD 'x: Int' type=kotlin.Int origin=null
|
||||||
|
receiver: THIS of 'Test2' type=Test2
|
||||||
|
ENUM_ENTRY enum entry ZERO
|
||||||
|
init: ENUM_CONSTRUCTOR_CALL 'constructor ZERO()'
|
||||||
|
class: CLASS ENUM_ENTRY ZERO
|
||||||
|
CONSTRUCTOR private constructor ZERO()
|
||||||
|
BLOCK_BODY
|
||||||
|
ENUM_CONSTRUCTOR_CALL 'constructor Test2(Int)'
|
||||||
|
INSTANCE_INITIALIZER_CALL classDescriptor='ZERO'
|
||||||
|
FUN public open override fun foo(): kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL 'println(Any?): Unit' type=kotlin.Unit origin=null
|
||||||
|
message: CONST String type=kotlin.String value='ZERO'
|
||||||
|
ENUM_ENTRY enum entry ONE
|
||||||
|
init: ENUM_CONSTRUCTOR_CALL 'constructor ONE()'
|
||||||
|
class: CLASS ENUM_ENTRY ONE
|
||||||
|
CONSTRUCTOR private constructor ONE()
|
||||||
|
BLOCK_BODY
|
||||||
|
ENUM_CONSTRUCTOR_CALL 'constructor Test2(Int)'
|
||||||
|
x: CONST Int type=kotlin.Int value='1'
|
||||||
|
INSTANCE_INITIALIZER_CALL classDescriptor='ONE'
|
||||||
|
FUN public open override fun foo(): kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL 'println(Any?): Unit' type=kotlin.Unit origin=null
|
||||||
|
message: CONST String type=kotlin.String value='ONE'
|
||||||
|
CONSTRUCTOR private constructor Test2()
|
||||||
|
BLOCK_BODY
|
||||||
|
DELEGATING_CONSTRUCTOR_CALL 'constructor Test2(Int)'
|
||||||
|
x: CONST Int type=kotlin.Int value='0'
|
||||||
|
FUN public abstract fun foo(): kotlin.Unit
|
||||||
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<Test2>
|
||||||
|
SYNTHETIC_BODY kind=ENUM_VALUES
|
||||||
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun valueOf(value: kotlin.String): Test2
|
||||||
|
SYNTHETIC_BODY kind=ENUM_VALUEOF
|
||||||
+2
-2
@@ -2,10 +2,10 @@ FILE /values.kt
|
|||||||
CLASS ENUM_CLASS Enum
|
CLASS ENUM_CLASS Enum
|
||||||
CONSTRUCTOR private constructor Enum()
|
CONSTRUCTOR private constructor Enum()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)' super
|
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||||
INSTANCE_INITIALIZER_CALL classDescriptor='Enum'
|
INSTANCE_INITIALIZER_CALL classDescriptor='Enum'
|
||||||
ENUM_ENTRY enum entry A
|
ENUM_ENTRY enum entry A
|
||||||
init: ENUM_CONSTRUCTOR_CALL 'constructor Enum()' A
|
init: ENUM_CONSTRUCTOR_CALL 'constructor Enum()'
|
||||||
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<Enum>
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array<Enum>
|
||||||
SYNTHETIC_BODY kind=ENUM_VALUES
|
SYNTHETIC_BODY kind=ENUM_VALUES
|
||||||
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun valueOf(value: kotlin.String): Enum
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun valueOf(value: kotlin.String): Enum
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ public class IrOnlyBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTest
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("enumClass.kt")
|
||||||
|
public void testEnumClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/enumClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("fileClassInitializers.kt")
|
@TestMetadata("fileClassInitializers.kt")
|
||||||
public void testFileClassInitializers() throws Exception {
|
public void testFileClassInitializers() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/fileClassInitializers.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/fileClassInitializers.kt");
|
||||||
|
|||||||
@@ -97,6 +97,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("enumWithSecondaryCtor.kt")
|
||||||
|
public void testEnumWithSecondaryCtor() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/enumWithSecondaryCtor.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("initBlock.kt")
|
@TestMetadata("initBlock.kt")
|
||||||
public void testInitBlock() throws Exception {
|
public void testInitBlock() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/initBlock.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/initBlock.kt");
|
||||||
|
|||||||
+10
@@ -55,6 +55,16 @@ public class ClassConstructorDescriptorImpl extends FunctionDescriptorImpl imple
|
|||||||
return new ClassConstructorDescriptorImpl(containingDeclaration, null, annotations, isPrimary, Kind.DECLARATION, source);
|
return new ClassConstructorDescriptorImpl(containingDeclaration, null, annotations, isPrimary, Kind.DECLARATION, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static ClassConstructorDescriptorImpl createSynthesized(
|
||||||
|
@NotNull ClassDescriptor containingDeclaration,
|
||||||
|
@NotNull Annotations annotations,
|
||||||
|
boolean isPrimary,
|
||||||
|
@NotNull SourceElement source
|
||||||
|
) {
|
||||||
|
return new ClassConstructorDescriptorImpl(containingDeclaration, null, annotations, isPrimary, Kind.SYNTHESIZED, source);
|
||||||
|
}
|
||||||
|
|
||||||
public ClassConstructorDescriptorImpl initialize(
|
public ClassConstructorDescriptorImpl initialize(
|
||||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||||
@NotNull Visibility visibility,
|
@NotNull Visibility visibility,
|
||||||
|
|||||||
Reference in New Issue
Block a user