From ba9b7547b04d8e66a316eefa89c15d0c5b00a89d Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Mon, 9 Jul 2018 17:07:43 +0300 Subject: [PATCH] Generate IR for synthetic nested classes directly in class generator --- .../SyntheticClassOrObjectDescriptor.kt | 1 + .../jetbrains/kotlin/psi2ir/KotlinUtils.kt | 8 ++-- .../kotlin/psi2ir/generators/BodyGenerator.kt | 23 ++++++----- .../psi2ir/generators/ClassGenerator.kt | 38 ++++++++++++++----- .../psi2ir/generators/DeclarationGenerator.kt | 18 ++++++--- .../psi2ir/generators/FunctionGenerator.kt | 32 ++++++++-------- .../jetbrains/kotlin/psi/KtClassOrObject.kt | 2 +- .../kotlin/psi/KtPureClassOrObject.java | 3 ++ .../jetbrains/kotlin/psi/psiUtil/psiUtils.kt | 12 ++++-- 9 files changed, 87 insertions(+), 50 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt index 0e4e807d3f8..fa5f8efb2c3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt @@ -164,6 +164,7 @@ class SyntheticClassOrObjectDescriptor( // in theory `containingKtFile` is `@NotNull` but in practice EA-114080 _parent.containingKtFile ?: throw IllegalStateException("containingKtFile was null for $_parent of ${_parent.javaClass}") + override fun getBody(): KtClassBody? = null } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/KotlinUtils.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/KotlinUtils.kt index d9c59ce9810..3bf36661a0a 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/KotlinUtils.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/KotlinUtils.kt @@ -22,10 +22,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.kotlin.psi.KtPsiUtil -import org.jetbrains.kotlin.psi.KtSecondaryConstructor +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.BindingContext @@ -85,3 +82,6 @@ val PropertyDescriptor.unwrappedGetMethod: FunctionDescriptor? val PropertyDescriptor.unwrappedSetMethod: FunctionDescriptor? get() = if (this is SyntheticPropertyDescriptor) this.setMethod else setter + +val KtPureElement?.pureStartOffsetOrUndefined get() = this?.psiOrParent?.startOffset ?: UNDEFINED_OFFSET +val KtPureElement?.pureEndOffsetOrUndefined get() = this?.psiOrParent?.endOffset ?: UNDEFINED_OFFSET \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt index 9087b5cdaa2..c875b4535f3 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt @@ -25,7 +25,10 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.referenceFunction import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.psi.psiUtil.pureEndOffset +import org.jetbrains.kotlin.psi.psiUtil.pureStartOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.psi.synthetics.findClassDescriptor import org.jetbrains.kotlin.psi2ir.intermediate.VariableLValue import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall @@ -176,15 +179,15 @@ class BodyGenerator( fun getLoop(expression: KtExpression): IrLoop? = loopTable[expression] - fun generatePrimaryConstructorBody(ktClassOrObject: KtClassOrObject): IrBody { - val irBlockBody = IrBlockBodyImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset) + fun generatePrimaryConstructorBody(ktClassOrObject: KtPureClassOrObject): IrBody { + val irBlockBody = IrBlockBodyImpl(ktClassOrObject.pureStartOffset, ktClassOrObject.pureEndOffset) generateSuperConstructorCall(irBlockBody, ktClassOrObject) val classDescriptor = (scopeOwner as ClassConstructorDescriptor).containingDeclaration irBlockBody.statements.add( IrInstanceInitializerCallImpl( - ktClassOrObject.startOffset, ktClassOrObject.endOffset, + ktClassOrObject.pureStartOffset, ktClassOrObject.pureEndOffset, context.symbolTable.referenceClass(classDescriptor), context.irBuiltIns.unitType ) @@ -214,11 +217,12 @@ class BodyGenerator( return irBlockBody } - private fun generateSuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktClassOrObject: KtClassOrObject) { - val classDescriptor = getOrFail(BindingContext.CLASS, ktClassOrObject) + private fun generateSuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktClassOrObject: KtPureClassOrObject) { + val classDescriptor = ktClassOrObject.findClassDescriptor(context.bindingContext) when (classDescriptor.kind) { - ClassKind.ENUM_CLASS -> generateEnumSuperConstructorCall(irBlockBody, ktClassOrObject, classDescriptor) + // enums can't be synthetic + ClassKind.ENUM_CLASS -> generateEnumSuperConstructorCall(irBlockBody, ktClassOrObject as KtClassOrObject, classDescriptor) ClassKind.ENUM_ENTRY -> { irBlockBody.statements.add( @@ -229,7 +233,8 @@ class BodyGenerator( else -> { val statementGenerator = createStatementGenerator() - ktClassOrObject.getSuperTypeList()?.let { ktSuperTypeList -> + // synthetic inheritance is not supported yet + (ktClassOrObject as? KtClassOrObject)?.getSuperTypeList()?.let { ktSuperTypeList -> for (ktSuperTypeListEntry in ktSuperTypeList.entries) { if (ktSuperTypeListEntry is KtSuperTypeCallEntry) { val superConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktSuperTypeListEntry)!!) @@ -253,11 +258,11 @@ class BodyGenerator( } } - private fun generateAnySuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktElement: KtElement) { + private fun generateAnySuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktElement: KtPureElement) { val anyConstructor = context.builtIns.any.constructors.single() irBlockBody.statements.add( IrDelegatingConstructorCallImpl( - ktElement.startOffset, ktElement.endOffset, + ktElement.pureStartOffset, ktElement.pureEndOffset, context.irBuiltIns.unitType, context.symbolTable.referenceConstructor(anyConstructor), anyConstructor 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 3358be3d560..e63d69602cb 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 @@ -31,11 +31,17 @@ import org.jetbrains.kotlin.ir.util.referenceFunction import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry import org.jetbrains.kotlin.psi.KtEnumEntry +import org.jetbrains.kotlin.psi.KtPureClassOrObject import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.psi.psiUtil.pureEndOffset +import org.jetbrains.kotlin.psi.psiUtil.pureStartOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor +import org.jetbrains.kotlin.psi.synthetics.findClassDescriptor import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeProjectionImpl import org.jetbrains.kotlin.types.TypeSubstitutor @@ -47,10 +53,10 @@ class ClassGenerator( declarationGenerator: DeclarationGenerator ) : DeclarationGeneratorExtension(declarationGenerator) { - fun generateClass(ktClassOrObject: KtClassOrObject): IrClass { - val classDescriptor = getOrFail(BindingContext.CLASS, ktClassOrObject) - val startOffset = ktClassOrObject.startOffset - val endOffset = ktClassOrObject.endOffset + fun generateClass(ktClassOrObject: KtPureClassOrObject): IrClass { + val classDescriptor = ktClassOrObject.findClassDescriptor(this.context.bindingContext) + val startOffset = ktClassOrObject.pureStartOffset + val endOffset = ktClassOrObject.pureEndOffset return context.symbolTable.declareClass( startOffset, endOffset, IrDeclarationOrigin.DEFINED, classDescriptor @@ -73,13 +79,14 @@ class ClassGenerator( generateDeclarationsForPrimaryConstructorParameters(irClass, irPrimaryConstructor, ktClassOrObject) } - generateMembersDeclaredInSupertypeList(irClass, ktClassOrObject) + if (ktClassOrObject is KtClassOrObject) //todo: supertype list for synthetic declarations + generateMembersDeclaredInSupertypeList(irClass, ktClassOrObject) generateMembersDeclaredInClassBody(irClass, ktClassOrObject) generateFakeOverrideMemberDeclarations(irClass, ktClassOrObject) - if (irClass.isData) { + if (irClass.isData && ktClassOrObject is KtClassOrObject) { generateAdditionalMembersForDataClass(irClass, ktClassOrObject) } @@ -89,7 +96,7 @@ class ClassGenerator( } } - private fun generateFakeOverrideMemberDeclarations(irClass: IrClass, ktClassOrObject: KtClassOrObject) { + private fun generateFakeOverrideMemberDeclarations(irClass: IrClass, ktClassOrObject: KtPureClassOrObject) { irClass.descriptor.unsubstitutedMemberScope.getContributedDescriptors() .mapNotNull { it.safeAs().takeIf { @@ -317,7 +324,7 @@ class ClassGenerator( EnumClassMembersGenerator(declarationGenerator).generateSpecialMembers(irClass) } - private fun generatePrimaryConstructor(irClass: IrClass, ktClassOrObject: KtClassOrObject): IrConstructor? { + private fun generatePrimaryConstructor(irClass: IrClass, ktClassOrObject: KtPureClassOrObject): IrConstructor? { val classDescriptor = irClass.descriptor val primaryConstructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor ?: return null @@ -331,7 +338,7 @@ class ClassGenerator( private fun generateDeclarationsForPrimaryConstructorParameters( irClass: IrClass, irPrimaryConstructor: IrConstructor, - ktClassOrObject: KtClassOrObject + ktClassOrObject: KtPureClassOrObject ) { ktClassOrObject.primaryConstructor?.let { ktPrimaryConstructor -> irPrimaryConstructor.valueParameters.forEach { @@ -349,12 +356,23 @@ class ClassGenerator( } } - private fun generateMembersDeclaredInClassBody(irClass: IrClass, ktClassOrObject: KtClassOrObject) { + private fun generateMembersDeclaredInClassBody(irClass: IrClass, ktClassOrObject: KtPureClassOrObject) { + // generate real body declarations ktClassOrObject.getBody()?.let { ktClassBody -> ktClassBody.declarations.mapTo(irClass.declarations) { ktDeclaration -> declarationGenerator.generateClassMemberDeclaration(ktDeclaration, irClass.descriptor) } } + + // generate synthetic nested classes (including companion) + irClass.descriptor + .unsubstitutedMemberScope + .getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, MemberScope.ALL_NAME_FILTER) + .asSequence() + .filterIsInstance() + .mapTo(irClass.declarations) { declarationGenerator.generateSyntheticClassOrObject(it.syntheticDeclaration) } + + // synthetic functions and properties to classes must be contributed by corresponding lowering } fun generateEnumEntry(ktEnumEntry: KtEnumEntry): IrEnumEntry { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt index 4ba2410311a..3b0791ccc40 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt @@ -28,6 +28,8 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi2ir.endOffsetOrUndefined +import org.jetbrains.kotlin.psi2ir.pureEndOffsetOrUndefined +import org.jetbrains.kotlin.psi2ir.pureStartOffsetOrUndefined import org.jetbrains.kotlin.psi2ir.startOffsetOrUndefined import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils @@ -56,6 +58,10 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator { ) } + fun generateSyntheticClassOrObject(syntheticDeclaration: KtPureClassOrObject): IrClass { + return generateClassOrObjectDeclaration(syntheticDeclaration) + } + fun generateClassMemberDeclaration(ktDeclaration: KtDeclaration, classDescriptor: ClassDescriptor): IrDeclaration = when (ktDeclaration) { is KtAnonymousInitializer -> @@ -71,7 +77,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator { private fun generateEnumEntryDeclaration(ktEnumEntry: KtEnumEntry): IrEnumEntry = ClassGenerator(this).generateEnumEntry(ktEnumEntry) - fun generateClassOrObjectDeclaration(ktClassOrObject: KtClassOrObject): IrClass = + fun generateClassOrObjectDeclaration(ktClassOrObject: KtPureClassOrObject): IrClass = ClassGenerator(this).generateClass(ktClassOrObject) private fun generateTypeAliasDeclaration(ktDeclaration: KtTypeAlias): IrDeclaration = @@ -135,7 +141,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator { fun generateInitializerBody(scopeOwnerSymbol: IrSymbol, ktBody: KtExpression): IrExpressionBody = createBodyGenerator(scopeOwnerSymbol).generateExpressionBody(ktBody) - fun generateFakeOverrideDeclaration(memberDescriptor: CallableMemberDescriptor, ktElement: KtElement): IrDeclaration { + fun generateFakeOverrideDeclaration(memberDescriptor: CallableMemberDescriptor, ktElement: KtPureElement): IrDeclaration { assert(memberDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { "Fake override expected: $memberDescriptor" } @@ -149,9 +155,9 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator { } } - private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtElement): IrProperty { - val startOffset = ktElement.startOffset - val endOffset = ktElement.endOffset + private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtPureElement): IrProperty { + val startOffset = ktElement.pureStartOffsetOrUndefined + val endOffset = ktElement.pureEndOffsetOrUndefined val backingField = if (propertyDescriptor.getter == null) @@ -173,7 +179,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator { ) } - private fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement): IrSimpleFunction = + private fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtPureElement): IrSimpleFunction = FunctionGenerator(this).generateFakeOverrideFunction(functionDescriptor, ktElement) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt index cd2ba6f04ed..8f17c62fe8b 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt @@ -25,10 +25,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.psi.psiUtil.pureEndOffset +import org.jetbrains.kotlin.psi.psiUtil.pureStartOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset -import org.jetbrains.kotlin.psi2ir.endOffsetOrUndefined -import org.jetbrains.kotlin.psi2ir.isConstructorDelegatingToSuper -import org.jetbrains.kotlin.psi2ir.startOffsetOrUndefined +import org.jetbrains.kotlin.psi2ir.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -58,7 +58,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio generateLambdaBody(ktFunction) } - fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement): IrSimpleFunction = + fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtPureElement): IrSimpleFunction = declareSimpleFunctionInner(functionDescriptor, ktElement, IrDeclarationOrigin.FAKE_OVERRIDE).buildWithScope { irFunction -> generateFunctionParameterDeclarationsAndReturnType(irFunction, ktElement, null) } @@ -77,17 +77,17 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio private fun declareSimpleFunctionInner( descriptor: FunctionDescriptor, - ktElement: KtElement, + ktElement: KtPureElement, origin: IrDeclarationOrigin ): IrSimpleFunction = context.symbolTable.declareSimpleFunctionWithOverrides( - ktElement.startOffset, ktElement.endOffset, origin, + ktElement.pureStartOffset, ktElement.pureEndOffset, origin, descriptor ) fun generateFunctionParameterDeclarationsAndReturnType( irFunction: IrFunction, - ktParameterOwner: KtElement?, + ktParameterOwner: KtPureElement?, ktReceiverParameterElement: KtElement? ) { declarationGenerator.generateScopedTypeParameterDeclarations(irFunction, irFunction.descriptor.propertyIfAccessor.typeParameters) @@ -208,7 +208,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio fun generatePrimaryConstructor( primaryConstructorDescriptor: ClassConstructorDescriptor, - ktClassOrObject: KtClassOrObject + ktClassOrObject: KtPureClassOrObject ): IrConstructor = declareConstructor(ktClassOrObject, ktClassOrObject.primaryConstructor ?: ktClassOrObject, primaryConstructorDescriptor) { if ( @@ -233,13 +233,13 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio private inline fun declareConstructor( - ktConstructorElement: KtElement, - ktParametersElement: KtElement, + ktConstructorElement: KtPureElement, + ktParametersElement: KtPureElement, constructorDescriptor: ClassConstructorDescriptor, generateBody: BodyGenerator.() -> IrBody? ): IrConstructor = context.symbolTable.declareConstructor( - ktConstructorElement.startOffset, ktConstructorElement.endOffset, IrDeclarationOrigin.DEFINED, + ktConstructorElement.pureStartOffset, ktConstructorElement.pureEndOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor ).buildWithScope { irConstructor -> generateValueParameterDeclarations(irConstructor, ktParametersElement, null) @@ -254,8 +254,8 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio private fun generateValueParameterDeclarations( irFunction: IrFunction, - ktParameterOwner: KtElement?, - ktReceiverParameterElement: KtElement?, + ktParameterOwner: KtPureElement?, + ktReceiverParameterElement: KtPureElement?, withDefaultValues: Boolean = true ) { val functionDescriptor = irFunction.descriptor @@ -291,13 +291,13 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio private fun generateReceiverParameterDeclaration( receiverParameterDescriptor: ReceiverParameterDescriptor, - ktElement: KtElement? + ktElement: KtPureElement? ): IrValueParameter = declareParameter(receiverParameterDescriptor, ktElement) - private fun declareParameter(descriptor: ParameterDescriptor, ktElement: KtElement?) = + private fun declareParameter(descriptor: ParameterDescriptor, ktElement: KtPureElement?) = context.symbolTable.declareValueParameter( - ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, + ktElement.pureStartOffsetOrUndefined, ktElement.pureEndOffsetOrUndefined, IrDeclarationOrigin.DEFINED, descriptor, descriptor.type.toIrType(), (descriptor as? ValueParameterDescriptor)?.varargElementType?.toIrType() diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt index 5953c9dd732..a8d710fd58f 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt @@ -67,7 +67,7 @@ abstract class KtClassOrObject : fun getAnonymousInitializers(): List = getBody()?.anonymousInitializers.orEmpty() - fun getBody(): KtClassBody? = getStubOrPsiChild(KtStubElementTypes.CLASS_BODY) + override fun getBody(): KtClassBody? = getStubOrPsiChild(KtStubElementTypes.CLASS_BODY) inline fun addDeclaration(declaration: T): T { val body = getOrCreateBody() diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtPureClassOrObject.java b/compiler/psi/src/org/jetbrains/kotlin/psi/KtPureClassOrObject.java index 1c1d7d9bfa7..4f4fd8edc46 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtPureClassOrObject.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtPureClassOrObject.java @@ -57,5 +57,8 @@ public interface KtPureClassOrObject extends KtPureElement, KtDeclarationContain @NotNull @ReadOnly List getSecondaryConstructors(); + + @Nullable + KtClassBody getBody(); } diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/psiUtil/psiUtils.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/psiUtil/psiUtils.kt index 9b5b735e826..c8ebcaff7bf 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/psiUtil/psiUtils.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/psiUtil/psiUtils.kt @@ -26,10 +26,7 @@ import com.intellij.psi.search.SearchScope import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtFileAnnotationList -import org.jetbrains.kotlin.psi.KtModifierList -import org.jetbrains.kotlin.psi.KtModifierListOwner +import org.jetbrains.kotlin.psi.* import java.util.* // NOTE: in this file we collect only LANGUAGE INDEPENDENT methods working with PSI and not modifying it @@ -294,6 +291,13 @@ val PsiElement.startOffset: Int val PsiElement.endOffset: Int get() = textRange.endOffset +val KtPureElement.pureStartOffset: Int + get() = psiOrParent.textRange.startOffset + +val KtPureElement.pureEndOffset: Int + get() = psiOrParent.textRange.endOffset + + fun PsiElement.getStartOffsetIn(ancestor: PsiElement): Int { var offset = 0 var parent = this