Initial lazy ir implementation
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.util.transform
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
|
||||
class IrLazyClass(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val symbol: IrClassSymbol,
|
||||
override val name: Name,
|
||||
override val kind: ClassKind,
|
||||
override val visibility: Visibility,
|
||||
override val modality: Modality,
|
||||
override val isCompanion: Boolean,
|
||||
override val isInner: Boolean,
|
||||
override val isData: Boolean,
|
||||
override val isExternal: Boolean,
|
||||
stubGenerator: DeclarationStubGenerator,
|
||||
typeTranslator: TypeTranslator
|
||||
) :
|
||||
IrLazyDeclarationBase(startOffset, endOffset, origin, stubGenerator, typeTranslator),
|
||||
IrClass {
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrClassSymbol,
|
||||
stubGenerator: DeclarationStubGenerator,
|
||||
TypeTranslator: TypeTranslator
|
||||
) :
|
||||
this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name, symbol.descriptor.kind,
|
||||
symbol.descriptor.visibility, symbol.descriptor.modality,
|
||||
isCompanion = symbol.descriptor.isCompanionObject,
|
||||
isInner = symbol.descriptor.isInner,
|
||||
isData = symbol.descriptor.isData,
|
||||
isExternal = symbol.descriptor.isEffectivelyExternal(),
|
||||
stubGenerator = stubGenerator,
|
||||
typeTranslator = TypeTranslator
|
||||
)
|
||||
|
||||
init {
|
||||
symbol.bind(this)
|
||||
}
|
||||
|
||||
override val annotations: MutableList<IrCall> = arrayListOf()
|
||||
|
||||
override val descriptor: ClassDescriptor get() = symbol.descriptor
|
||||
|
||||
override var thisReceiver: IrValueParameter? by lazyVar {
|
||||
typeTranslator.buildWithScope(this) {
|
||||
descriptor.thisAsReceiverParameter.generateReceiverParameterStub()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override val declarations: MutableList<IrDeclaration> by lazyVar {
|
||||
ArrayList<IrDeclaration>().also {
|
||||
typeTranslator.buildWithScope(this) {
|
||||
generateChildStubs(descriptor.constructors, it)
|
||||
generateMemberStubs(descriptor.defaultType.memberScope, it)
|
||||
generateMemberStubs(descriptor.staticScope, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val typeParameters: MutableList<IrTypeParameter> by lazy {
|
||||
descriptor.declaredTypeParameters.mapTo(arrayListOf()) {
|
||||
stubGenerator.generateOrGetTypeParameterStub(it)
|
||||
}
|
||||
}
|
||||
|
||||
override val superTypes: MutableList<IrType> by lazy {
|
||||
typeTranslator.buildWithScope(this) {
|
||||
// TODO get rid of code duplication, see ClassGenerator#generateClass
|
||||
descriptor.typeConstructor.supertypes.mapNotNullTo(arrayListOf()) {
|
||||
it.toIrType()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitClass(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
thisReceiver?.accept(visitor, data)
|
||||
typeParameters.forEach { it.accept(visitor, data) }
|
||||
declarations.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
thisReceiver = thisReceiver?.transform(transformer, data)
|
||||
typeParameters.transform { it.transform(transformer, data) }
|
||||
declarations.transform { it.transform(transformer, data) }
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
|
||||
class IrLazyConstructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val symbol: IrConstructorSymbol,
|
||||
name: Name,
|
||||
visibility: Visibility,
|
||||
isInline: Boolean,
|
||||
isExternal: Boolean,
|
||||
override val isPrimary: Boolean,
|
||||
stubGenerator: DeclarationStubGenerator,
|
||||
typeTranslator: TypeTranslator
|
||||
) :
|
||||
IrLazyFunctionBase(
|
||||
startOffset, endOffset, origin, name,
|
||||
visibility, isInline, isExternal,
|
||||
stubGenerator, typeTranslator
|
||||
),
|
||||
IrConstructor {
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrConstructorSymbol,
|
||||
stubGenerator: DeclarationStubGenerator,
|
||||
TypeTranslator: TypeTranslator
|
||||
) : this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name,
|
||||
symbol.descriptor.visibility,
|
||||
symbol.descriptor.isInline,
|
||||
symbol.descriptor.isEffectivelyExternal(),
|
||||
symbol.descriptor.isPrimary,
|
||||
stubGenerator,
|
||||
TypeTranslator
|
||||
)
|
||||
|
||||
override val typeParameters: MutableList<IrTypeParameter> = arrayListOf()
|
||||
|
||||
init {
|
||||
symbol.bind(this)
|
||||
}
|
||||
|
||||
override val descriptor: ClassConstructorDescriptor get() = symbol.descriptor
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitConstructor(this, data)
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrElementBase
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
abstract class IrLazyDeclarationBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
override val origin: IrDeclarationOrigin,
|
||||
private val stubGenerator: DeclarationStubGenerator,
|
||||
protected val typeTranslator: TypeTranslator
|
||||
) : IrElementBase(startOffset, endOffset), IrDeclaration {
|
||||
|
||||
protected fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
protected fun ReceiverParameterDescriptor.generateReceiverParameterStub(): IrValueParameter =
|
||||
IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, this,
|
||||
type.toIrType(), null
|
||||
)
|
||||
|
||||
protected fun generateMemberStubs(memberScope: MemberScope, container: MutableList<IrDeclaration>) {
|
||||
generateChildStubs(memberScope.getContributedDescriptors(), container)
|
||||
}
|
||||
|
||||
protected fun generateChildStubs(descriptors: Collection<DeclarationDescriptor>, declarations: MutableList<IrDeclaration>) {
|
||||
descriptors.mapTo(declarations) { generateMemberStub(it) }
|
||||
}
|
||||
|
||||
private fun generateMemberStub(descriptor: DeclarationDescriptor): IrDeclaration =
|
||||
stubGenerator.generateMemberStub(descriptor)
|
||||
|
||||
override var parent: IrDeclarationParent by lazyVar {
|
||||
createLazyParent()!!
|
||||
}
|
||||
|
||||
override val annotations: MutableList<IrCall> = arrayListOf()
|
||||
|
||||
private fun createLazyParent(): IrDeclarationParent? {
|
||||
val currentDescriptor = descriptor
|
||||
val containingDeclaration = currentDescriptor.containingDeclaration
|
||||
return when (containingDeclaration) {
|
||||
is PackageFragmentDescriptor -> stubGenerator.generateOrGetEmptyExternalPackageFragmentStub(containingDeclaration).also {
|
||||
it.declarations.add(this)
|
||||
}
|
||||
is ClassDescriptor -> stubGenerator.generateClassStub(containingDeclaration)
|
||||
is FunctionDescriptor -> stubGenerator.generateFunctionStub(containingDeclaration)
|
||||
else -> throw AssertionError("Package or class expected: $containingDeclaration; for $currentDescriptor")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal fun <T> lazyVar(initializer: () -> T): UnsafeLazyVar<T> = UnsafeLazyVar(initializer)
|
||||
|
||||
|
||||
internal class UnsafeLazyVar<T>(initializer: () -> T) {
|
||||
private var isInitialized = false;
|
||||
private var initializer: (() -> T)? = initializer
|
||||
private var _value: Any? = null
|
||||
|
||||
private val value: T
|
||||
get() {
|
||||
if (!isInitialized) {
|
||||
_value = initializer!!()
|
||||
isInitialized = true
|
||||
initializer = null
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return _value as T
|
||||
}
|
||||
|
||||
override fun toString(): String = if (isInitialized) value.toString() else "Lazy value not initialized yet."
|
||||
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value
|
||||
|
||||
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||
this._value = value
|
||||
isInitialized = true
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.declarations.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class IrLazyEnumEntryImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val symbol: IrEnumEntrySymbol,
|
||||
stubGenerator: DeclarationStubGenerator,
|
||||
typeTranslator: TypeTranslator
|
||||
) : IrLazyDeclarationBase(startOffset, endOffset, origin, stubGenerator, typeTranslator),
|
||||
IrEnumEntry {
|
||||
|
||||
init {
|
||||
symbol.bind(this)
|
||||
}
|
||||
|
||||
override val descriptor: ClassDescriptor get() = symbol.descriptor
|
||||
override val name: Name = symbol.descriptor.name
|
||||
|
||||
override var correspondingClass: IrClass? = null
|
||||
|
||||
override var initializerExpression: IrExpression? = null
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitEnumEntry(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
initializerExpression?.accept(visitor, data)
|
||||
correspondingClass?.accept(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
initializerExpression = initializerExpression?.transform(transformer, data)
|
||||
correspondingClass = correspondingClass?.transform(transformer, data) as? IrClass
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
|
||||
|
||||
class IrLazyFunction(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val symbol: IrSimpleFunctionSymbol,
|
||||
name: Name,
|
||||
visibility: Visibility,
|
||||
override val modality: Modality,
|
||||
isInline: Boolean,
|
||||
isExternal: Boolean,
|
||||
override val isTailrec: Boolean,
|
||||
override val isSuspend: Boolean,
|
||||
stubGenerator: DeclarationStubGenerator,
|
||||
typeTranslator: TypeTranslator
|
||||
) :
|
||||
IrLazyFunctionBase(startOffset, endOffset, origin, name, visibility, isInline, isExternal, stubGenerator, typeTranslator),
|
||||
IrSimpleFunction {
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrSimpleFunctionSymbol,
|
||||
stubGenerator: DeclarationStubGenerator,
|
||||
TypeTranslator: TypeTranslator
|
||||
) : this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name,
|
||||
symbol.descriptor.visibility,
|
||||
symbol.descriptor.modality,
|
||||
symbol.descriptor.isInline,
|
||||
symbol.descriptor.isExternal,
|
||||
symbol.descriptor.isTailrec,
|
||||
symbol.descriptor.isSuspend,
|
||||
stubGenerator,
|
||||
TypeTranslator
|
||||
)
|
||||
|
||||
override val descriptor: FunctionDescriptor = symbol.descriptor
|
||||
|
||||
override val typeParameters: MutableList<IrTypeParameter> by lazy {
|
||||
typeTranslator.buildWithScope(this) {
|
||||
stubGenerator.symbolTable.enterScope(descriptor)
|
||||
val propertyIfAccessor = descriptor.propertyIfAccessor
|
||||
propertyIfAccessor.typeParameters.mapTo(arrayListOf()) {
|
||||
if (descriptor != propertyIfAccessor) {
|
||||
stubGenerator.generateOrGetScopedTypeParameterStub(it).also {
|
||||
it.parent = this@IrLazyFunction
|
||||
}
|
||||
} else {
|
||||
stubGenerator.generateOrGetTypeParameterStub(it)
|
||||
}
|
||||
}.also {
|
||||
stubGenerator.symbolTable.leaveScope(descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override val overriddenSymbols: MutableList<IrSimpleFunctionSymbol> by lazy {
|
||||
descriptor.overriddenDescriptors.mapTo(arrayListOf()) {
|
||||
stubGenerator.generateFunctionStub(it.original).symbol
|
||||
}
|
||||
}
|
||||
|
||||
override var correspondingProperty: IrProperty? = null
|
||||
|
||||
init {
|
||||
symbol.bind(this)
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitSimpleFunction(this, data)
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.util.transform
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
|
||||
|
||||
abstract class IrLazyFunctionBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val name: Name,
|
||||
override val visibility: Visibility,
|
||||
override val isInline: Boolean,
|
||||
override val isExternal: Boolean,
|
||||
stubGenerator: DeclarationStubGenerator,
|
||||
typeTranslator: TypeTranslator
|
||||
) :
|
||||
IrLazyDeclarationBase(startOffset, endOffset, origin, stubGenerator, typeTranslator),
|
||||
IrFunction {
|
||||
|
||||
override var dispatchReceiverParameter: IrValueParameter? by lazyVar {
|
||||
typeTranslator.buildWithScope(this) {
|
||||
descriptor.dispatchReceiverParameter?.generateReceiverParameterStub()
|
||||
}
|
||||
}
|
||||
override var extensionReceiverParameter: IrValueParameter? by lazyVar {
|
||||
typeTranslator.buildWithScope(this) {
|
||||
descriptor.extensionReceiverParameter?.generateReceiverParameterStub()
|
||||
}
|
||||
}
|
||||
|
||||
override val valueParameters: MutableList<IrValueParameter> by lazy {
|
||||
typeTranslator.buildWithScope(this) {
|
||||
descriptor.valueParameters.mapTo(arrayListOf()) { stubGenerator.generateValueParameterStub(it) }
|
||||
}
|
||||
}
|
||||
|
||||
final override var body: IrBody? = null
|
||||
|
||||
final override var returnType: IrType by lazyVar {
|
||||
typeTranslator.buildWithScope(this) {
|
||||
descriptor.returnType!!.toIrType()
|
||||
}
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
typeParameters.forEach { it.accept(visitor, data) }
|
||||
|
||||
dispatchReceiverParameter?.accept(visitor, data)
|
||||
extensionReceiverParameter?.accept(visitor, data)
|
||||
valueParameters.forEach { it.accept(visitor, data) }
|
||||
|
||||
body?.accept(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
typeParameters.transform { it.transform(transformer, data) }
|
||||
|
||||
dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data)
|
||||
extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data)
|
||||
valueParameters.transform { it.transform(transformer, data) }
|
||||
|
||||
body = body?.transform(transformer, data)
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
|
||||
|
||||
class IrLazySymbolTable(private val stubGenerator: DeclarationStubGenerator, val originalTable: SymbolTable) : SymbolTable() {
|
||||
|
||||
/*Don't force builtins class linking before unbound symbols linking: otherwise stdlib compilation will failed*/
|
||||
internal var unboundSymbolGeneration = false
|
||||
|
||||
override fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol {
|
||||
return originalTable.referenceClass(descriptor).also {
|
||||
if (unboundSymbolGeneration && !it.isBound) {
|
||||
stubGenerator.generateClassStub(descriptor).symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol {
|
||||
return originalTable.referenceConstructor(descriptor).also {
|
||||
if (!it.isBound && unboundSymbolGeneration) {
|
||||
stubGenerator.generateConstructorStub(descriptor).symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol {
|
||||
return originalTable.referenceEnumEntry(descriptor).also {
|
||||
if (!it.isBound && unboundSymbolGeneration) {
|
||||
stubGenerator.generateEnumEntryStub(descriptor).symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol {
|
||||
return originalTable.referenceSimpleFunction(descriptor).also {
|
||||
if (!it.isBound && unboundSymbolGeneration) {
|
||||
stubGenerator.generateFunctionStub(descriptor).symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol {
|
||||
return originalTable.referenceTypeParameter(classifier).also {
|
||||
if (!it.isBound && unboundSymbolGeneration) {
|
||||
stubGenerator.generateOrGetTypeParameterStub(classifier).symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
class IrLazyTypeParameter(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val symbol: IrTypeParameterSymbol,
|
||||
override val name: Name,
|
||||
override val index: Int,
|
||||
override val variance: Variance,
|
||||
stubGenerator: DeclarationStubGenerator,
|
||||
typeTranslator: TypeTranslator
|
||||
) :
|
||||
IrLazyDeclarationBase(startOffset, endOffset, origin, stubGenerator, typeTranslator),
|
||||
IrTypeParameter {
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrTypeParameterSymbol,
|
||||
stubGenerator: DeclarationStubGenerator,
|
||||
TypeTranslator: TypeTranslator
|
||||
) :
|
||||
this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name,
|
||||
symbol.descriptor.index,
|
||||
symbol.descriptor.variance,
|
||||
stubGenerator, TypeTranslator
|
||||
)
|
||||
|
||||
override val descriptor: TypeParameterDescriptor get() = symbol.descriptor
|
||||
|
||||
init {
|
||||
symbol.bind(this)
|
||||
}
|
||||
|
||||
override val superTypes: MutableList<IrType> by lazy {
|
||||
typeTranslator.buildWithScope(this.parent as IrTypeParametersContainer) {
|
||||
val descriptor = symbol.descriptor
|
||||
descriptor.upperBounds.mapTo(arrayListOf()) { it.toIrType() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitTypeParameter(this, data)
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrTypeParameter =
|
||||
transformer.visitTypeParameter(this, data) as IrTypeParameter
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
// no children
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
// no children
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import java.util.*
|
||||
|
||||
class LazyScopedTypeParametersResolver() : TypeParametersResolver {
|
||||
|
||||
private val typeParameterScopes = ArrayDeque<IrTypeParametersContainer>()
|
||||
|
||||
override fun enterTypeParameterScope(typeParametersContainer: IrTypeParametersContainer) {
|
||||
typeParameterScopes.addFirst(
|
||||
typeParametersContainer
|
||||
)
|
||||
}
|
||||
|
||||
override fun leaveTypeParameterScope() {
|
||||
typeParameterScopes.removeFirst()
|
||||
}
|
||||
|
||||
//TODO optimize
|
||||
override fun resolveScopedTypeParameter(typeParameterDescriptor: TypeParameterDescriptor): IrTypeParameterSymbol? {
|
||||
var parent = typeParameterScopes.first()
|
||||
while (parent != null) {
|
||||
val declaration = parent
|
||||
val symbol = declaration.typeParameters.firstOrNull {
|
||||
it.descriptor == typeParameterDescriptor
|
||||
}?.symbol
|
||||
if (symbol != null) return symbol
|
||||
parent = calcParent(parent)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun calcParent(container: IrTypeParametersContainer): IrTypeParametersContainer? {
|
||||
return when(container) {
|
||||
is IrClass -> if (container.isObject || !container.isInner) null else container.parent
|
||||
else -> (container as? IrDeclaration)?.parent
|
||||
} as? IrTypeParametersContainer
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,14 +22,13 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class DeclarationStubGenerator(
|
||||
@@ -38,8 +37,15 @@ class DeclarationStubGenerator(
|
||||
val origin: IrDeclarationOrigin,
|
||||
val languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
private val typeTranslator = TypeTranslator(symbolTable, languageVersionSettings)
|
||||
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable)
|
||||
private val lazyTable = IrLazySymbolTable(this, symbolTable)
|
||||
|
||||
internal var unboundSymbolGeneration: Boolean
|
||||
get() = lazyTable.unboundSymbolGeneration
|
||||
set(value) { lazyTable.unboundSymbolGeneration = value }
|
||||
|
||||
|
||||
private val typeTranslator = TypeTranslator(lazyTable, languageVersionSettings, LazyScopedTypeParametersResolver())
|
||||
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, lazyTable)
|
||||
|
||||
init {
|
||||
typeTranslator.constantValueGenerator = constantValueGenerator
|
||||
@@ -49,8 +55,9 @@ class DeclarationStubGenerator(
|
||||
fun generateEmptyModuleFragmentStub(descriptor: ModuleDescriptor, irBuiltIns: IrBuiltIns): IrModuleFragment =
|
||||
IrModuleFragmentImpl(descriptor, irBuiltIns)
|
||||
|
||||
fun generateEmptyExternalPackageFragmentStub(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment =
|
||||
symbolTable.declareExternalPackageFragment(descriptor)
|
||||
fun generateOrGetEmptyExternalPackageFragmentStub(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment {
|
||||
return symbolTable.declareExternalPackageFragment(descriptor)
|
||||
}
|
||||
|
||||
fun generateMemberStub(descriptor: DeclarationDescriptor): IrDeclaration =
|
||||
when (descriptor) {
|
||||
@@ -69,7 +76,7 @@ class DeclarationStubGenerator(
|
||||
throw AssertionError("Unexpected member descriptor: $descriptor")
|
||||
}
|
||||
|
||||
private fun generatePropertyStub(descriptor: PropertyDescriptor): IrProperty =
|
||||
internal fun generatePropertyStub(descriptor: PropertyDescriptor): IrProperty =
|
||||
IrPropertyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor).also { irProperty ->
|
||||
val getterDescriptor = descriptor.getter
|
||||
if (getterDescriptor == null) {
|
||||
@@ -88,8 +95,13 @@ class DeclarationStubGenerator(
|
||||
irProperty.setter = descriptor.setter?.let { generateFunctionStub(it) }
|
||||
}
|
||||
|
||||
fun generateFunctionStub(descriptor: FunctionDescriptor): IrSimpleFunction =
|
||||
symbolTable.declareSimpleFunctionWithOverrides(
|
||||
fun generateFunctionStub(descriptor: FunctionDescriptor): IrSimpleFunction {
|
||||
val referenced = symbolTable.referenceSimpleFunction(descriptor)
|
||||
if (referenced.isBound) {
|
||||
return referenced.owner
|
||||
}
|
||||
|
||||
return symbolTable.declareSimpleFunction(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
if (descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
IrDeclarationOrigin.FAKE_OVERRIDE
|
||||
@@ -97,41 +109,24 @@ class DeclarationStubGenerator(
|
||||
origin
|
||||
},
|
||||
descriptor.original
|
||||
).also { irFunction ->
|
||||
generateTypeParameterStubs(descriptor.propertyIfAccessor.typeParameters, irFunction)
|
||||
) { IrLazyFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator) }
|
||||
}
|
||||
|
||||
typeTranslator.buildWithScope(irFunction) {
|
||||
irFunction.returnType = descriptor.returnType!!.toIrType()
|
||||
generateValueParametersStubs(irFunction)
|
||||
}
|
||||
internal fun generateConstructorStub(descriptor: ClassConstructorDescriptor): IrConstructor {
|
||||
val referenced = symbolTable.referenceConstructor(descriptor)
|
||||
if (referenced.isBound) {
|
||||
return referenced.owner
|
||||
}
|
||||
|
||||
private fun generateConstructorStub(descriptor: ClassConstructorDescriptor): IrConstructor =
|
||||
symbolTable.declareConstructor(
|
||||
return symbolTable.declareConstructor(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original
|
||||
).also { irConstructor ->
|
||||
// So far, constructors in Kotlin can't have type parameters of their own.
|
||||
irConstructor.returnType = descriptor.returnType.toIrType()
|
||||
generateValueParametersStubs(irConstructor)
|
||||
}
|
||||
|
||||
private fun generateValueParametersStubs(function: IrFunction) {
|
||||
val descriptor = function.descriptor
|
||||
function.dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.generateReceiverParameterStub()
|
||||
function.extensionReceiverParameter = descriptor.extensionReceiverParameter?.generateReceiverParameterStub()
|
||||
descriptor.valueParameters.mapTo(function.valueParameters) { generateValueParameterStub(it) }
|
||||
) { IrLazyConstructor(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator) }
|
||||
}
|
||||
|
||||
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
private fun ReceiverParameterDescriptor.generateReceiverParameterStub(): IrValueParameter =
|
||||
IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, this,
|
||||
type.toIrType(), null
|
||||
)
|
||||
|
||||
private fun generateValueParameterStub(descriptor: ValueParameterDescriptor): IrValueParameter =
|
||||
IrValueParameterImpl(
|
||||
internal fun generateValueParameterStub(descriptor: ValueParameterDescriptor): IrValueParameter {
|
||||
return IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin,
|
||||
descriptor, descriptor.type.toIrType(), descriptor.varargElementType?.toIrType()
|
||||
).also { irValueParameter ->
|
||||
@@ -145,49 +140,32 @@ class DeclarationStubGenerator(
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateClassStub(descriptor: ClassDescriptor): IrClass =
|
||||
symbolTable.declareClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor).also { irClass ->
|
||||
generateTypeParameterStubs(descriptor.declaredTypeParameters, irClass)
|
||||
|
||||
typeTranslator.buildWithScope(irClass) {
|
||||
// TODO get rid of code duplication, see ClassGenerator#generateClass
|
||||
descriptor.typeConstructor.supertypes.mapNotNullTo(irClass.superTypes) {
|
||||
it.toIrType()
|
||||
}
|
||||
|
||||
irClass.thisReceiver = descriptor.thisAsReceiverParameter.generateReceiverParameterStub()
|
||||
generateChildStubs(descriptor.constructors, irClass)
|
||||
generateMemberStubs(descriptor.defaultType.memberScope, irClass)
|
||||
generateMemberStubs(descriptor.staticScope, irClass)
|
||||
}
|
||||
internal fun generateClassStub(descriptor: ClassDescriptor): IrClass {
|
||||
val referenceClass = symbolTable.referenceClass(descriptor)
|
||||
if (referenceClass.isBound) {
|
||||
return referenceClass.owner
|
||||
}
|
||||
return symbolTable.declareClass(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor
|
||||
) { IrLazyClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator) }
|
||||
}
|
||||
|
||||
private fun generateEnumEntryStub(descriptor: ClassDescriptor): IrEnumEntry =
|
||||
symbolTable.declareEnumEntry(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor)
|
||||
|
||||
private fun generateTypeParameterStubs(typeParameters: List<TypeParameterDescriptor>, container: IrTypeParametersContainer) {
|
||||
typeParameters.mapTo(container.typeParameters) { generateTypeParameterStub(it) }
|
||||
|
||||
typeTranslator.buildWithScope(container) {
|
||||
for (typeParameter in container.typeParameters) {
|
||||
val descriptor = typeParameter.descriptor
|
||||
descriptor.upperBounds.mapTo(typeParameter.superTypes) { it.toIrType() }
|
||||
}
|
||||
internal fun generateEnumEntryStub(descriptor: ClassDescriptor): IrEnumEntry {
|
||||
val referenced = symbolTable.referenceEnumEntry(descriptor)
|
||||
if (referenced.isBound) {
|
||||
return referenced.owner
|
||||
}
|
||||
return symbolTable.declareEnumEntry(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
|
||||
IrLazyEnumEntryImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateTypeParameterStub(descriptor: TypeParameterDescriptor): IrTypeParameter =
|
||||
IrTypeParameterImpl(
|
||||
internal fun generateTypeParameterStub(descriptor: TypeParameterDescriptor): IrTypeParameter {
|
||||
return IrLazyTypeParameter(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin,
|
||||
descriptor
|
||||
IrTypeParameterSymbolImpl(descriptor), this, typeTranslator
|
||||
)
|
||||
|
||||
private fun generateMemberStubs(memberScope: MemberScope, container: IrDeclarationContainer) {
|
||||
generateChildStubs(memberScope.getContributedDescriptors(), container)
|
||||
}
|
||||
|
||||
private fun generateChildStubs(descriptors: Collection<DeclarationDescriptor>, container: IrDeclarationContainer) {
|
||||
descriptors.mapTo(container.declarations) { generateMemberStub(it) }
|
||||
}
|
||||
}
|
||||
+26
-9
@@ -43,15 +43,32 @@ class ExternalDependenciesGenerator(
|
||||
private val packageFragments = HashMap<PackageFragmentDescriptor, IrExternalPackageFragment>()
|
||||
|
||||
fun run() {
|
||||
while (true) {
|
||||
val collector = DependenciesCollector()
|
||||
collector.collectTopLevelDescriptorsForUnboundSymbols(symbolTable)
|
||||
if (collector.isEmpty) break
|
||||
|
||||
collector.dependencyModules.mapTo(irModule.dependencyModules) { moduleDescriptor ->
|
||||
generateModuleStub(collector, moduleDescriptor)
|
||||
}
|
||||
stubGenerator.unboundSymbolGeneration = true
|
||||
ArrayList(symbolTable.unboundClasses).forEach {
|
||||
stubGenerator.generateClassStub(it.descriptor)
|
||||
}
|
||||
ArrayList(symbolTable.unboundConstructors).forEach {
|
||||
stubGenerator.generateConstructorStub(it.descriptor)
|
||||
}
|
||||
ArrayList(symbolTable.unboundEnumEntries).forEach {
|
||||
stubGenerator.generateEnumEntryStub(it.descriptor)
|
||||
}
|
||||
ArrayList(symbolTable.unboundFields).forEach {
|
||||
stubGenerator.generatePropertyStub(it.descriptor)
|
||||
}
|
||||
ArrayList(symbolTable.unboundSimpleFunctions).forEach {
|
||||
stubGenerator.generateFunctionStub(it.descriptor)
|
||||
}
|
||||
ArrayList(symbolTable.unboundTypeParameters).forEach {
|
||||
stubGenerator.generateOrGetTypeParameterStub(it.descriptor)
|
||||
}
|
||||
|
||||
assert(symbolTable.unboundClasses.isEmpty())
|
||||
assert(symbolTable.unboundConstructors.isEmpty())
|
||||
assert(symbolTable.unboundEnumEntries.isEmpty())
|
||||
assert(symbolTable.unboundFields.isEmpty())
|
||||
assert(symbolTable.unboundSimpleFunctions.isEmpty())
|
||||
assert(symbolTable.unboundTypeParameters.isEmpty())
|
||||
}
|
||||
|
||||
private fun generateModuleStub(collector: DependenciesCollector, moduleDescriptor: ModuleDescriptor): IrModuleFragment =
|
||||
@@ -80,7 +97,7 @@ class ExternalDependenciesGenerator(
|
||||
|
||||
private fun getOrCreatePackageFragment(packageFragmentDescriptor: PackageFragmentDescriptor) =
|
||||
packageFragments.getOrPut(packageFragmentDescriptor) {
|
||||
stubGenerator.generateEmptyExternalPackageFragmentStub(packageFragmentDescriptor)
|
||||
stubGenerator.generateOrGetEmptyExternalPackageFragmentStub(packageFragmentDescriptor)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-4
@@ -10,11 +10,18 @@ import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import java.util.*
|
||||
|
||||
class ScopedTypeParametersResolver {
|
||||
interface TypeParametersResolver {
|
||||
fun enterTypeParameterScope(typeParametersContainer: IrTypeParametersContainer)
|
||||
fun leaveTypeParameterScope()
|
||||
|
||||
fun resolveScopedTypeParameter(typeParameterDescriptor: TypeParameterDescriptor): IrTypeParameterSymbol?
|
||||
}
|
||||
|
||||
class ScopedTypeParametersResolver : TypeParametersResolver {
|
||||
|
||||
private val typeParameterScopes = ArrayDeque<Map<TypeParameterDescriptor, IrTypeParameterSymbol>>()
|
||||
|
||||
fun enterTypeParameterScope(typeParametersContainer: IrTypeParametersContainer) {
|
||||
override fun enterTypeParameterScope(typeParametersContainer: IrTypeParametersContainer) {
|
||||
typeParameterScopes.addFirst(
|
||||
typeParametersContainer.typeParameters.associate {
|
||||
it.descriptor to it.symbol
|
||||
@@ -22,11 +29,11 @@ class ScopedTypeParametersResolver {
|
||||
)
|
||||
}
|
||||
|
||||
fun leaveTypeParameterScope() {
|
||||
override fun leaveTypeParameterScope() {
|
||||
typeParameterScopes.removeFirst()
|
||||
}
|
||||
|
||||
fun resolveScopedTypeParameter(typeParameterDescriptor: TypeParameterDescriptor): IrTypeParameterSymbol? {
|
||||
override fun resolveScopedTypeParameter(typeParameterDescriptor: TypeParameterDescriptor): IrTypeParameterSymbol? {
|
||||
for (scope in typeParameterScopes) {
|
||||
val local = scope[typeParameterDescriptor]
|
||||
if (local != null) return local
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
|
||||
class SymbolTable {
|
||||
open class SymbolTable {
|
||||
private abstract class SymbolTableBase<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>> {
|
||||
val unboundSymbols = linkedSetOf<S>()
|
||||
|
||||
@@ -174,14 +174,17 @@ class SymbolTable {
|
||||
IrAnonymousInitializerSymbolImpl(descriptor)
|
||||
)
|
||||
|
||||
fun declareClass(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor): IrClass =
|
||||
fun declareClass(
|
||||
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
|
||||
classFactory: (IrClassSymbol) -> IrClass = { IrClassImpl(startOffset, endOffset, origin, it) }
|
||||
): IrClass =
|
||||
classSymbolTable.declare(
|
||||
descriptor,
|
||||
{ IrClassSymbolImpl(descriptor) },
|
||||
{ IrClassImpl(startOffset, endOffset, origin, it) }
|
||||
classFactory
|
||||
)
|
||||
|
||||
fun referenceClass(descriptor: ClassDescriptor) =
|
||||
open fun referenceClass(descriptor: ClassDescriptor) =
|
||||
classSymbolTable.referenced(descriptor) { IrClassSymbolImpl(descriptor) }
|
||||
|
||||
val unboundClasses: Set<IrClassSymbol> get() = classSymbolTable.unboundSymbols
|
||||
@@ -190,27 +193,29 @@ class SymbolTable {
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ClassConstructorDescriptor
|
||||
descriptor: ClassConstructorDescriptor,
|
||||
constructorFactory: (IrConstructorSymbol) -> IrConstructor = { IrConstructorImpl(startOffset, endOffset, origin, it) }
|
||||
): IrConstructor =
|
||||
constructorSymbolTable.declare(
|
||||
descriptor,
|
||||
{ IrConstructorSymbolImpl(descriptor) },
|
||||
{ IrConstructorImpl(startOffset, endOffset, origin, it) }
|
||||
constructorFactory
|
||||
)
|
||||
|
||||
fun referenceConstructor(descriptor: ClassConstructorDescriptor) =
|
||||
open fun referenceConstructor(descriptor: ClassConstructorDescriptor) =
|
||||
constructorSymbolTable.referenced(descriptor) { IrConstructorSymbolImpl(descriptor) }
|
||||
|
||||
val unboundConstructors: Set<IrConstructorSymbol> get() = constructorSymbolTable.unboundSymbols
|
||||
|
||||
fun declareEnumEntry(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor): IrEnumEntry =
|
||||
fun declareEnumEntry(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
|
||||
factory: (IrEnumEntrySymbol) -> IrEnumEntry = { IrEnumEntryImpl(startOffset, endOffset, origin, it) }): IrEnumEntry =
|
||||
enumEntrySymbolTable.declare(
|
||||
descriptor,
|
||||
{ IrEnumEntrySymbolImpl(descriptor) },
|
||||
{ IrEnumEntryImpl(startOffset, endOffset, origin, it) }
|
||||
factory
|
||||
)
|
||||
|
||||
fun referenceEnumEntry(descriptor: ClassDescriptor) =
|
||||
open fun referenceEnumEntry(descriptor: ClassDescriptor) =
|
||||
enumEntrySymbolTable.referenced(descriptor) { IrEnumEntrySymbolImpl(descriptor) }
|
||||
|
||||
val unboundEnumEntries: Set<IrEnumEntrySymbol> get() = enumEntrySymbolTable.unboundSymbols
|
||||
@@ -220,12 +225,13 @@ class SymbolTable {
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: PropertyDescriptor,
|
||||
type: IrType
|
||||
type: IrType,
|
||||
fieldFactory: (IrFieldSymbol) -> IrField = { IrFieldImpl(startOffset, endOffset, origin, it, type) }
|
||||
): IrField =
|
||||
fieldSymbolTable.declare(
|
||||
descriptor,
|
||||
{ IrFieldSymbolImpl(descriptor) },
|
||||
{ IrFieldImpl(startOffset, endOffset, origin, it, type) }
|
||||
fieldFactory
|
||||
)
|
||||
|
||||
fun declareField(
|
||||
@@ -249,15 +255,16 @@ class SymbolTable {
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: FunctionDescriptor
|
||||
descriptor: FunctionDescriptor,
|
||||
functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction = { IrFunctionImpl(startOffset, endOffset, origin, it) }
|
||||
): IrSimpleFunction =
|
||||
simpleFunctionSymbolTable.declare(
|
||||
descriptor,
|
||||
{ IrSimpleFunctionSymbolImpl(descriptor) },
|
||||
{ IrFunctionImpl(startOffset, endOffset, origin, it) }
|
||||
functionFactory
|
||||
)
|
||||
|
||||
fun referenceSimpleFunction(descriptor: FunctionDescriptor) =
|
||||
open fun referenceSimpleFunction(descriptor: FunctionDescriptor) =
|
||||
simpleFunctionSymbolTable.referenced(descriptor) { IrSimpleFunctionSymbolImpl(descriptor) }
|
||||
|
||||
fun referenceDeclaredFunction(descriptor: FunctionDescriptor) =
|
||||
@@ -314,7 +321,7 @@ class SymbolTable {
|
||||
throw AssertionError("Undefined parameter referenced: $descriptor\n${valueParameterSymbolTable.dump()}")
|
||||
}
|
||||
|
||||
fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol =
|
||||
open fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol =
|
||||
scopedTypeParameterSymbolTable.get(classifier)
|
||||
?: globalTypeParameterSymbolTable.referenced(classifier) {
|
||||
throw AssertionError("Undefined type parameter referenced: $classifier")
|
||||
@@ -363,9 +370,9 @@ class SymbolTable {
|
||||
fun referenceFunction(callable: CallableDescriptor): IrFunctionSymbol =
|
||||
when (callable) {
|
||||
is ClassConstructorDescriptor ->
|
||||
constructorSymbolTable.referenced(callable) { IrConstructorSymbolImpl(callable) }
|
||||
referenceConstructor(callable)
|
||||
is FunctionDescriptor ->
|
||||
simpleFunctionSymbolTable.referenced(callable) { IrSimpleFunctionSymbolImpl(callable) }
|
||||
referenceSimpleFunction(callable)
|
||||
else ->
|
||||
throw IllegalArgumentException("Unexpected callable descriptor: $callable")
|
||||
}
|
||||
@@ -385,7 +392,7 @@ class SymbolTable {
|
||||
is TypeParameterDescriptor ->
|
||||
referenceTypeParameter(classifier)
|
||||
is ClassDescriptor ->
|
||||
classSymbolTable.referenced(classifier) { IrClassSymbolImpl(classifier) }
|
||||
referenceClass(classifier)
|
||||
else ->
|
||||
throw IllegalArgumentException("Unexpected classifier descriptor: $classifier")
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@ import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes
|
||||
|
||||
class TypeTranslator(
|
||||
private val symbolTable: SymbolTable,
|
||||
val languageVersionSettings: LanguageVersionSettings
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
private val typeParametersResolver: TypeParametersResolver = ScopedTypeParametersResolver()
|
||||
) {
|
||||
|
||||
private val typeParametersResolver = ScopedTypeParametersResolver()
|
||||
private val typeApproximatorForNI = TypeApproximator()
|
||||
lateinit var constantValueGenerator: ConstantValueGenerator
|
||||
|
||||
|
||||
Reference in New Issue
Block a user