Extract ReferenceSymbolTable, support lazy type parameters

This commit is contained in:
Mikhael Bogdanov
2018-07-31 09:09:49 +02:00
parent 6623799671
commit 1bf3f4bda7
9 changed files with 168 additions and 105 deletions
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
import org.jetbrains.kotlin.name.FqName 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
@@ -26,7 +26,7 @@ abstract class Ir<out T : CommonBackendContext>(val context: T, val irModule: Ir
open fun shouldGenerateHandlerParameterForDefaultBodyFun() = false open fun shouldGenerateHandlerParameterForDefaultBodyFun() = false
} }
abstract class Symbols<out T : CommonBackendContext>(val context: T, private val symbolTable: SymbolTable) { abstract class Symbols<out T : CommonBackendContext>(val context: T, private val symbolTable: ReferenceSymbolTable) {
protected val builtIns protected val builtIns
get() = context.builtIns get() = context.builtIns
@@ -31,7 +31,7 @@ class AnnotationGenerator(
generateAnnotationsForDeclaration(declaration) generateAnnotationsForDeclaration(declaration)
visitElement(declaration) visitElement(declaration)
if (declaration is IrTypeParametersContainer) { if (declaration is IrTypeParametersContainer) {
typeTranslator.leaveScope() typeTranslator.leaveScope(declaration)
} }
} }
@@ -16,6 +16,6 @@
package org.jetbrains.kotlin.ir.declarations package org.jetbrains.kotlin.ir.declarations
interface IrTypeParametersContainer { interface IrTypeParametersContainer : IrDeclaration {
val typeParameters: MutableList<IrTypeParameter> val typeParameters: MutableList<IrTypeParameter>
} }
@@ -5,57 +5,66 @@
package org.jetbrains.kotlin.ir.declarations.lazy package org.jetbrains.kotlin.ir.declarations.lazy
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.*
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.symbols.*
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
class IrLazySymbolTable(private val stubGenerator: DeclarationStubGenerator, val originalTable: SymbolTable) : SymbolTable() { class IrLazySymbolTable(private val originalTable: SymbolTable) : ReferenceSymbolTable by originalTable {
override val declarationSystemTable: SymbolTable = originalTable
override val referenceSymbolTable: ReferenceSymbolTable = this
/*Don't force builtins class linking before unbound symbols linking: otherwise stdlib compilation will failed*/ /*Don't force builtins class linking before unbound symbols linking: otherwise stdlib compilation will failed*/
internal var unboundSymbolGeneration = false var stubGenerator: DeclarationStubGenerator? = null
override fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol { override fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol {
return originalTable.referenceClass(descriptor).also { return originalTable.referenceClass(descriptor).also {
if (unboundSymbolGeneration && !it.isBound) { if (!it.isBound) {
stubGenerator.generateClassStub(descriptor).symbol stubGenerator?.generateClassStub(descriptor)
} }
} }
} }
override fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol { override fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol {
return originalTable.referenceConstructor(descriptor).also { return originalTable.referenceConstructor(descriptor).also {
if (!it.isBound && unboundSymbolGeneration) { if (!it.isBound) {
stubGenerator.generateConstructorStub(descriptor).symbol stubGenerator?.generateConstructorStub(descriptor)
} }
} }
} }
override fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol { override fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol {
return originalTable.referenceEnumEntry(descriptor).also { return originalTable.referenceEnumEntry(descriptor).also {
if (!it.isBound && unboundSymbolGeneration) { if (!it.isBound) {
stubGenerator.generateEnumEntryStub(descriptor).symbol stubGenerator?.generateEnumEntryStub(descriptor)
} }
} }
} }
override fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol { override fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol {
return originalTable.referenceSimpleFunction(descriptor).also { return originalTable.referenceSimpleFunction(descriptor).also {
if (!it.isBound && unboundSymbolGeneration) { if (!it.isBound) {
stubGenerator.generateFunctionStub(descriptor).symbol stubGenerator?.generateFunctionStub(descriptor)
} }
} }
} }
override fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol { override fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol {
return originalTable.referenceTypeParameter(classifier).also { return originalTable.referenceTypeParameter(classifier).also {
if (!it.isBound && unboundSymbolGeneration) { if (!it.isBound) {
stubGenerator.generateOrGetTypeParameterStub(classifier).symbol stubGenerator?.generateOrGetTypeParameterStub(classifier)
} }
} }
} }
override fun referenceFunction(callable: CallableDescriptor): IrFunctionSymbol {
return super.referenceFunction(callable)
}
override fun referenceClassifier(classifier: ClassifierDescriptor): IrClassifierSymbol {
return super.referenceClassifier(classifier)
}
} }
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import java.util.* import java.util.*
class LazyScopedTypeParametersResolver() : TypeParametersResolver { class LazyScopedTypeParametersResolver(private val symbolTable: ReferenceSymbolTable) : TypeParametersResolver {
private val typeParameterScopes = ArrayDeque<IrTypeParametersContainer>() private val typeParameterScopes = ArrayDeque<IrTypeParametersContainer>()
@@ -27,25 +27,13 @@ class LazyScopedTypeParametersResolver() : TypeParametersResolver {
typeParameterScopes.removeFirst() typeParameterScopes.removeFirst()
} }
//TODO optimize
override fun resolveScopedTypeParameter(typeParameterDescriptor: TypeParameterDescriptor): IrTypeParameterSymbol? { override fun resolveScopedTypeParameter(typeParameterDescriptor: TypeParameterDescriptor): IrTypeParameterSymbol? {
var parent = typeParameterScopes.first() //Just support accessor scoped symbols resolve in external declaration
while (parent != null) { //there should be enough to process only parent typeparameters
val declaration = parent return typeParameterScopes.firstOrNull()?.let { parent ->
val symbol = declaration.typeParameters.firstOrNull { parent.typeParameters.firstOrNull {
it.descriptor == typeParameterDescriptor it.descriptor == typeParameterDescriptor
}?.symbol }?.symbol
if (symbol != null) return symbol } ?: null
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
}
} }
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class ConstantValueGenerator( class ConstantValueGenerator(
private val moduleDescriptor: ModuleDescriptor, private val moduleDescriptor: ModuleDescriptor,
private val symbolTable: SymbolTable private val symbolTable: ReferenceSymbolTable
) { ) {
lateinit var typeTranslator: TypeTranslator lateinit var typeTranslator: TypeTranslator
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.ir.declarations.lazy.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl 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.DescriptorUtils
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
@@ -37,14 +36,17 @@ class DeclarationStubGenerator(
val origin: IrDeclarationOrigin, val origin: IrDeclarationOrigin,
val languageVersionSettings: LanguageVersionSettings val languageVersionSettings: LanguageVersionSettings
) { ) {
private val lazyTable = IrLazySymbolTable(this, symbolTable)
private val lazyTable = symbolTable.lazyWrapper
internal var unboundSymbolGeneration: Boolean internal var unboundSymbolGeneration: Boolean
get() = lazyTable.unboundSymbolGeneration get() = lazyTable.stubGenerator != null
set(value) { lazyTable.unboundSymbolGeneration = value } set(value) {
lazyTable.stubGenerator = if (value) this else null
}
private val typeTranslator = TypeTranslator(lazyTable, languageVersionSettings, LazyScopedTypeParametersResolver()) private val typeTranslator = TypeTranslator(lazyTable, languageVersionSettings, LazyScopedTypeParametersResolver(lazyTable), true)
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, lazyTable) private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, lazyTable)
init { init {
@@ -101,13 +103,13 @@ class DeclarationStubGenerator(
return referenced.owner return referenced.owner
} }
val origin =
if (descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
IrDeclarationOrigin.FAKE_OVERRIDE
else origin
return symbolTable.declareSimpleFunction( return symbolTable.declareSimpleFunction(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET,
if (descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { origin,
IrDeclarationOrigin.FAKE_OVERRIDE
} else {
origin
},
descriptor.original descriptor.original
) { IrLazyFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator) } ) { IrLazyFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator) }
} }
@@ -162,10 +164,29 @@ class DeclarationStubGenerator(
} }
} }
internal fun generateTypeParameterStub(descriptor: TypeParameterDescriptor): IrTypeParameter { internal fun generateOrGetTypeParameterStub(descriptor: TypeParameterDescriptor): IrTypeParameter {
return IrLazyTypeParameter( val referenced = symbolTable.referenceTypeParameter(descriptor)
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, if (referenced.isBound) {
IrTypeParameterSymbolImpl(descriptor), this, typeTranslator return referenced.owner
) }
return symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
IrLazyTypeParameter(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin,
it, this, typeTranslator
)
}
}
internal fun generateOrGetScopedTypeParameterStub(descriptor: TypeParameterDescriptor): IrTypeParameter {
val referenced = symbolTable.referenceTypeParameter(descriptor)
if (referenced.isBound) {
return referenced.owner
}
return symbolTable.declareScopedTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
IrLazyTypeParameter(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin,
it, this, typeTranslator
)
}
} }
} }
@@ -20,13 +20,65 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.SourceManager import org.jetbrains.kotlin.ir.SourceManager
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.*
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazySymbolTable
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
open class SymbolTable { interface ReferenceSymbolTable {
fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol
fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol
fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol
fun referenceField(descriptor: PropertyDescriptor): IrFieldSymbol
fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol
fun referenceDeclaredFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol
fun referenceValueParameter(descriptor: ParameterDescriptor): IrValueParameterSymbol
fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol
fun referenceVariable(descriptor: VariableDescriptor): IrVariableSymbol
fun referenceFunction(callable: CallableDescriptor): IrFunctionSymbol =
when (callable) {
is ClassConstructorDescriptor ->
referenceConstructor(callable)
is FunctionDescriptor ->
referenceSimpleFunction(callable)
else ->
throw IllegalArgumentException("Unexpected callable descriptor: $callable")
}
fun referenceClassifier(classifier: ClassifierDescriptor): IrClassifierSymbol =
when (classifier) {
is TypeParameterDescriptor ->
referenceTypeParameter(classifier)
is ClassDescriptor ->
referenceClass(classifier)
else ->
throw IllegalArgumentException("Unexpected classifier descriptor: $classifier")
}
val declarationSystemTable: SymbolTable
val referenceSymbolTable: ReferenceSymbolTable
fun enterScope(owner: DeclarationDescriptor)
fun leaveScope(owner: DeclarationDescriptor)
}
open class SymbolTable : ReferenceSymbolTable {
override val declarationSystemTable: SymbolTable = this
override val referenceSymbolTable: ReferenceSymbolTable = IrLazySymbolTable(this)
val lazyWrapper = referenceSymbolTable as IrLazySymbolTable
private abstract class SymbolTableBase<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>> { private abstract class SymbolTableBase<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>> {
val unboundSymbols = linkedSetOf<S>() val unboundSymbols = linkedSetOf<S>()
@@ -102,7 +154,7 @@ open class SymbolTable {
override fun get(d: D): S? { override fun get(d: D): S? {
val scope = currentScope val scope = currentScope
?: throw AssertionError("No active scope") ?: throw AssertionError("No active scope")
return scope[d] return scope[d]
} }
@@ -177,14 +229,15 @@ open class SymbolTable {
fun declareClass( fun declareClass(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
classFactory: (IrClassSymbol) -> IrClass = { IrClassImpl(startOffset, endOffset, origin, it) } classFactory: (IrClassSymbol) -> IrClass = { IrClassImpl(startOffset, endOffset, origin, it) }
): IrClass = ): IrClass {
classSymbolTable.declare( return classSymbolTable.declare(
descriptor, descriptor,
{ IrClassSymbolImpl(descriptor) }, { IrClassSymbolImpl(descriptor) },
classFactory classFactory
) )
}
open fun referenceClass(descriptor: ClassDescriptor) = override fun referenceClass(descriptor: ClassDescriptor) =
classSymbolTable.referenced(descriptor) { IrClassSymbolImpl(descriptor) } classSymbolTable.referenced(descriptor) { IrClassSymbolImpl(descriptor) }
val unboundClasses: Set<IrClassSymbol> get() = classSymbolTable.unboundSymbols val unboundClasses: Set<IrClassSymbol> get() = classSymbolTable.unboundSymbols
@@ -202,20 +255,22 @@ open class SymbolTable {
constructorFactory constructorFactory
) )
open fun referenceConstructor(descriptor: ClassConstructorDescriptor) = override fun referenceConstructor(descriptor: ClassConstructorDescriptor) =
constructorSymbolTable.referenced(descriptor) { IrConstructorSymbolImpl(descriptor) } constructorSymbolTable.referenced(descriptor) { IrConstructorSymbolImpl(descriptor) }
val unboundConstructors: Set<IrConstructorSymbol> get() = constructorSymbolTable.unboundSymbols val unboundConstructors: Set<IrConstructorSymbol> get() = constructorSymbolTable.unboundSymbols
fun declareEnumEntry(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, fun declareEnumEntry(
factory: (IrEnumEntrySymbol) -> IrEnumEntry = { IrEnumEntryImpl(startOffset, endOffset, origin, it) }): IrEnumEntry = startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
factory: (IrEnumEntrySymbol) -> IrEnumEntry = { IrEnumEntryImpl(startOffset, endOffset, origin, it) }
): IrEnumEntry =
enumEntrySymbolTable.declare( enumEntrySymbolTable.declare(
descriptor, descriptor,
{ IrEnumEntrySymbolImpl(descriptor) }, { IrEnumEntrySymbolImpl(descriptor) },
factory factory
) )
open fun referenceEnumEntry(descriptor: ClassDescriptor) = override fun referenceEnumEntry(descriptor: ClassDescriptor) =
enumEntrySymbolTable.referenced(descriptor) { IrEnumEntrySymbolImpl(descriptor) } enumEntrySymbolTable.referenced(descriptor) { IrEnumEntrySymbolImpl(descriptor) }
val unboundEnumEntries: Set<IrEnumEntrySymbol> get() = enumEntrySymbolTable.unboundSymbols val unboundEnumEntries: Set<IrEnumEntrySymbol> get() = enumEntrySymbolTable.unboundSymbols
@@ -246,7 +301,7 @@ open class SymbolTable {
initializer = irInitializer initializer = irInitializer
} }
fun referenceField(descriptor: PropertyDescriptor) = override fun referenceField(descriptor: PropertyDescriptor) =
fieldSymbolTable.referenced(descriptor) { IrFieldSymbolImpl(descriptor) } fieldSymbolTable.referenced(descriptor) { IrFieldSymbolImpl(descriptor) }
val unboundFields: Set<IrFieldSymbol> get() = fieldSymbolTable.unboundSymbols val unboundFields: Set<IrFieldSymbol> get() = fieldSymbolTable.unboundSymbols
@@ -257,17 +312,18 @@ open class SymbolTable {
origin: IrDeclarationOrigin, origin: IrDeclarationOrigin,
descriptor: FunctionDescriptor, descriptor: FunctionDescriptor,
functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction = { IrFunctionImpl(startOffset, endOffset, origin, it) } functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction = { IrFunctionImpl(startOffset, endOffset, origin, it) }
): IrSimpleFunction = ): IrSimpleFunction {
simpleFunctionSymbolTable.declare( return simpleFunctionSymbolTable.declare(
descriptor, descriptor,
{ IrSimpleFunctionSymbolImpl(descriptor) }, { IrSimpleFunctionSymbolImpl(descriptor) },
functionFactory functionFactory
) )
}
open fun referenceSimpleFunction(descriptor: FunctionDescriptor) = override fun referenceSimpleFunction(descriptor: FunctionDescriptor) =
simpleFunctionSymbolTable.referenced(descriptor) { IrSimpleFunctionSymbolImpl(descriptor) } simpleFunctionSymbolTable.referenced(descriptor) { IrSimpleFunctionSymbolImpl(descriptor) }
fun referenceDeclaredFunction(descriptor: FunctionDescriptor) = override fun referenceDeclaredFunction(descriptor: FunctionDescriptor) =
simpleFunctionSymbolTable.referenced(descriptor) { throw AssertionError("Function is not declared: $descriptor") } simpleFunctionSymbolTable.referenced(descriptor) { throw AssertionError("Function is not declared: $descriptor") }
val unboundSimpleFunctions: Set<IrSimpleFunctionSymbol> get() = simpleFunctionSymbolTable.unboundSymbols val unboundSimpleFunctions: Set<IrSimpleFunctionSymbol> get() = simpleFunctionSymbolTable.unboundSymbols
@@ -276,26 +332,29 @@ open class SymbolTable {
startOffset: Int, startOffset: Int,
endOffset: Int, endOffset: Int,
origin: IrDeclarationOrigin, origin: IrDeclarationOrigin,
descriptor: TypeParameterDescriptor descriptor: TypeParameterDescriptor,
typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter = { IrTypeParameterImpl(startOffset, endOffset, origin, it) }
): IrTypeParameter = ): IrTypeParameter =
globalTypeParameterSymbolTable.declare( globalTypeParameterSymbolTable.declare(
descriptor, descriptor,
{ IrTypeParameterSymbolImpl(descriptor) }, { IrTypeParameterSymbolImpl(descriptor) },
{ IrTypeParameterImpl(startOffset, endOffset, origin, it) } typeParameterFactory
) )
fun declareScopedTypeParameter( fun declareScopedTypeParameter(
startOffset: Int, startOffset: Int,
endOffset: Int, endOffset: Int,
origin: IrDeclarationOrigin, origin: IrDeclarationOrigin,
descriptor: TypeParameterDescriptor descriptor: TypeParameterDescriptor,
typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter = { IrTypeParameterImpl(startOffset, endOffset, origin, it) }
): IrTypeParameter = ): IrTypeParameter =
scopedTypeParameterSymbolTable.declare( scopedTypeParameterSymbolTable.declare(
descriptor, descriptor,
{ IrTypeParameterSymbolImpl(descriptor) }, { IrTypeParameterSymbolImpl(descriptor) },
{ IrTypeParameterImpl(startOffset, endOffset, origin, it) } typeParameterFactory
) )
val unboundTypeParameters: Set<IrTypeParameterSymbol> get() = globalTypeParameterSymbolTable.unboundSymbols val unboundTypeParameters: Set<IrTypeParameterSymbol> get() = globalTypeParameterSymbolTable.unboundSymbols
fun declareValueParameter( fun declareValueParameter(
@@ -316,16 +375,15 @@ open class SymbolTable {
valueParameterSymbolTable.introduceLocal(irValueParameter.descriptor, irValueParameter.symbol) valueParameterSymbolTable.introduceLocal(irValueParameter.descriptor, irValueParameter.symbol)
} }
fun referenceValueParameter(descriptor: ParameterDescriptor) = override fun referenceValueParameter(descriptor: ParameterDescriptor) =
valueParameterSymbolTable.referenced(descriptor) { valueParameterSymbolTable.referenced(descriptor) {
throw AssertionError("Undefined parameter referenced: $descriptor\n${valueParameterSymbolTable.dump()}") throw AssertionError("Undefined parameter referenced: $descriptor\n${valueParameterSymbolTable.dump()}")
} }
open fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol = override fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol =
scopedTypeParameterSymbolTable.get(classifier) scopedTypeParameterSymbolTable.get(classifier) ?: globalTypeParameterSymbolTable.referenced(classifier) {
?: globalTypeParameterSymbolTable.referenced(classifier) { IrTypeParameterSymbolImpl(classifier)
throw AssertionError("Undefined type parameter referenced: $classifier") }
}
val unboundValueParameters: Set<IrValueParameterSymbol> get() = valueParameterSymbolTable.unboundSymbols val unboundValueParameters: Set<IrValueParameterSymbol> get() = valueParameterSymbolTable.unboundSymbols
@@ -354,29 +412,19 @@ open class SymbolTable {
initializer = irInitializerExpression initializer = irInitializerExpression
} }
fun referenceVariable(descriptor: VariableDescriptor) = override fun referenceVariable(descriptor: VariableDescriptor) =
variableSymbolTable.referenced(descriptor) { throw AssertionError("Undefined variable referenced: $descriptor") } variableSymbolTable.referenced(descriptor) { throw AssertionError("Undefined variable referenced: $descriptor") }
val unboundVariables: Set<IrVariableSymbol> get() = variableSymbolTable.unboundSymbols val unboundVariables: Set<IrVariableSymbol> get() = variableSymbolTable.unboundSymbols
fun enterScope(owner: DeclarationDescriptor) { override fun enterScope(owner: DeclarationDescriptor) {
scopedSymbolTables.forEach { it.enterScope(owner) } scopedSymbolTables.forEach { it.enterScope(owner) }
} }
fun leaveScope(owner: DeclarationDescriptor) { override fun leaveScope(owner: DeclarationDescriptor) {
scopedSymbolTables.forEach { it.leaveScope(owner) } scopedSymbolTables.forEach { it.leaveScope(owner) }
} }
fun referenceFunction(callable: CallableDescriptor): IrFunctionSymbol =
when (callable) {
is ClassConstructorDescriptor ->
referenceConstructor(callable)
is FunctionDescriptor ->
referenceSimpleFunction(callable)
else ->
throw IllegalArgumentException("Unexpected callable descriptor: $callable")
}
fun referenceValue(value: ValueDescriptor): IrValueSymbol = fun referenceValue(value: ValueDescriptor): IrValueSymbol =
when (value) { when (value) {
is ParameterDescriptor -> is ParameterDescriptor ->
@@ -386,16 +434,6 @@ open class SymbolTable {
else -> else ->
throw IllegalArgumentException("Unexpected value descriptor: $value") throw IllegalArgumentException("Unexpected value descriptor: $value")
} }
fun referenceClassifier(classifier: ClassifierDescriptor): IrClassifierSymbol =
when (classifier) {
is TypeParameterDescriptor ->
referenceTypeParameter(classifier)
is ClassDescriptor ->
referenceClass(classifier)
else ->
throw IllegalArgumentException("Unexpected classifier descriptor: $classifier")
}
} }
inline fun <T> SymbolTable.withScope(owner: DeclarationDescriptor, block: SymbolTable.() -> T): T { inline fun <T> SymbolTable.withScope(owner: DeclarationDescriptor, block: SymbolTable.() -> T): T {
@@ -22,9 +22,10 @@ import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes
class TypeTranslator( class TypeTranslator(
private val symbolTable: SymbolTable, private val symbolTable: ReferenceSymbolTable,
val languageVersionSettings: LanguageVersionSettings, val languageVersionSettings: LanguageVersionSettings,
private val typeParametersResolver: TypeParametersResolver = ScopedTypeParametersResolver() private val typeParametersResolver: TypeParametersResolver = ScopedTypeParametersResolver(),
private val enterTableScope: Boolean = false
) { ) {
private val typeApproximatorForNI = TypeApproximator() private val typeApproximatorForNI = TypeApproximator()
@@ -32,16 +33,22 @@ class TypeTranslator(
fun enterScope(irElement: IrTypeParametersContainer) { fun enterScope(irElement: IrTypeParametersContainer) {
typeParametersResolver.enterTypeParameterScope(irElement) typeParametersResolver.enterTypeParameterScope(irElement)
if(enterTableScope) {
symbolTable.enterScope(irElement.descriptor)
}
} }
fun leaveScope() { fun leaveScope(irElement: IrTypeParametersContainer) {
typeParametersResolver.leaveTypeParameterScope() typeParametersResolver.leaveTypeParameterScope()
if(enterTableScope) {
symbolTable.leaveScope(irElement.descriptor)
}
} }
inline fun <T> buildWithScope(container: IrTypeParametersContainer, builder: () -> T): T { inline fun <T> buildWithScope(container: IrTypeParametersContainer, builder: () -> T): T {
enterScope(container) enterScope(container)
val result = builder() val result = builder()
leaveScope() leaveScope(container)
return result return result
} }