Provide DeclarationStubGenerator as a separate class in IR utilities

This commit is contained in:
Dmitry Petrov
2017-05-23 14:29:22 +03:00
parent 7204a929f3
commit 6fd762cfce
4 changed files with 159 additions and 107 deletions
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi2ir.StableDescriptorsComparator
import org.jetbrains.kotlin.ir.util.StableDescriptorsComparator
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -16,20 +16,20 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
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.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.psi2ir.StableDescriptorsComparator
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.MemberScope
class ModuleDependenciesGenerator(override val context: GeneratorContext) : Generator {
private val stubGenerator = DeclarationStubGenerator(context.symbolTable)
private class DependenciesCollector {
private val modulesForDependencyDescriptors = LinkedHashSet<ModuleDescriptor>()
private val packageFragmentsForDependencyDescriptors = LinkedHashMap<ModuleDescriptor, MutableSet<PackageFragmentDescriptor>>()
@@ -94,110 +94,18 @@ class ModuleDependenciesGenerator(override val context: GeneratorContext) : Gene
}
}
private fun generateModuleStub(collector: DependenciesCollector, moduleDescriptor: ModuleDescriptor): IrModuleFragmentImpl =
IrModuleFragmentImpl(moduleDescriptor, context.irBuiltIns).also { irDependencyModule ->
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 =
context.symbolTable.declareExternalPackageFragment(packageFragmentDescriptor).also { irExternalPackageFragment ->
stubGenerator.generateEmptyExternalPackageFragmentStub(packageFragmentDescriptor).also { irExternalPackageFragment ->
topLevelDescriptors.mapTo(irExternalPackageFragment.declarations) {
generateStub(it)
stubGenerator.generateMemberStub(it)
}
}
private fun generateStub(descriptor: DeclarationDescriptor): IrDeclaration =
when (descriptor) {
is ClassDescriptor ->
if (DescriptorUtils.isEnumEntry(descriptor))
generateEnumEntryStub(descriptor)
else
generateClassStub(descriptor)
is ClassConstructorDescriptor ->
generateConstructorStub(descriptor)
is FunctionDescriptor ->
generateFunctionStub(descriptor)
is PropertyDescriptor ->
generatePropertyStub(descriptor)
else ->
throw AssertionError("Unexpected top-level descriptor: $descriptor")
}
private fun MemberScope.generateChildStubs(irParent: IrDeclarationContainer) {
getContributedDescriptors().sortedWith(StableDescriptorsComparator).generateChildStubs (irParent)
}
private fun Collection<DeclarationDescriptor>.generateChildStubs(irParent: IrDeclarationContainer) {
mapTo(irParent.declarations) { generateStub(it) }
}
private fun Collection<TypeParameterDescriptor>.generateTypeParameterStubs(irParent: IrTypeParametersContainer) {
mapTo(irParent.typeParameters) { generateTypeParameterStub(it) }
}
private fun Collection<ValueParameterDescriptor>.generateValueParametersStubs(irParent: IrFunction) {
mapTo(irParent.valueParameters) { generateValueParameterStub(it) }
}
private fun generateClassStub(classDescriptor: ClassDescriptor): IrClass =
context.symbolTable.declareClass(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
classDescriptor
).also { irClass ->
classDescriptor.declaredTypeParameters.generateTypeParameterStubs(irClass)
classDescriptor.constructors.generateChildStubs(irClass)
classDescriptor.defaultType.memberScope.generateChildStubs(irClass)
classDescriptor.staticScope.generateChildStubs(irClass)
}
private fun generateEnumEntryStub(enumEntryDescriptor: ClassDescriptor): IrEnumEntry =
context.symbolTable.declareEnumEntry(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
enumEntryDescriptor
)
private fun generateTypeParameterStub(typeParameterDescriptor: TypeParameterDescriptor): IrTypeParameter =
IrTypeParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, typeParameterDescriptor)
private fun generateValueParameterStub(valueParameterDescriptor: ValueParameterDescriptor): IrValueParameter =
IrValueParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, valueParameterDescriptor)
private fun generateConstructorStub(constructorDescriptor: ClassConstructorDescriptor): IrConstructor =
context.symbolTable.declareConstructor(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
constructorDescriptor
).also { irConstructor ->
constructorDescriptor.valueParameters.generateValueParametersStubs(irConstructor)
}
private fun generateFunctionStub(functionDescriptor: FunctionDescriptor): IrFunction =
context.symbolTable.declareSimpleFunction(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
functionDescriptor
).also { irFunction ->
functionDescriptor.typeParameters.generateTypeParameterStubs(irFunction)
functionDescriptor.valueParameters.generateValueParametersStubs(irFunction)
}
private fun generatePropertyStub(propertyDescriptor: PropertyDescriptor): IrProperty =
IrPropertyImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
propertyDescriptor
).also { irProperty ->
val getterDescriptor = propertyDescriptor.getter
if (getterDescriptor == null) {
irProperty.backingField =
context.symbolTable.declareField(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
propertyDescriptor
)
}
else {
irProperty.getter = generateFunctionStub(getterDescriptor)
}
irProperty.setter = propertyDescriptor.setter?.let { generateFunctionStub(it) }
}
}
@@ -0,0 +1,144 @@
/*
* 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.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.resolve.scopes.MemberScope
class DeclarationStubGenerator(val symbolTable: SymbolTable) {
fun generateEmptyModuleFragmentStub(descriptor: ModuleDescriptor, irBuiltIns: IrBuiltIns): IrModuleFragment =
IrModuleFragmentImpl(descriptor, irBuiltIns)
fun generateEmptyExternalPackageFragmentStub(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment =
symbolTable.declareExternalPackageFragment(descriptor)
fun generateMemberStub(descriptor: DeclarationDescriptor): IrDeclaration =
when (descriptor) {
is ClassDescriptor ->
if (DescriptorUtils.isEnumEntry(descriptor))
generateEnumEntryStub(descriptor)
else
generateClassStub(descriptor)
is ClassConstructorDescriptor ->
generateConstructorStub(descriptor)
is FunctionDescriptor ->
generateFunctionStub(descriptor)
is PropertyDescriptor ->
generatePropertyStub(descriptor)
else ->
throw AssertionError("Unexpected member descriptor: $descriptor")
}
fun generatePropertyStub(descriptor: PropertyDescriptor): IrProperty =
IrPropertyImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
descriptor
).also { irProperty ->
val getterDescriptor = descriptor.getter
if (getterDescriptor == null) {
irProperty.backingField =
symbolTable.declareField(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
descriptor
)
}
else {
irProperty.getter = generateFunctionStub(getterDescriptor)
}
irProperty.setter = descriptor.setter?.let { generateFunctionStub(it) }
}
fun generateFunctionStub(descriptor: FunctionDescriptor): IrSimpleFunction =
symbolTable.declareSimpleFunction(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
descriptor
).also { irFunction ->
generateTypeParameterStubs(descriptor.typeParameters, irFunction)
generateValueParametersStubs(descriptor.valueParameters, irFunction)
}
fun generateConstructorStub(descriptor: ClassConstructorDescriptor): IrConstructor =
symbolTable.declareConstructor(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
descriptor
).also { irConstructor ->
generateValueParametersStubs(descriptor.valueParameters, irConstructor)
}
fun generateValueParametersStubs(valueParameters: Collection<ValueParameterDescriptor>, function: IrFunction) {
valueParameters.mapTo(function.valueParameters) { generateValueParameterStub(it) }
}
fun generateValueParameterStub(descriptor: ValueParameterDescriptor): IrValueParameter =
IrValueParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
descriptor
).also { irValueParameter ->
if (descriptor.declaresDefaultValue()) {
irValueParameter.defaultValue =
IrExpressionBodyImpl(IrErrorExpressionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, descriptor.type,
"Stub expression for default value of ${descriptor.name}"
))
}
}
fun generateClassStub(descriptor: ClassDescriptor): IrClass =
symbolTable.declareClass(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
descriptor
).also { irClass ->
generateTypeParameterStubs(descriptor.declaredTypeParameters, irClass)
generateChildStubs(descriptor.constructors, irClass)
generateMemberStubs(descriptor.defaultType.memberScope, irClass)
generateMemberStubs(descriptor.staticScope, irClass)
}
fun generateEnumEntryStub(descriptor: ClassDescriptor): IrEnumEntry =
symbolTable.declareEnumEntry(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
descriptor
)
fun generateTypeParameterStubs(typeParameters: List<TypeParameterDescriptor>, container: IrTypeParametersContainer) {
typeParameters.mapTo(container.typeParameters) { generateTypeParameterStub(it) }
}
fun generateTypeParameterStub(descriptor: TypeParameterDescriptor): IrTypeParameter =
IrTypeParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, descriptor)
fun generateMemberStubs(memberScope: MemberScope, container: IrDeclarationContainer) {
generateChildStubs(memberScope.getContributedDescriptors(), container)
}
fun generateChildStubs(descriptors: Collection<DeclarationDescriptor>, container: IrDeclarationContainer) {
descriptors.sortedWith(StableDescriptorsComparator).mapTo(container.declarations) { generateMemberStub(it) }
}
}
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.psi2ir
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.renderer.ClassifierNamePolicy