KT-28324 More exact startOffset for function/constructor declarations
Function/constructor declaration start offset is the start offset of the corresponding declaration token, if available.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.psi2ir
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
@@ -32,7 +33,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.lang.Exception
|
||||
|
||||
fun KotlinType.containsNull() =
|
||||
TypeUtils.isNullableType(this)
|
||||
@@ -84,4 +84,6 @@ val PropertyDescriptor.unwrappedSetMethod: FunctionDescriptor?
|
||||
get() = if (this is SyntheticPropertyDescriptor) this.setMethod else setter
|
||||
|
||||
val KtPureElement?.pureStartOffsetOrUndefined get() = this?.psiOrParent?.startOffsetSkippingComments ?: UNDEFINED_OFFSET
|
||||
val KtPureElement?.pureEndOffsetOrUndefined get() = this?.psiOrParent?.endOffset ?: UNDEFINED_OFFSET
|
||||
val KtPureElement?.pureEndOffsetOrUndefined get() = this?.psiOrParent?.endOffset ?: UNDEFINED_OFFSET
|
||||
|
||||
fun KtElement.getChildTokenStartOffsetOrNull(tokenSet: TokenSet) = node.findChildByType(tokenSet)?.startOffset
|
||||
@@ -54,7 +54,7 @@ class ClassGenerator(
|
||||
|
||||
fun generateClass(ktClassOrObject: KtPureClassOrObject): IrClass {
|
||||
val classDescriptor = ktClassOrObject.findClassDescriptor(this.context.bindingContext)
|
||||
val startOffset = ktClassOrObject.pureStartOffset
|
||||
val startOffset = ktClassOrObject.getStartOffsetOfClassDeclarationKeywordOrNull() ?: ktClassOrObject.pureStartOffset
|
||||
val endOffset = ktClassOrObject.pureEndOffset
|
||||
|
||||
return context.symbolTable.declareClass(
|
||||
@@ -138,7 +138,7 @@ class ClassGenerator(
|
||||
val superType = getOrFail(BindingContext.TYPE, ktEntry.typeReference!!)
|
||||
val superTypeConstructorDescriptor = superType.constructor.declarationDescriptor
|
||||
val superClass = superTypeConstructorDescriptor as? ClassDescriptor
|
||||
?: throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor")
|
||||
?: throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor")
|
||||
val delegateDescriptor = IrImplementingDelegateDescriptorImpl(irClass.descriptor, delegateType, superType)
|
||||
val irDelegateField = context.symbolTable.declareField(
|
||||
ktDelegateExpression.startOffsetSkippingComments, ktDelegateExpression.endOffset,
|
||||
|
||||
+39
-31
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
@@ -24,13 +25,9 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
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.startOffsetSkippingComments
|
||||
import org.jetbrains.kotlin.psi2ir.isConstructorDelegatingToSuper
|
||||
import org.jetbrains.kotlin.psi2ir.pureEndOffsetOrUndefined
|
||||
import org.jetbrains.kotlin.psi2ir.pureStartOffsetOrUndefined
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -83,7 +80,9 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
origin: IrDeclarationOrigin
|
||||
): IrSimpleFunction =
|
||||
context.symbolTable.declareSimpleFunctionWithOverrides(
|
||||
ktElement.pureStartOffset, ktElement.pureEndOffset, origin,
|
||||
ktElement.getStartOffsetOfFunctionDeclarationKeywordOrNull() ?: ktElement.pureStartOffset,
|
||||
ktElement.pureEndOffset,
|
||||
origin,
|
||||
descriptor
|
||||
)
|
||||
|
||||
@@ -115,7 +114,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
if (ktBodyExpression != null)
|
||||
createBodyGenerator(irAccessor.symbol).generateFunctionBody(ktBodyExpression)
|
||||
else
|
||||
generateDefaultAccessorBody(ktProperty, descriptor, irAccessor)
|
||||
generateDefaultAccessorBody(descriptor, irAccessor)
|
||||
}
|
||||
|
||||
fun generateDefaultAccessorForPrimaryConstructorParameter(
|
||||
@@ -126,31 +125,33 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
declarationGenerator.generateScopedTypeParameterDeclarations(irAccessor, descriptor.typeParameters)
|
||||
irAccessor.returnType = descriptor.returnType!!.toIrType()
|
||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irAccessor)
|
||||
irAccessor.body = generateDefaultAccessorBody(ktParameter, descriptor, irAccessor)
|
||||
irAccessor.body = generateDefaultAccessorBody(descriptor, irAccessor)
|
||||
}
|
||||
|
||||
private fun generateDefaultAccessorBody(ktProperty: KtElement, accessor: PropertyAccessorDescriptor, irAccessor: IrSimpleFunction) =
|
||||
private fun generateDefaultAccessorBody(
|
||||
accessor: PropertyAccessorDescriptor,
|
||||
irAccessor: IrSimpleFunction
|
||||
) =
|
||||
if (accessor.modality == Modality.ABSTRACT)
|
||||
null
|
||||
else
|
||||
when (accessor) {
|
||||
is PropertyGetterDescriptor -> generateDefaultGetterBody(ktProperty, accessor, irAccessor)
|
||||
is PropertySetterDescriptor -> generateDefaultSetterBody(ktProperty, accessor, irAccessor)
|
||||
is PropertyGetterDescriptor -> generateDefaultGetterBody(accessor, irAccessor)
|
||||
is PropertySetterDescriptor -> generateDefaultSetterBody(accessor, irAccessor)
|
||||
else -> throw AssertionError("Should be getter or setter: $accessor")
|
||||
}
|
||||
|
||||
private fun generateDefaultGetterBody(
|
||||
ktProperty: KtElement,
|
||||
getter: PropertyGetterDescriptor,
|
||||
irAccessor: IrSimpleFunction
|
||||
): IrBlockBody {
|
||||
val property = getter.correspondingProperty
|
||||
|
||||
val startOffset = ktProperty.startOffsetSkippingComments
|
||||
val endOffset = ktProperty.endOffset
|
||||
val startOffset = irAccessor.startOffset
|
||||
val endOffset = irAccessor.endOffset
|
||||
val irBody = IrBlockBodyImpl(startOffset, endOffset)
|
||||
|
||||
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
|
||||
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(property, irAccessor)
|
||||
|
||||
irBody.statements.add(
|
||||
IrReturnImpl(
|
||||
@@ -168,17 +169,16 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
}
|
||||
|
||||
private fun generateDefaultSetterBody(
|
||||
ktProperty: KtElement,
|
||||
setter: PropertySetterDescriptor,
|
||||
irAccessor: IrSimpleFunction
|
||||
): IrBlockBody {
|
||||
val property = setter.correspondingProperty
|
||||
|
||||
val startOffset = ktProperty.startOffsetSkippingComments
|
||||
val endOffset = ktProperty.endOffset
|
||||
val startOffset = irAccessor.startOffset
|
||||
val endOffset = irAccessor.endOffset
|
||||
val irBody = IrBlockBodyImpl(startOffset, endOffset)
|
||||
|
||||
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
|
||||
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(property, irAccessor)
|
||||
|
||||
val irValueParameter = irAccessor.valueParameters.single()
|
||||
irBody.statements.add(
|
||||
@@ -193,13 +193,16 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
return irBody
|
||||
}
|
||||
|
||||
private fun generateReceiverExpressionForDefaultPropertyAccessor(ktProperty: KtElement, property: PropertyDescriptor): IrExpression? {
|
||||
private fun generateReceiverExpressionForDefaultPropertyAccessor(
|
||||
property: PropertyDescriptor,
|
||||
irAccessor: IrSimpleFunction
|
||||
): IrExpression? {
|
||||
val containingDeclaration = property.containingDeclaration
|
||||
return when (containingDeclaration) {
|
||||
is ClassDescriptor -> {
|
||||
val thisAsReceiverParameter = containingDeclaration.thisAsReceiverParameter
|
||||
IrGetValueImpl(
|
||||
ktProperty.startOffsetSkippingComments, ktProperty.endOffset,
|
||||
irAccessor.startOffset, irAccessor.endOffset,
|
||||
thisAsReceiverParameter.type.toIrType(),
|
||||
context.symbolTable.referenceValue(thisAsReceiverParameter)
|
||||
)
|
||||
@@ -246,7 +249,9 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
generateBody: BodyGenerator.() -> IrBody?
|
||||
): IrConstructor =
|
||||
context.symbolTable.declareConstructor(
|
||||
ktConstructorElement.pureStartOffset, ktConstructorElement.pureEndOffset, IrDeclarationOrigin.DEFINED,
|
||||
ktConstructorElement.getStartOffsetOfConstructorDeclarationKeywordOrNull() ?: ktConstructorElement.pureStartOffset,
|
||||
ktConstructorElement.pureEndOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
constructorDescriptor
|
||||
).buildWithScope { irConstructor ->
|
||||
generateValueParameterDeclarations(irConstructor, ktParametersElement, null)
|
||||
@@ -268,17 +273,17 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
val functionDescriptor = irFunction.descriptor
|
||||
|
||||
irFunction.dispatchReceiverParameter = functionDescriptor.dispatchReceiverParameter?.let {
|
||||
generateReceiverParameterDeclaration(it, ktParameterOwner)
|
||||
generateReceiverParameterDeclaration(it, ktParameterOwner, irFunction)
|
||||
}
|
||||
|
||||
irFunction.extensionReceiverParameter = functionDescriptor.extensionReceiverParameter?.let {
|
||||
generateReceiverParameterDeclaration(it, ktReceiverParameterElement ?: ktParameterOwner)
|
||||
generateReceiverParameterDeclaration(it, ktReceiverParameterElement ?: ktParameterOwner, irFunction)
|
||||
}
|
||||
|
||||
val bodyGenerator = createBodyGenerator(irFunction.symbol)
|
||||
functionDescriptor.valueParameters.mapTo(irFunction.valueParameters) { valueParameterDescriptor ->
|
||||
val ktParameter = DescriptorToSourceUtils.getSourceFromDescriptor(valueParameterDescriptor) as? KtParameter
|
||||
generateValueParameterDeclaration(valueParameterDescriptor, ktParameter, bodyGenerator, withDefaultValues)
|
||||
generateValueParameterDeclaration(valueParameterDescriptor, ktParameter, bodyGenerator, withDefaultValues, irFunction)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,11 +291,12 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
valueParameterDescriptor: ValueParameterDescriptor,
|
||||
ktParameter: KtParameter?,
|
||||
bodyGenerator: BodyGenerator,
|
||||
withDefaultValues: Boolean
|
||||
withDefaultValues: Boolean,
|
||||
irOwnerElement: IrElement
|
||||
): IrValueParameter =
|
||||
declareParameter(valueParameterDescriptor, ktParameter).also {
|
||||
declareParameter(valueParameterDescriptor, ktParameter, irOwnerElement).also { irValueParameter ->
|
||||
if (withDefaultValues) {
|
||||
it.defaultValue = ktParameter?.defaultValue?.let {
|
||||
irValueParameter.defaultValue = ktParameter?.defaultValue?.let {
|
||||
bodyGenerator.generateExpressionBody(it)
|
||||
}
|
||||
}
|
||||
@@ -298,13 +304,15 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
|
||||
private fun generateReceiverParameterDeclaration(
|
||||
receiverParameterDescriptor: ReceiverParameterDescriptor,
|
||||
ktElement: KtPureElement?
|
||||
ktElement: KtPureElement?,
|
||||
irOwnerElement: IrElement
|
||||
): IrValueParameter =
|
||||
declareParameter(receiverParameterDescriptor, ktElement)
|
||||
declareParameter(receiverParameterDescriptor, ktElement, irOwnerElement)
|
||||
|
||||
private fun declareParameter(descriptor: ParameterDescriptor, ktElement: KtPureElement?) =
|
||||
private fun declareParameter(descriptor: ParameterDescriptor, ktElement: KtPureElement?, irOwnerElement: IrElement) =
|
||||
context.symbolTable.declareValueParameter(
|
||||
ktElement.pureStartOffsetOrUndefined, ktElement.pureEndOffsetOrUndefined,
|
||||
ktElement?.pureStartOffset ?: irOwnerElement.startOffset,
|
||||
ktElement?.pureEndOffset ?: irOwnerElement.endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
descriptor, descriptor.type.toIrType(),
|
||||
(descriptor as? ValueParameterDescriptor)?.varargElementType?.toIrType()
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.psi2ir.generators
|
||||
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi2ir.getChildTokenStartOffsetOrNull
|
||||
|
||||
private val FUNCTION_DECL_TOKENS = TokenSet.create(KtTokens.FUN_KEYWORD)
|
||||
private val ACCESSOR_DECL_TOKENS = TokenSet.create(KtTokens.GET_KEYWORD, KtTokens.SET_KEYWORD)
|
||||
private val PROPERTY_DECL_TOKENS = TokenSet.create(KtTokens.VAL_KEYWORD, KtTokens.VAR_KEYWORD)
|
||||
private val CLASS_DECL_TOKENS = TokenSet.create(KtTokens.CLASS_KEYWORD, KtTokens.INTERFACE_KEYWORD)
|
||||
private val CONSTRUCTOR_DECL_TOKENS = TokenSet.create(KtTokens.CONSTRUCTOR_KEYWORD)
|
||||
|
||||
internal fun KtPureElement.getStartOffsetOfFunctionDeclarationKeywordOrNull(): Int? =
|
||||
when (this) {
|
||||
is KtNamedFunction -> getChildTokenStartOffsetOrNull(FUNCTION_DECL_TOKENS)
|
||||
is KtPropertyAccessor -> getChildTokenStartOffsetOrNull(ACCESSOR_DECL_TOKENS)
|
||||
is KtProperty -> getChildTokenStartOffsetOrNull(PROPERTY_DECL_TOKENS)
|
||||
is KtParameter -> getChildTokenStartOffsetOrNull(PROPERTY_DECL_TOKENS)
|
||||
is KtClassOrObject -> getChildTokenStartOffsetOrNull(CLASS_DECL_TOKENS)
|
||||
else -> null
|
||||
}
|
||||
|
||||
internal fun KtPureClassOrObject.getStartOffsetOfClassDeclarationKeywordOrNull(): Int? =
|
||||
when (this) {
|
||||
is KtClassOrObject -> getChildTokenStartOffsetOrNull(CLASS_DECL_TOKENS)
|
||||
else -> null
|
||||
}
|
||||
|
||||
internal fun KtPureElement.getStartOffsetOfConstructorDeclarationKeywordOrNull(): Int? =
|
||||
when (this) {
|
||||
is KtPrimaryConstructor -> getChildTokenStartOffsetOrNull(CONSTRUCTOR_DECL_TOKENS)
|
||||
|
||||
is KtSecondaryConstructor -> getChildTokenStartOffsetOrNull(CONSTRUCTOR_DECL_TOKENS)
|
||||
|
||||
is KtClassOrObject ->
|
||||
primaryConstructor?.getStartOffsetOfConstructorDeclarationKeywordOrNull()
|
||||
?: getChildTokenStartOffsetOrNull(CONSTRUCTOR_DECL_TOKENS)
|
||||
?: getChildTokenStartOffsetOrNull(CLASS_DECL_TOKENS)
|
||||
|
||||
else -> null
|
||||
}
|
||||
Reference in New Issue
Block a user