[Psi2Ir] Isolate type translator in file scope

Create TypeTranslator per file to avoid reusing it between files
This commit is contained in:
Roman Artemev
2021-06-03 12:32:19 +03:00
committed by TeamCityServer
parent ae3a2d4e71
commit 7ef63fbb45
5 changed files with 56 additions and 30 deletions
@@ -63,7 +63,6 @@ class Psi2IrTranslator(
symbolTable, symbolTable,
extensions, extensions,
typeTranslator, typeTranslator,
typeTranslator.constantValueGenerator,
IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, symbolTable), IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, symbolTable),
) )
} }
@@ -14,25 +14,47 @@ import org.jetbrains.kotlin.descriptors.NotFoundClasses
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.IrDeclarationReference import org.jetbrains.kotlin.ir.expressions.IrDeclarationReference
import org.jetbrains.kotlin.ir.util.ConstantValueGenerator
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.LockBasedStorageManager
class GeneratorContext( class GeneratorContext private constructor(
val configuration: Psi2IrConfiguration, val configuration: Psi2IrConfiguration,
val moduleDescriptor: ModuleDescriptor, val moduleDescriptor: ModuleDescriptor,
val bindingContext: BindingContext, val bindingContext: BindingContext,
val languageVersionSettings: LanguageVersionSettings, val languageVersionSettings: LanguageVersionSettings,
val symbolTable: SymbolTable, val symbolTable: SymbolTable,
val extensions: GeneratorExtensions, val extensions: GeneratorExtensions,
val typeTranslator: TypeTranslatorImpl, val typeTranslator: TypeTranslator,
val constantValueGenerator: ConstantValueGenerator, override val irBuiltIns: IrBuiltIns,
override val irBuiltIns: IrBuiltIns internal val callToSubstitutedDescriptorMap: MutableMap<IrDeclarationReference, CallableDescriptor>
) : IrGeneratorContext { ) : IrGeneratorContext {
internal val callToSubstitutedDescriptorMap = mutableMapOf<IrDeclarationReference, CallableDescriptor>()
constructor(
configuration: Psi2IrConfiguration,
moduleDescriptor: ModuleDescriptor,
bindingContext: BindingContext,
languageVersionSettings: LanguageVersionSettings,
symbolTable: SymbolTable,
extensions: GeneratorExtensions,
typeTranslator: TypeTranslator,
irBuiltIns: IrBuiltIns,
) : this(
configuration,
moduleDescriptor,
bindingContext,
languageVersionSettings,
symbolTable,
extensions,
typeTranslator,
irBuiltIns,
mutableMapOf()
)
val constantValueGenerator = typeTranslator.constantValueGenerator
fun IrDeclarationReference.commitSubstituted(descriptor: CallableDescriptor) { fun IrDeclarationReference.commitSubstituted(descriptor: CallableDescriptor) {
callToSubstitutedDescriptorMap[this] = descriptor callToSubstitutedDescriptorMap[this] = descriptor
@@ -42,4 +64,19 @@ class GeneratorContext(
val reflectionTypes = ReflectionTypes(moduleDescriptor, NotFoundClasses(LockBasedStorageManager.NO_LOCKS, moduleDescriptor)) val reflectionTypes = ReflectionTypes(moduleDescriptor, NotFoundClasses(LockBasedStorageManager.NO_LOCKS, moduleDescriptor))
val samTypeApproximator = SamTypeApproximator(moduleDescriptor.builtIns, languageVersionSettings) val samTypeApproximator = SamTypeApproximator(moduleDescriptor.builtIns, languageVersionSettings)
fun createFileScopeContext(ktFile: KtFile): GeneratorContext {
return GeneratorContext(
configuration,
moduleDescriptor,
bindingContext,
languageVersionSettings,
symbolTable,
extensions,
TypeTranslatorImpl(symbolTable, languageVersionSettings, moduleDescriptor, extensions = extensions, ktFile = ktFile),
irBuiltIns,
callToSubstitutedDescriptorMap
)
}
} }
@@ -38,15 +38,13 @@ class ModuleGenerator(
override val context: GeneratorContext, override val context: GeneratorContext,
private val expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null private val expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
) : Generator { ) : Generator {
private val constantValueGenerator = context.constantValueGenerator
fun generateModuleFragment(ktFiles: Collection<KtFile>): IrModuleFragment = fun generateModuleFragment(ktFiles: Collection<KtFile>): IrModuleFragment =
IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule -> IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule ->
val irDeclarationGenerator = DeclarationGenerator(context)
ktFiles.toSet().mapTo(irModule.files) { ktFile -> ktFiles.toSet().mapTo(irModule.files) { ktFile ->
context.typeTranslator.inFile(ktFile) { val fileContext = context.createFileScopeContext(ktFile)
generateSingleFile(irDeclarationGenerator, ktFile, irModule) val irDeclarationGenerator = DeclarationGenerator(fileContext)
} generateSingleFile(irDeclarationGenerator, ktFile, irModule)
} }
} }
@@ -57,6 +55,7 @@ class ModuleGenerator(
private fun generateSingleFile(irDeclarationGenerator: DeclarationGenerator, ktFile: KtFile, module: IrModuleFragment): IrFileImpl { private fun generateSingleFile(irDeclarationGenerator: DeclarationGenerator, ktFile: KtFile, module: IrModuleFragment): IrFileImpl {
val irFile = createEmptyIrFile(ktFile, module) val irFile = createEmptyIrFile(ktFile, module)
val constantValueGenerator = irDeclarationGenerator.context.constantValueGenerator
for (ktAnnotationEntry in ktFile.annotationEntries) { for (ktAnnotationEntry in ktFile.annotationEntries) {
val annotationDescriptor = getOrFail(BindingContext.ANNOTATION, ktAnnotationEntry) val annotationDescriptor = getOrFail(BindingContext.ANNOTATION, ktAnnotationEntry)
constantValueGenerator.generateAnnotationConstructorCall(annotationDescriptor)?.let { constantValueGenerator.generateAnnotationConstructorCall(annotationDescriptor)?.let {
@@ -14,16 +14,16 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
class TypeTranslatorImpl( open class TypeTranslatorImpl(
symbolTable: ReferenceSymbolTable, symbolTable: ReferenceSymbolTable,
languageVersionSettings: LanguageVersionSettings, languageVersionSettings: LanguageVersionSettings,
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
typeParametersResolverBuilder: () -> TypeParametersResolver = { ScopedTypeParametersResolver() }, typeParametersResolverBuilder: () -> TypeParametersResolver = { ScopedTypeParametersResolver() },
enterTableScope: Boolean = false, enterTableScope: Boolean = false,
extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY, extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY,
private val ktFile: KtFile? = null
) : TypeTranslator(symbolTable, languageVersionSettings, typeParametersResolverBuilder, enterTableScope, extensions) { ) : TypeTranslator(symbolTable, languageVersionSettings, typeParametersResolverBuilder, enterTableScope, extensions) {
override val constantValueGenerator: ConstantValueGenerator = override val constantValueGenerator: ConstantValueGenerator = ConstantValueGeneratorImpl(moduleDescriptor, symbolTable, this)
ConstantValueGeneratorImpl(moduleDescriptor, symbolTable, this)
private val typeApproximatorForNI = TypeApproximator(moduleDescriptor.builtIns, languageVersionSettings) private val typeApproximatorForNI = TypeApproximator(moduleDescriptor.builtIns, languageVersionSettings)
@@ -48,17 +48,6 @@ class TypeTranslatorImpl(
val psiFile = typeAliasDescriptor.source.getPsi()?.containingFile ?: return false val psiFile = typeAliasDescriptor.source.getPsi()?.containingFile ?: return false
return psiFile == currentFile return psiFile == ktFile
}
private var currentFile: KtFile? = null
fun <R> inFile(ktFile: KtFile?, block: () -> R): R {
try {
currentFile = ktFile
return block()
} finally {
currentFile = null
}
} }
} }
@@ -28,11 +28,11 @@ import java.util.*
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
abstract class TypeTranslator( abstract class TypeTranslator(
private val symbolTable: ReferenceSymbolTable, protected val symbolTable: ReferenceSymbolTable,
val languageVersionSettings: LanguageVersionSettings, val languageVersionSettings: LanguageVersionSettings,
typeParametersResolverBuilder: () -> TypeParametersResolver = { ScopedTypeParametersResolver() }, typeParametersResolverBuilder: () -> TypeParametersResolver = { ScopedTypeParametersResolver() },
private val enterTableScope: Boolean = false, private val enterTableScope: Boolean = false,
private val extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY protected val extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
) { ) {
abstract val constantValueGenerator: ConstantValueGenerator abstract val constantValueGenerator: ConstantValueGenerator
@@ -69,7 +69,7 @@ abstract class TypeTranslator(
} }
} }
inline fun <T> buildWithScope(container: IrTypeParametersContainer, builder: () -> T): T { fun <T> buildWithScope(container: IrTypeParametersContainer, builder: () -> T): T {
enterScope(container) enterScope(container)
val result = builder() val result = builder()
leaveScope(container) leaveScope(container)
@@ -170,6 +170,8 @@ abstract class TypeTranslator(
// Abbreviated type's classifier might not be TypeAliasDescriptor in case it's MockClassDescriptor (not found in dependencies). // Abbreviated type's classifier might not be TypeAliasDescriptor in case it's MockClassDescriptor (not found in dependencies).
val typeAliasDescriptor = constructor.declarationDescriptor as? TypeAliasDescriptor ?: return null val typeAliasDescriptor = constructor.declarationDescriptor as? TypeAliasDescriptor ?: return null
// There is possible situation when we have private top-level type alias visible outside its file which is illegal from klib POV.
// In that specific case don't generate type abbreviation
if (!isTypeAliasAccessibleHere(typeAliasDescriptor)) return null if (!isTypeAliasAccessibleHere(typeAliasDescriptor)) return null
return IrTypeAbbreviationImpl( return IrTypeAbbreviationImpl(