Separate stub generation for external dependencies from PSI2IR
This commit is contained in:
-112
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* 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.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
class ModuleDependenciesGenerator(override val context: GeneratorContext) : Generator {
|
||||
private val stubGenerator = DeclarationStubGenerator(context.symbolTable, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB)
|
||||
|
||||
private 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()
|
||||
|
||||
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.unboundClasses.addTopLevelDeclarations()
|
||||
symbolTable.unboundConstructors.addTopLevelDeclarations()
|
||||
symbolTable.unboundEnumEntries.addTopLevelDeclarations()
|
||||
symbolTable.unboundFields.addTopLevelDeclarations()
|
||||
symbolTable.unboundSimpleFunctions.addTopLevelDeclarations()
|
||||
}
|
||||
|
||||
private fun Collection<IrSymbol>.addTopLevelDeclarations() {
|
||||
forEach { addTopLevelDeclaration(it) }
|
||||
}
|
||||
|
||||
fun addTopLevelDeclaration(symbol: IrSymbol) {
|
||||
val descriptor = symbol.descriptor
|
||||
val topLevelDeclaration = getTopLevelDeclaration(descriptor)
|
||||
addTopLevelDescriptor(topLevelDeclaration)
|
||||
}
|
||||
|
||||
private fun getTopLevelDeclaration(descriptor: DeclarationDescriptor): DeclarationDescriptor {
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
return when (containingDeclaration) {
|
||||
is PackageFragmentDescriptor -> descriptor
|
||||
is ClassDescriptor -> getTopLevelDeclaration(containingDeclaration)
|
||||
else -> throw AssertionError("Package or class expected: $containingDeclaration")
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment) {
|
||||
val collector = DependenciesCollector()
|
||||
collector.collectTopLevelDescriptorsForUnboundSymbols(context.symbolTable)
|
||||
|
||||
collector.dependencyModules.mapTo(irModule.dependencyModules) { moduleDescriptor ->
|
||||
generateModuleStub(collector, moduleDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateModuleStub(collector: DependenciesCollector, moduleDescriptor: ModuleDescriptor): IrModuleFragment =
|
||||
stubGenerator.generateEmptyModuleFragmentStub(moduleDescriptor, context.irBuiltIns).also { irDependencyModule ->
|
||||
collector.getPackageFragments(moduleDescriptor).mapTo(irDependencyModule.externalPackageFragments) { packageFragmentDescriptor ->
|
||||
generatePackageStub(packageFragmentDescriptor, collector.getTopLevelDescriptors(packageFragmentDescriptor))
|
||||
}
|
||||
}
|
||||
|
||||
private fun generatePackageStub(packageFragmentDescriptor: PackageFragmentDescriptor, topLevelDescriptors: Collection<DeclarationDescriptor>): IrExternalPackageFragment =
|
||||
stubGenerator.generateEmptyExternalPackageFragmentStub(packageFragmentDescriptor).also { irExternalPackageFragment ->
|
||||
topLevelDescriptors.mapTo(irExternalPackageFragment.declarations) {
|
||||
stubGenerator.generateMemberStub(it)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
@@ -35,7 +36,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
}
|
||||
|
||||
private fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment) {
|
||||
ModuleDependenciesGenerator(context).generateUnboundSymbolsAsDependencies(irModule)
|
||||
ExternalDependenciesGenerator(context.symbolTable, context.irBuiltIns).generateUnboundSymbolsAsDependencies(irModule)
|
||||
}
|
||||
|
||||
private fun generateFiles(ktFiles: Collection<KtFile>): List<IrFile> {
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
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()
|
||||
|
||||
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.unboundClasses.addTopLevelDeclarations()
|
||||
symbolTable.unboundConstructors.addTopLevelDeclarations()
|
||||
symbolTable.unboundEnumEntries.addTopLevelDeclarations()
|
||||
symbolTable.unboundFields.addTopLevelDeclarations()
|
||||
symbolTable.unboundSimpleFunctions.addTopLevelDeclarations()
|
||||
}
|
||||
|
||||
private fun Collection<IrSymbol>.addTopLevelDeclarations() {
|
||||
forEach { addTopLevelDeclaration(it) }
|
||||
}
|
||||
|
||||
fun addTopLevelDeclaration(symbol: IrSymbol) {
|
||||
val descriptor = symbol.descriptor
|
||||
val topLevelDeclaration = getTopLevelDeclaration(descriptor)
|
||||
addTopLevelDescriptor(topLevelDeclaration)
|
||||
}
|
||||
|
||||
private fun getTopLevelDeclaration(descriptor: DeclarationDescriptor): DeclarationDescriptor {
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
return when (containingDeclaration) {
|
||||
is PackageFragmentDescriptor -> descriptor
|
||||
is ClassDescriptor -> getTopLevelDeclaration(containingDeclaration)
|
||||
else -> throw AssertionError("Package or class expected: $containingDeclaration")
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
|
||||
class ExternalDependenciesGenerator(val symbolTable: SymbolTable, val irBuiltIns: IrBuiltIns) {
|
||||
private val stubGenerator = DeclarationStubGenerator(symbolTable, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB)
|
||||
|
||||
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment) {
|
||||
val collector = DependenciesCollector()
|
||||
collector.collectTopLevelDescriptorsForUnboundSymbols(symbolTable)
|
||||
|
||||
collector.dependencyModules.mapTo(irModule.dependencyModules) { moduleDescriptor ->
|
||||
generateModuleStub(collector, moduleDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateModuleStub(collector: DependenciesCollector, moduleDescriptor: ModuleDescriptor): IrModuleFragment =
|
||||
stubGenerator.generateEmptyModuleFragmentStub(moduleDescriptor, irBuiltIns).also { irDependencyModule ->
|
||||
collector.getPackageFragments(moduleDescriptor).mapTo(irDependencyModule.externalPackageFragments) { packageFragmentDescriptor ->
|
||||
generatePackageStub(packageFragmentDescriptor, collector.getTopLevelDescriptors(packageFragmentDescriptor))
|
||||
}
|
||||
}
|
||||
|
||||
private fun generatePackageStub(packageFragmentDescriptor: PackageFragmentDescriptor, topLevelDescriptors: Collection<DeclarationDescriptor>): IrExternalPackageFragment =
|
||||
stubGenerator.generateEmptyExternalPackageFragmentStub(packageFragmentDescriptor).also { irExternalPackageFragment ->
|
||||
topLevelDescriptors.mapTo(irExternalPackageFragment.declarations) {
|
||||
stubGenerator.generateMemberStub(it)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user