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 psi2IrTranslator = Psi2IrTranslator(configuration.languageVersionSettings)
|
||||||
val psi2IrContext = psi2IrTranslator.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext)
|
val psi2IrContext = psi2IrTranslator.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext)
|
||||||
|
|
||||||
val moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files).removeDuplicates()
|
val moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files)
|
||||||
|
|
||||||
val context = JsIrBackendContext(
|
val context = JsIrBackendContext(
|
||||||
analysisResult.moduleDescriptor,
|
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 BodyLoweringPass.runOnFilePostfix(files: List<IrFile>) = files.forEach { runOnFilePostfix(it) }
|
||||||
private fun FunctionLoweringPass.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) }
|
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,
|
symbolTable = context.symbolTable,
|
||||||
irBuiltIns = context.irBuiltIns
|
irBuiltIns = context.irBuiltIns
|
||||||
).generateUnboundSymbolsAsDependencies(this)
|
).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 {
|
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.expressions.getTypeArgumentOrDefault
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
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.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
@@ -26,7 +27,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
|
|
||||||
// backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/irasdescriptors/NewIrUtils.kt
|
// 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
|
val moduleDescriptor = this.descriptor
|
||||||
|
|
||||||
fun KotlinType.referenceAllClassifiers() {
|
fun KotlinType.referenceAllClassifiers() {
|
||||||
@@ -126,9 +127,4 @@ fun IrModuleFragment.referenceAllTypeExternalClassifiers(symbolTable: SymbolTabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.acceptVoid(visitor)
|
this.acceptVoid(visitor)
|
||||||
this.dependencyModules.forEach { module ->
|
|
||||||
module.externalPackageFragments.forEach {
|
|
||||||
it.acceptVoid(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ interface IrModuleFragment : IrElement {
|
|||||||
val descriptor: ModuleDescriptor
|
val descriptor: ModuleDescriptor
|
||||||
val irBuiltins: IrBuiltIns
|
val irBuiltins: IrBuiltIns
|
||||||
val files: MutableList<IrFile>
|
val files: MutableList<IrFile>
|
||||||
val externalPackageFragments: MutableList<IrExternalPackageFragment>
|
|
||||||
val dependencyModules: MutableList<IrModuleFragment>
|
|
||||||
|
|
||||||
override val startOffset: Int get() = UNDEFINED_OFFSET
|
override val startOffset: Int get() = UNDEFINED_OFFSET
|
||||||
override val endOffset: 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 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 =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitModuleFragment(this, data)
|
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) {
|
override fun visitModuleFragment(declaration: IrModuleFragment, data: String) {
|
||||||
declaration.dumpLabeledElementWith(data) {
|
declaration.dumpLabeledElementWith(data) {
|
||||||
declaration.files.dumpElements()
|
declaration.files.dumpElements()
|
||||||
declaration.externalPackageFragments.dumpElements()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,19 +42,6 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
|
|||||||
for ((testFile, irFile) in ktFiles.zip(irModule.files)) {
|
for ((testFile, irFile) in ktFiles.zip(irModule.files)) {
|
||||||
doTestIrFileAgainstExpectations(dir, testFile, irFile)
|
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) {
|
protected fun doTestIrFileAgainstExpectations(dir: File, testFile: TestFile, irFile: IrFile) {
|
||||||
|
|||||||
Reference in New Issue
Block a user