Get rid of 'externalPackageFragments' and 'dependencyModules' in IrModuleFragment
This commit is contained in:
@@ -43,7 +43,7 @@ fun compile(
|
||||
val psi2IrTranslator = Psi2IrTranslator(configuration.languageVersionSettings)
|
||||
val psi2IrContext = psi2IrTranslator.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext)
|
||||
|
||||
val moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files).removeDuplicates()
|
||||
val moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files)
|
||||
|
||||
val context = JsIrBackendContext(
|
||||
analysisResult.moduleDescriptor,
|
||||
@@ -113,18 +113,3 @@ private fun DeclarationContainerLoweringPass.runOnFilePostfix(files: List<IrFile
|
||||
private fun BodyLoweringPass.runOnFilePostfix(files: List<IrFile>) = files.forEach { runOnFilePostfix(it) }
|
||||
private fun FunctionLoweringPass.runOnFilePostfix(files: List<IrFile>) = files.forEach { runOnFilePostfix(it) }
|
||||
private fun ClassLoweringPass.runOnFilePostfix(files: List<IrFile>) = files.forEach { runOnFilePostfix(it) }
|
||||
|
||||
// TODO find out why duplicates occur
|
||||
private fun IrModuleFragment.removeDuplicates(): IrModuleFragment {
|
||||
|
||||
fun <T> MutableList<T>.removeDuplicates() {
|
||||
val tmp = toSet()
|
||||
clear()
|
||||
addAll(tmp)
|
||||
}
|
||||
|
||||
dependencyModules.removeDuplicates()
|
||||
dependencyModules.forEach { it.externalPackageFragments.removeDuplicates() }
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
-36
@@ -59,42 +59,6 @@ internal fun IrModuleFragment.replaceUnboundSymbols(context: JsIrBackendContext)
|
||||
symbolTable = context.symbolTable,
|
||||
irBuiltIns = context.irBuiltIns
|
||||
).generateUnboundSymbolsAsDependencies(this)
|
||||
|
||||
// Merge duplicated module and package declarations:
|
||||
this.acceptVoid(object : IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {}
|
||||
|
||||
override fun visitModuleFragment(declaration: IrModuleFragment) {
|
||||
declaration.dependencyModules.forEach { it.acceptVoid(this) }
|
||||
|
||||
val dependencyModules = declaration.dependencyModules.toSet().groupBy { it.descriptor }.map { (_, fragments) ->
|
||||
fragments.reduce { firstModule, nextModule ->
|
||||
firstModule.apply {
|
||||
mergeFrom(nextModule)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declaration.dependencyModules.clear()
|
||||
declaration.dependencyModules.addAll(dependencyModules)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
private fun IrModuleFragment.mergeFrom(other: IrModuleFragment): Unit {
|
||||
assert(this.files.isEmpty())
|
||||
assert(other.files.isEmpty())
|
||||
|
||||
val thisPackages = this.externalPackageFragments.groupBy { it.packageFragmentDescriptor }
|
||||
other.externalPackageFragments.forEach {
|
||||
val thisPackage = thisPackages[it.packageFragmentDescriptor]?.toSet()?.single()
|
||||
if (thisPackage == null) {
|
||||
this.externalPackageFragments.add(it)
|
||||
} else {
|
||||
thisPackage.addChildren(it.declarations)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DeclarationSymbolCollector : IrElementVisitorVoid {
|
||||
|
||||
+2
-6
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.getTypeArgumentOrDefault
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -26,7 +27,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
// backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/irasdescriptors/NewIrUtils.kt
|
||||
fun IrModuleFragment.referenceAllTypeExternalClassifiers(symbolTable: SymbolTable) {
|
||||
fun IrModuleFragment.referenceAllTypeExternalClassifiers(symbolTable: ReferenceSymbolTable) {
|
||||
val moduleDescriptor = this.descriptor
|
||||
|
||||
fun KotlinType.referenceAllClassifiers() {
|
||||
@@ -126,9 +127,4 @@ fun IrModuleFragment.referenceAllTypeExternalClassifiers(symbolTable: SymbolTabl
|
||||
}
|
||||
|
||||
this.acceptVoid(visitor)
|
||||
this.dependencyModules.forEach { module ->
|
||||
module.externalPackageFragments.forEach {
|
||||
it.acceptVoid(visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@ interface IrModuleFragment : IrElement {
|
||||
val descriptor: ModuleDescriptor
|
||||
val irBuiltins: IrBuiltIns
|
||||
val files: MutableList<IrFile>
|
||||
val externalPackageFragments: MutableList<IrExternalPackageFragment>
|
||||
val dependencyModules: MutableList<IrModuleFragment>
|
||||
|
||||
override val startOffset: Int get() = UNDEFINED_OFFSET
|
||||
override val endOffset: Int get() = UNDEFINED_OFFSET
|
||||
|
||||
-4
@@ -38,10 +38,6 @@ class IrModuleFragmentImpl(
|
||||
|
||||
override val files: MutableList<IrFile> = ArrayList()
|
||||
|
||||
override val externalPackageFragments: MutableList<IrExternalPackageFragment> = ArrayList()
|
||||
|
||||
override val dependencyModules: MutableList<IrModuleFragment> = ArrayList()
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitModuleFragment(this, data)
|
||||
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* 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.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
||||
|
||||
class DependenciesCollector {
|
||||
private val modulesForDependencyDescriptors = LinkedHashSet<ModuleDescriptor>()
|
||||
private val packageFragmentsForDependencyDescriptors = LinkedHashMap<ModuleDescriptor, MutableSet<PackageFragmentDescriptor>>()
|
||||
private val topLevelDescriptors = LinkedHashMap<PackageFragmentDescriptor, MutableSet<DeclarationDescriptor>>()
|
||||
|
||||
val dependencyModules: Collection<ModuleDescriptor> get() = modulesForDependencyDescriptors
|
||||
|
||||
fun getPackageFragments(moduleDescriptor: ModuleDescriptor): Collection<PackageFragmentDescriptor> =
|
||||
packageFragmentsForDependencyDescriptors[moduleDescriptor] ?: emptyList()
|
||||
|
||||
fun getTopLevelDescriptors(packageFragmentDescriptor: PackageFragmentDescriptor): Collection<DeclarationDescriptor> =
|
||||
topLevelDescriptors[packageFragmentDescriptor] ?: emptyList()
|
||||
|
||||
val isEmpty get() = topLevelDescriptors.isEmpty()
|
||||
|
||||
fun collectTopLevelDescriptorsForUnboundSymbols(symbolTable: SymbolTable) {
|
||||
assert(symbolTable.unboundTypeParameters.isEmpty()) { "Unbound type parameters: ${symbolTable.unboundTypeParameters}" }
|
||||
assert(symbolTable.unboundValueParameters.isEmpty()) { "Unbound value parameters: ${symbolTable.unboundValueParameters}" }
|
||||
assert(symbolTable.unboundVariables.isEmpty()) { "Unbound variables: ${symbolTable.unboundVariables}" }
|
||||
|
||||
symbolTable.markOverriddenFunctionsForUnboundFunctionsReferenced()
|
||||
symbolTable.markSuperClassesForUnboundClassesReferenced()
|
||||
|
||||
symbolTable.unboundClasses.addTopLevelDeclarations()
|
||||
symbolTable.unboundConstructors.addTopLevelDeclarations()
|
||||
symbolTable.unboundEnumEntries.addTopLevelDeclarations()
|
||||
symbolTable.unboundFields.addTopLevelDeclarations()
|
||||
symbolTable.unboundSimpleFunctions.addTopLevelDeclarations()
|
||||
}
|
||||
|
||||
private fun SymbolTable.markOverriddenFunctionsForUnboundFunctionsReferenced() {
|
||||
for (unboundFunction in unboundSimpleFunctions.toTypedArray()) {
|
||||
markOverriddenFunctionsReferenced(unboundFunction.descriptor, HashSet())
|
||||
}
|
||||
}
|
||||
|
||||
private fun SymbolTable.markOverriddenFunctionsReferenced(
|
||||
function: FunctionDescriptor,
|
||||
visitedFunctions: MutableSet<FunctionDescriptor>
|
||||
) {
|
||||
for (overridden in function.overriddenDescriptors) {
|
||||
if (overridden !in visitedFunctions) {
|
||||
visitedFunctions.add(overridden)
|
||||
referenceFunction(overridden.original)
|
||||
markOverriddenFunctionsReferenced(overridden, visitedFunctions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun SymbolTable.markSuperClassesForUnboundClassesReferenced() {
|
||||
for (unboundClass in unboundClasses.toTypedArray()) {
|
||||
for (superClassifier in unboundClass.descriptor.getAllSuperClassifiers()) {
|
||||
if (superClassifier is ClassDescriptor) {
|
||||
referenceClass(superClassifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Collection<IrSymbol>.addTopLevelDeclarations() {
|
||||
forEach {
|
||||
getTopLevelDeclaration(it.descriptor)?.let { addTopLevelDescriptor(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor.isSyntheticJavaProperties() =
|
||||
this is PropertyAccessorDescriptor &&
|
||||
this.kind == CallableMemberDescriptor.Kind.SYNTHESIZED &&
|
||||
containingDeclaration is ModuleDescriptor
|
||||
|
||||
private fun getTopLevelDeclaration(descriptor: DeclarationDescriptor): DeclarationDescriptor? {
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
return when (containingDeclaration) {
|
||||
is PackageFragmentDescriptor -> descriptor
|
||||
is ClassDescriptor -> getTopLevelDeclaration(containingDeclaration)
|
||||
else ->
|
||||
if (descriptor.isDynamic() || descriptor.isSyntheticJavaProperties()) {
|
||||
//skip
|
||||
null
|
||||
} else {
|
||||
throw AssertionError("Package or class expected: $containingDeclaration; for $descriptor")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addTopLevelDescriptor(descriptor: DeclarationDescriptor) {
|
||||
val packageFragmentDescriptor = DescriptorUtils.getParentOfType(descriptor, PackageFragmentDescriptor::class.java)!!
|
||||
|
||||
val moduleDescriptor = packageFragmentDescriptor.containingDeclaration
|
||||
modulesForDependencyDescriptors.add(moduleDescriptor)
|
||||
|
||||
packageFragmentsForDependencyDescriptors.getOrPut(moduleDescriptor) { LinkedHashSet() }.add(packageFragmentDescriptor)
|
||||
topLevelDescriptors.getOrPut(packageFragmentDescriptor) { LinkedHashSet() }.add(descriptor)
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,6 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
|
||||
override fun visitModuleFragment(declaration: IrModuleFragment, data: String) {
|
||||
declaration.dumpLabeledElementWith(data) {
|
||||
declaration.files.dumpElements()
|
||||
declaration.externalPackageFragments.dumpElements()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,19 +42,6 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
|
||||
for ((testFile, irFile) in ktFiles.zip(irModule.files)) {
|
||||
doTestIrFileAgainstExpectations(dir, testFile, irFile)
|
||||
}
|
||||
|
||||
if (shouldDumpDependencies(wholeFile)) {
|
||||
doTestIrModuleDependencies(wholeFile, irModule)
|
||||
}
|
||||
}
|
||||
|
||||
private fun doTestIrModuleDependencies(wholeFile: File, irModule: IrModuleFragment) {
|
||||
irModule.dependencyModules.forEach { irDependencyModule ->
|
||||
val actual = irDependencyModule.dump()
|
||||
val sanitizedModuleName = StringUtil.sanitizeJavaIdentifier(irDependencyModule.descriptor.name.asString())
|
||||
val expectedFileName = wholeFile.absolutePath.replace(".kt", "__$sanitizedModuleName.txt")
|
||||
KotlinTestUtils.assertEqualsToFile(File(expectedFileName), actual)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun doTestIrFileAgainstExpectations(dir: File, testFile: TestFile, irFile: IrFile) {
|
||||
|
||||
Reference in New Issue
Block a user