Remove JvmDescriptorWithExtraFlags and fix syntheticness

(of fields and classes, it is already correct for methods).
This commit is contained in:
pyos
2019-04-04 09:39:39 +02:00
committed by Mikhael Bogdanov
parent 3fdcf8376f
commit fb0261bfc1
14 changed files with 62 additions and 322 deletions
@@ -9,9 +9,9 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.IrType
interface DeclarationFactory {
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS", isSynthetic = true)
fun getFieldForEnumEntry(enumEntry: IrEnumEntry, type: IrType): IrField
fun getFieldForEnumEntry(enumEntry: IrEnumEntry, entryType: IrType): IrField
fun getOuterThisField(innerClass: IrClass): IrField
fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: IrConstructor): IrConstructor
fun getFieldForObjectInstance(singleton: IrClass): IrField
@@ -32,7 +32,7 @@ class JsDeclarationFactory : DeclarationFactory {
private val outerThisFieldSymbols = HashMap<IrClass, IrField>()
private val innerClassConstructors = HashMap<IrConstructor, IrConstructor>()
override fun getFieldForEnumEntry(enumEntry: IrEnumEntry, type: IrType): IrField = TODO()
override fun getFieldForEnumEntry(enumEntry: IrEnumEntry, entryType: IrType): IrField = TODO()
override fun getOuterThisField(innerClass: IrClass): IrField =
if (!innerClass.isInner) throw AssertionError("Class is not inner: ${innerClass.dump()}")
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDescriptorWithExtraFlags
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper
@@ -27,9 +26,7 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.getPackageFragment
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.name.SpecialNames
@@ -97,7 +94,7 @@ open class ClassCodegen protected constructor(
visitor.defineClass(
psiElement,
state.classFileVersion,
descriptor.calculateClassFlags(),
irClass.flags,
signature.name,
signature.javaGenericSignature,
signature.superclassName,
@@ -218,7 +215,7 @@ open class ClassCodegen protected constructor(
val fieldSignature = typeMapper.mapFieldSignature(field.descriptor.type, field.descriptor)
val fieldName = field.descriptor.name.asString()
val fv = visitor.newField(
field.OtherOrigin, field.descriptor.calculateCommonFlags(), fieldName, fieldType.descriptor,
field.OtherOrigin, field.flags, fieldName, fieldType.descriptor,
fieldSignature, null/*TODO support default values*/
)
@@ -313,79 +310,33 @@ open class ClassCodegen protected constructor(
}
fun ClassDescriptor.calculateClassFlags(): Int {
var flags = 0
flags = flags or if (JvmCodegenUtil.isJvmInterface(this)) Opcodes.ACC_INTERFACE else Opcodes.ACC_SUPER
flags = flags or calcModalityFlag()
flags = flags or AsmUtil.getVisibilityAccessFlagForClass(this)
flags = flags or if (kind == ClassKind.ENUM_CLASS) Opcodes.ACC_ENUM else 0
flags = flags or if (kind == ClassKind.ANNOTATION_CLASS) Opcodes.ACC_ANNOTATION else 0
return flags
}
fun MemberDescriptor.calculateCommonFlags(): Int {
var flags = 0
if (Visibilities.isPrivate(visibility)) {
flags = flags.or(Opcodes.ACC_PRIVATE)
} else if (visibility == Visibilities.PUBLIC || visibility == Visibilities.INTERNAL) {
flags = flags.or(Opcodes.ACC_PUBLIC)
} else if (visibility == Visibilities.PROTECTED) {
flags = flags.or(Opcodes.ACC_PROTECTED)
} else if (visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
// default visibility
} else {
throw RuntimeException("Unsupported visibility $visibility for descriptor $this")
private val IrClass.flags: Int
get() = origin.flags or AsmUtil.getVisibilityAccessFlagForClass(descriptor) or when {
isAnnotationClass -> Opcodes.ACC_ANNOTATION or Opcodes.ACC_INTERFACE or Opcodes.ACC_ABSTRACT
isInterface -> Opcodes.ACC_INTERFACE or Opcodes.ACC_ABSTRACT
isEnumClass -> Opcodes.ACC_ENUM or Opcodes.ACC_SUPER or modality.flags
else -> Opcodes.ACC_SUPER or modality.flags
}
flags = flags.or(calcModalityFlag())
private val IrField.flags: Int
get() = origin.flags or visibility.flags or
(if (isFinal) Opcodes.ACC_FINAL else 0) or
(if (isStatic) Opcodes.ACC_STATIC else 0)
if (this is JvmDescriptorWithExtraFlags) {
flags = flags or extraFlags
private val IrDeclarationOrigin.flags: Int
get() = (if (isSynthetic) Opcodes.ACC_SYNTHETIC else 0) or
(if (this == IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) Opcodes.ACC_ENUM else 0)
private val Modality.flags: Int
get() = when (this) {
Modality.ABSTRACT, Modality.SEALED -> Opcodes.ACC_ABSTRACT
Modality.FINAL -> Opcodes.ACC_FINAL
Modality.OPEN -> 0
else -> throw AssertionError("Unsupported modality $this")
}
return flags
}
private fun MemberDescriptor.calcModalityFlag(): Int {
var flags = 0
if (this is PropertyDescriptor) {
// Modality for a field: set FINAL for vals
if (!isVar && !isLateInit) {
flags = flags.or(Opcodes.ACC_FINAL)
}
} else when (effectiveModality) {
Modality.ABSTRACT -> {
flags = flags.or(Opcodes.ACC_ABSTRACT)
}
Modality.FINAL -> {
if (this !is ConstructorDescriptor && !DescriptorUtils.isEnumClass(this)) {
flags = flags.or(Opcodes.ACC_FINAL)
}
}
Modality.OPEN -> {
assert(!Visibilities.isPrivate(visibility))
}
else -> throw RuntimeException("Unsupported modality $modality for descriptor ${this}")
}
if (this is CallableMemberDescriptor) {
if (this !is ConstructorDescriptor && dispatchReceiverParameter == null) {
flags = flags or Opcodes.ACC_STATIC
}
}
return flags
}
private val MemberDescriptor.effectiveModality: Modality
get() {
if (DescriptorUtils.isSealedClass(this) ||
DescriptorUtils.isAnnotationClass(this)
) {
return Modality.ABSTRACT
}
return modality
}
private val Visibility.flags: Int
get() = AsmUtil.getVisibilityAccessFlag(this) ?: throw AssertionError("Unsupported visibility $this")
private val IrField.OtherOrigin: JvmDeclarationOrigin
get() = OtherOrigin(descriptor.psiElement, this.descriptor)
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDescriptorWithExtraFlags
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.FunctionCodegen
@@ -95,8 +94,7 @@ open class FunctionCodegen(
deprecation or
nativeFlag or
bridgeFlag or
syntheticFlag or
(if (descriptor is JvmDescriptorWithExtraFlags) descriptor.extraFlags else 0)
syntheticFlag
}
protected open fun createMethod(flags: Int, signature: JvmMethodGenericSignature): MethodVisitor {
@@ -22,6 +22,8 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.buildField
import org.jetbrains.kotlin.ir.builders.setSourceRange
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
@@ -50,33 +52,31 @@ class JvmDeclarationFactory(
private val defaultImplsMethods = HashMap<IrSimpleFunction, IrSimpleFunction>()
private val defaultImplsClasses = HashMap<IrClass, IrClass>()
override fun getFieldForEnumEntry(enumEntry: IrEnumEntry, type: IrType): IrField =
override fun getFieldForEnumEntry(enumEntry: IrEnumEntry, entryType: IrType): IrField =
singletonFieldDeclarations.getOrPut(enumEntry) {
val symbol = IrFieldSymbolImpl(createEnumEntryFieldDescriptor(enumEntry.descriptor))
IrFieldImpl(
enumEntry.startOffset,
enumEntry.endOffset,
IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY,
symbol,
type
)
buildField {
setSourceRange(enumEntry)
name = enumEntry.name
type = enumEntry.parentAsClass.defaultType
origin = IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY
isFinal = true
isStatic = true
}.apply {
parent = enumEntry.parent
}
}
override fun getOuterThisField(innerClass: IrClass): IrField =
if (!innerClass.isInner) throw AssertionError("Class is not inner: ${innerClass.dump()}")
else outerThisDeclarations.getOrPut(innerClass) {
val outerClass = innerClass.parent as? IrClass
?: throw AssertionError("No containing class for inner class ${innerClass.dump()}")
val symbol = IrFieldSymbolImpl(
JvmPropertyDescriptorImpl.createFinalField(
Name.identifier("this$0"), outerClass.defaultType.toKotlinType(), innerClass.descriptor,
Annotations.EMPTY, JavaVisibilities.PACKAGE_VISIBILITY, Opcodes.ACC_SYNTHETIC, SourceElement.NO_SOURCE
)
)
IrFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, DeclarationFactory.FIELD_FOR_OUTER_THIS, symbol, outerClass.defaultType).also {
it.parent = innerClass
outerThisDeclarations.getOrPut(innerClass) {
assert(innerClass.isInner) { "Class is not inner: ${innerClass.dump()}" }
buildField {
name = Name.identifier("this$0")
type = innerClass.parentAsClass.defaultType
origin = DeclarationFactory.FIELD_FOR_OUTER_THIS
visibility = JavaVisibilities.PACKAGE_VISIBILITY
isFinal = true
}.apply {
parent = innerClass
}
}
@@ -124,52 +124,20 @@ class JvmDeclarationFactory(
}
}
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.createStaticVal(
enumEntryDescriptor.name,
enumClassDescriptor.defaultType,
enumClassDescriptor,
enumEntryDescriptor.annotations,
Modality.FINAL,
Visibilities.PUBLIC,
Opcodes.ACC_ENUM,
enumEntryDescriptor.source
)
}
override fun getFieldForObjectInstance(singleton: IrClass): IrField =
singletonFieldDeclarations.getOrPut(singleton) {
val symbol = IrFieldSymbolImpl(createObjectInstanceFieldDescriptor(singleton.descriptor))
return IrFieldImpl(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE,
symbol,
singleton.defaultType
)
val isNotMappedCompanion = singleton.isCompanion && !isMappedIntrinsicCompanionObject(singleton.descriptor)
buildField {
name = if (isNotMappedCompanion) singleton.name else Name.identifier(JvmAbi.INSTANCE_FIELD)
type = singleton.defaultType
origin = IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE
isFinal = true
isStatic = true
}.apply {
parent = if (isNotMappedCompanion) singleton.parent else singleton
}
}
private fun createObjectInstanceFieldDescriptor(objectDescriptor: ClassDescriptor): PropertyDescriptor {
assert(objectDescriptor.kind == ClassKind.OBJECT) { "Should be an object: $objectDescriptor" }
val isNotMappedCompanion = objectDescriptor.isCompanionObject && !isMappedIntrinsicCompanionObject(objectDescriptor)
val name = if (isNotMappedCompanion) objectDescriptor.name else Name.identifier("INSTANCE")
val containingDeclaration = if (isNotMappedCompanion) objectDescriptor.containingDeclaration else objectDescriptor
return PropertyDescriptorImpl.create(
containingDeclaration,
Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, false,
name,
CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false,
/* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false, /* isDelegated = */ false
).initialize(objectDescriptor.defaultType)
}
fun getDefaultImplsFunction(interfaceFun: IrSimpleFunction): IrSimpleFunction {
val parent = interfaceFun.parentAsClass
assert(parent.isInterface) { "Parent of ${interfaceFun.dump()} should be interface" }
@@ -1,119 +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.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
interface JvmDescriptorWithExtraFlags {
val extraFlags: Int
}
class JvmPropertyDescriptorImpl private constructor(
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,
isExpect: Boolean,
isActual: Boolean
) : JvmDescriptorWithExtraFlags, PropertyDescriptorImpl(
containingDeclaration, original, annotations, modality, visibility, isVar,
name, kind, source, isLateInit, isConst, isExpect, isActual, /* isExternal = */ false, false
) {
override fun createSubstitutedCopy(
newOwner: DeclarationDescriptor,
newModality: Modality,
newVisibility: Visibility,
original: PropertyDescriptor?,
kind: CallableMemberDescriptor.Kind,
newName: Name
): PropertyDescriptorImpl =
JvmPropertyDescriptorImpl(
newOwner, original, annotations, newModality, newVisibility, extraFlags, isVar, newName, kind,
SourceElement.NO_SOURCE, isLateInit, isConst, isExpect, isActual
)
companion object {
fun createStaticVal(
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, false, false
).initialize(type)
fun createFinalField(
name: Name,
type: KotlinType,
classDescriptor: ClassDescriptor,
annotations: Annotations,
visibility: Visibility,
extraFlags: Int,
source: SourceElement
): PropertyDescriptorImpl =
JvmPropertyDescriptorImpl(
classDescriptor, null, annotations, Modality.FINAL, visibility, extraFlags, false, name,
CallableMemberDescriptor.Kind.SYNTHESIZED, source, false, false, false, false
).initialize(type, dispatchReceiverParameter = classDescriptor.thisAsReceiverParameter)
}
}
class JvmFunctionDescriptorImpl(
containingDeclaration: DeclarationDescriptor,
original: FunctionDescriptor?,
annotations: Annotations,
name: Name,
kind: CallableMemberDescriptor.Kind,
source: SourceElement,
override val extraFlags: Int
) : JvmDescriptorWithExtraFlags, FunctionDescriptorImpl(
containingDeclaration, original, annotations,
name, kind, source
) {
override fun createSubstitutedCopy(
newOwner: DeclarationDescriptor,
original: FunctionDescriptor?,
kind: CallableMemberDescriptor.Kind,
newName: Name?,
annotations: Annotations,
source: SourceElement
): FunctionDescriptorImpl {
return JvmFunctionDescriptorImpl(
newOwner, original, annotations, name, kind,
SourceElement.NO_SOURCE, extraFlags
)
}
}
@@ -1,51 +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.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
fun PropertyDescriptorImpl.initialize(
type: KotlinType,
typeParameters: List<TypeParameterDescriptor> = emptyList(),
dispatchReceiverParameter: ReceiverParameterDescriptor? = null,
extensionReceiverParameter: ReceiverParameterDescriptor? = null,
getter: PropertyGetterDescriptorImpl? = null,
setter: PropertySetterDescriptorImpl? = null,
backingField: FieldDescriptor? = null,
delegateField: FieldDescriptor? = null
): PropertyDescriptorImpl {
setType(type, typeParameters, dispatchReceiverParameter, extensionReceiverParameter)
initialize(getter, setter, backingField, delegateField)
return this
}
fun CallableMemberDescriptor.createValueParameter(index: Int, name: String, type: KotlinType): ValueParameterDescriptor =
ValueParameterDescriptorImpl(
this, null,
index,
Annotations.EMPTY,
Name.identifier(name),
type,
false, false, false, null, SourceElement.NO_SOURCE
)
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
enum class MyClass() {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
class Foo {
enum class MyClass() {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
private enum class MyClass() {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// NO_FLAGS because we put enum in companion object of foo. When it will be fixed - MyClass should have ACC_PRIVATE flag
class Foo {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
public enum class MyClass() {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
class Foo {
public enum class MyClass() {
}