From 6fd762cfcefc4baac3eea599e6117bb933462eca Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 23 May 2017 14:29:22 +0300 Subject: [PATCH] Provide DeclarationStubGenerator as a separate class in IR utilities --- .../psi2ir/generators/ClassGenerator.kt | 2 +- .../generators/ModuleDependenciesGenerator.kt | 118 ++------------ .../ir/util/DeclarationStubGenerator.kt | 144 ++++++++++++++++++ .../ir/util}/StableDescriptorsComparator.kt | 2 +- 4 files changed, 159 insertions(+), 107 deletions(-) create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt rename compiler/ir/{ir.psi2ir/src/org/jetbrains/kotlin/psi2ir => ir.tree/src/org/jetbrains/kotlin/ir/util}/StableDescriptorsComparator.kt (97%) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt index fbec017e6b3..d2bb7d4f6f8 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt @@ -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 diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleDependenciesGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleDependenciesGenerator.kt index c7350a34612..bc07d372d64 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleDependenciesGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleDependenciesGenerator.kt @@ -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() private val packageFragmentsForDependencyDescriptors = LinkedHashMap>() @@ -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): 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.generateChildStubs(irParent: IrDeclarationContainer) { - mapTo(irParent.declarations) { generateStub(it) } - } - - private fun Collection.generateTypeParameterStubs(irParent: IrTypeParametersContainer) { - mapTo(irParent.typeParameters) { generateTypeParameterStub(it) } - } - - private fun Collection.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) } - } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt new file mode 100644 index 00000000000..f9e16daa567 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt @@ -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, 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, 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, container: IrDeclarationContainer) { + descriptors.sortedWith(StableDescriptorsComparator).mapTo(container.declarations) { generateMemberStub(it) } + } +} \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/StableDescriptorsComparator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StableDescriptorsComparator.kt similarity index 97% rename from compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/StableDescriptorsComparator.kt rename to compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StableDescriptorsComparator.kt index 267694fc9cf..d482fba6fa1 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/StableDescriptorsComparator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StableDescriptorsComparator.kt @@ -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