Introduce SymbolTable as a symbol factory and unbound symbols tracker
This commit is contained in:
@@ -33,6 +33,8 @@ class GeneratorContext(
|
|||||||
) : IrGeneratorContext(IrBuiltIns(moduleDescriptor.builtIns)) {
|
) : IrGeneratorContext(IrBuiltIns(moduleDescriptor.builtIns)) {
|
||||||
val sourceManager = PsiSourceManager()
|
val sourceManager = PsiSourceManager()
|
||||||
|
|
||||||
|
val symbolTable = SymbolTable()
|
||||||
|
|
||||||
// TODO: inject a correct StorageManager instance, or store NotFoundClasses inside ModuleDescriptor
|
// TODO: inject a correct StorageManager instance, or store NotFoundClasses inside ModuleDescriptor
|
||||||
val reflectionTypes = ReflectionTypes(moduleDescriptor, NotFoundClasses(LockBasedStorageManager.NO_LOCKS, moduleDescriptor))
|
val reflectionTypes = ReflectionTypes(moduleDescriptor, NotFoundClasses(LockBasedStorageManager.NO_LOCKS, moduleDescriptor))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 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.psi2ir.generators
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.ir.SourceManager
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||||
|
|
||||||
|
class SymbolTable {
|
||||||
|
private class SpecializedSymbolTable<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>> {
|
||||||
|
val descriptorToSymbol = linkedMapOf<D, S>()
|
||||||
|
val unboundSymbols = linkedSetOf<S>()
|
||||||
|
|
||||||
|
inline fun declare(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
|
||||||
|
val symbol = declared(d, createSymbol)
|
||||||
|
val owner = createOwner(symbol)
|
||||||
|
symbol.bind(owner)
|
||||||
|
return owner
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun declared(d: D, createSymbol: () -> S): S {
|
||||||
|
val existing = descriptorToSymbol[d]
|
||||||
|
return if (existing == null) {
|
||||||
|
val new = createSymbol()
|
||||||
|
descriptorToSymbol[d] = new
|
||||||
|
new
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(unboundSymbols.remove(existing)) {
|
||||||
|
"Symbol for $d is already bound"
|
||||||
|
}
|
||||||
|
existing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun referenced(d: D, createSymbol: () -> S): S =
|
||||||
|
descriptorToSymbol.getOrPut(d) {
|
||||||
|
createSymbol().also {
|
||||||
|
unboundSymbols.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val classSymbolTable = SpecializedSymbolTable<ClassDescriptor, IrClass, IrClassSymbol>()
|
||||||
|
private val constructorSymbolTable = SpecializedSymbolTable<ClassConstructorDescriptor, IrConstructor, IrConstructorSymbol>()
|
||||||
|
private val enumEntrySymbolTable = SpecializedSymbolTable<ClassDescriptor, IrEnumEntry, IrEnumEntrySymbol>()
|
||||||
|
private val fieldSymbolTable = SpecializedSymbolTable<PropertyDescriptor, IrField, IrFieldSymbol>()
|
||||||
|
private val simpleFunctionSymbolTable = SpecializedSymbolTable<FunctionDescriptor, IrSimpleFunction, IrSimpleFunctionSymbol>()
|
||||||
|
private val typeParameterSymbolTable = SpecializedSymbolTable<TypeParameterDescriptor, IrTypeParameter, IrTypeParameterSymbol>()
|
||||||
|
private val valueParameterSymbolTable = SpecializedSymbolTable<ParameterDescriptor, IrValueParameter, IrValueParameterSymbol>()
|
||||||
|
private val variableSymbolTable = SpecializedSymbolTable<VariableDescriptor, IrVariable, IrVariableSymbol>()
|
||||||
|
|
||||||
|
fun declareFile(fileEntry: SourceManager.FileEntry, packageFragmentDescriptor: PackageFragmentDescriptor): IrFile =
|
||||||
|
IrFileImpl(
|
||||||
|
fileEntry, packageFragmentDescriptor,
|
||||||
|
IrFileSymbolImpl(packageFragmentDescriptor)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun declareAnonymousInitializer(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor): IrAnonymousInitializer =
|
||||||
|
IrAnonymousInitializerImpl(
|
||||||
|
startOffset, endOffset, origin, descriptor,
|
||||||
|
IrAnonymousInitializerSymbolImpl(descriptor)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun declareClass(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor): IrClass =
|
||||||
|
classSymbolTable.declare(
|
||||||
|
descriptor,
|
||||||
|
{ IrClassSymbolImpl(descriptor) },
|
||||||
|
{ IrClassImpl(startOffset, endOffset, origin, descriptor, it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
fun referenceClass(descriptor: ClassDescriptor) =
|
||||||
|
classSymbolTable.referenced(descriptor) { IrClassSymbolImpl(descriptor) }
|
||||||
|
|
||||||
|
val unboundClasses: Set<IrClassSymbol> get() = classSymbolTable.unboundSymbols
|
||||||
|
|
||||||
|
fun declareConstructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassConstructorDescriptor): IrConstructor =
|
||||||
|
constructorSymbolTable.declare(
|
||||||
|
descriptor,
|
||||||
|
{ IrConstructorSymbolImpl(descriptor) },
|
||||||
|
{ IrConstructorImpl(startOffset, endOffset, origin, descriptor, it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
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 =
|
||||||
|
enumEntrySymbolTable.declare(
|
||||||
|
descriptor,
|
||||||
|
{ IrEnumEntrySymbolImpl(descriptor) },
|
||||||
|
{ IrEnumEntryImpl(startOffset, endOffset, origin, descriptor, it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
fun referenceEnumEntry(descriptor: ClassDescriptor) =
|
||||||
|
enumEntrySymbolTable.referenced(descriptor) { IrEnumEntrySymbolImpl(descriptor) }
|
||||||
|
|
||||||
|
val unboundEnumEntries: Set<IrEnumEntrySymbol> get() = enumEntrySymbolTable.unboundSymbols
|
||||||
|
|
||||||
|
fun declareField(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: PropertyDescriptor): IrField =
|
||||||
|
fieldSymbolTable.declare(
|
||||||
|
descriptor,
|
||||||
|
{ IrFieldSymbolImpl(descriptor) },
|
||||||
|
{ IrFieldImpl(startOffset, endOffset, origin, descriptor, it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
fun referenceField(descriptor: PropertyDescriptor) =
|
||||||
|
fieldSymbolTable.referenced(descriptor) { IrFieldSymbolImpl(descriptor) }
|
||||||
|
|
||||||
|
val unboundFields: Set<IrFieldSymbol> get() = fieldSymbolTable.unboundSymbols
|
||||||
|
|
||||||
|
fun declareSimpleFunction(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: FunctionDescriptor): IrSimpleFunction =
|
||||||
|
simpleFunctionSymbolTable.declare(
|
||||||
|
descriptor,
|
||||||
|
{ IrSimpleFunctionSymbolImpl(descriptor) },
|
||||||
|
{ IrFunctionImpl(startOffset, endOffset, origin, descriptor, it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
fun referenceSimpleFunction(descriptor: FunctionDescriptor) =
|
||||||
|
simpleFunctionSymbolTable.referenced(descriptor) { IrSimpleFunctionSymbolImpl(descriptor) }
|
||||||
|
|
||||||
|
val unboundSimpleFunctions: Set<IrSimpleFunctionSymbol> get() = simpleFunctionSymbolTable.unboundSymbols
|
||||||
|
|
||||||
|
fun declareTypeParameter(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: TypeParameterDescriptor) : IrTypeParameter =
|
||||||
|
typeParameterSymbolTable.declare(
|
||||||
|
descriptor,
|
||||||
|
{ IrTypeParameterSymbolImpl(descriptor) },
|
||||||
|
{ IrTypeParameterImpl(startOffset, endOffset, origin, descriptor, it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
fun referenceTypeParameter(descriptor: TypeParameterDescriptor) =
|
||||||
|
typeParameterSymbolTable.referenced(descriptor) { IrTypeParameterSymbolImpl(descriptor) }
|
||||||
|
|
||||||
|
val unboundTypeParameters: Set<IrTypeParameterSymbol> get() = typeParameterSymbolTable.unboundSymbols
|
||||||
|
|
||||||
|
fun declareValueParameter(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ParameterDescriptor): IrValueParameter =
|
||||||
|
valueParameterSymbolTable.declare(
|
||||||
|
descriptor,
|
||||||
|
{ IrValueParameterSymbolImpl(descriptor) },
|
||||||
|
{ IrValueParameterImpl(startOffset, endOffset, origin, descriptor, it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
fun referenceValueParameter(descriptor: ParameterDescriptor) =
|
||||||
|
valueParameterSymbolTable.referenced(descriptor) { IrValueParameterSymbolImpl(descriptor) }
|
||||||
|
|
||||||
|
val unboundValueParameters: Set<IrValueParameterSymbol> get() = valueParameterSymbolTable.unboundSymbols
|
||||||
|
|
||||||
|
fun declareVariable(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: VariableDescriptor): IrVariable =
|
||||||
|
variableSymbolTable.declare(
|
||||||
|
descriptor,
|
||||||
|
{ IrVariableSymbolImpl(descriptor) },
|
||||||
|
{ IrVariableImpl(startOffset, endOffset, origin, descriptor, it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
fun referenceVariable(descriptor: VariableDescriptor) =
|
||||||
|
variableSymbolTable.referenced(descriptor) { IrVariableSymbolImpl(descriptor) }
|
||||||
|
|
||||||
|
val unboundVariables: Set<IrVariableSymbol> get() = variableSymbolTable.unboundSymbols
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user