Generate super classes and overridden functions in proper scope

Such references require proper scope so that local symbols are bound.
Example:

```
fun <T> outer() {
    abstract class ALocal<S : T> {
        abstract fun bar()
    }

    class Local<S : T> : ALocal<S>() {
        override fun bar() {}
    }
}
```

Here local classes have type parameters with upper bounds depending on
function type parameters, and members overriding members in other local
classes.
This commit is contained in:
Dmitry Petrov
2018-02-22 10:00:02 +03:00
parent 8fef0f0535
commit e89047d2cc
54 changed files with 2463 additions and 79 deletions
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.util.patchOverriddenFunctionsFromDescriptors
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
@@ -61,6 +60,5 @@ class Psi2IrTranslator(val configuration: Psi2IrConfiguration = Psi2IrConfigurat
postprocessingSteps.forEach { it.postprocess(context, irElement) }
irElement.patchDeclarationParents()
irElement.patchOverriddenFunctionsFromDescriptors(context.symbolTable)
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
import org.jetbrains.kotlin.ir.util.StableDescriptorsComparator
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
import org.jetbrains.kotlin.psi.KtEnumEntry
@@ -187,7 +188,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
}
private fun generateDelegatedFunction(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrFunction =
context.symbolTable.declareSimpleFunction(
context.symbolTable.declareSimpleFunctionWithOverrides(
irDelegate.startOffset, irDelegate.endOffset,
IrDeclarationOrigin.DELEGATED_MEMBER,
delegated
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi2ir.containsNull
@@ -48,7 +49,7 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
}
private fun declareSimpleFunction(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, function: FunctionDescriptor) =
context.symbolTable.declareSimpleFunction(startOffset, endOffset, origin, function)
context.symbolTable.declareSimpleFunctionWithOverrides(startOffset, endOffset, origin, function)
private inner class MemberFunctionBuilder(
val irClass: IrClass,
@@ -83,10 +83,24 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
val ktTypeParameterDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(typeParameterDescriptor)
val startOffset = ktTypeParameterDeclaration.startOffsetOrUndefined
val endOffset = ktTypeParameterDeclaration.endOffsetOrUndefined
context.symbolTable.declareTypeParameter(startOffset, endOffset, IrDeclarationOrigin.DEFINED, typeParameterDescriptor)
declareTypeParameterWithSuperClassifiers(startOffset, endOffset, IrDeclarationOrigin.DEFINED, typeParameterDescriptor)
}
}
private fun declareTypeParameterWithSuperClassifiers(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: TypeParameterDescriptor
) =
context.symbolTable.declareTypeParameter(startOffset, endOffset, origin, descriptor).also { irTypeParameter ->
descriptor.typeConstructor.supertypes.mapNotNullTo(irTypeParameter.superClassifiers) {
it.constructor.declarationDescriptor?.let {
context.symbolTable.referenceClassifier(it)
}
}
}
fun generateInitializerBody(scopeOwnerSymbol: IrSymbol, ktBody: KtExpression): IrExpressionBody =
createBodyGenerator(scopeOwnerSymbol).generateExpressionBody(ktBody)
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPropertyDelegate
@@ -93,7 +94,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
accessorDescriptor: PropertyAccessorDescriptor,
generateBody: (IrFunction) -> IrBody
): IrFunction =
context.symbolTable.declareSimpleFunction(
context.symbolTable.declareSimpleFunctionWithOverrides(
ktDelegate.startOffset, ktDelegate.endOffset,
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
accessorDescriptor
@@ -327,7 +328,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
ktDelegate: KtPropertyDelegate,
generateBody: (IrFunction) -> IrBody
) =
context.symbolTable.declareSimpleFunction(
context.symbolTable.declareSimpleFunctionWithOverrides(
ktDelegate.startOffset, ktDelegate.endOffset,
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
getterDescriptor
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.addMember
import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind
import org.jetbrains.kotlin.ir.expressions.impl.IrSyntheticBodyImpl
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
import org.jetbrains.kotlin.psi2ir.findFirstFunction
class EnumClassMembersGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
@@ -38,7 +39,7 @@ class EnumClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
}
irClass.addMember(
context.symbolTable.declareSimpleFunction(
context.symbolTable.declareSimpleFunctionWithOverrides(
irClass.startOffset, irClass.endOffset,
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
valuesFunction
@@ -57,7 +58,7 @@ class EnumClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
}
irClass.addMember(
context.symbolTable.declareSimpleFunction(
context.symbolTable.declareSimpleFunctionWithOverrides(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
valueOfFunction
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrBody
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.startOffset
@@ -55,7 +56,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
}
fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement): IrFunction =
context.symbolTable.declareSimpleFunction(
context.symbolTable.declareSimpleFunctionWithOverrides(
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
IrDeclarationOrigin.FAKE_OVERRIDE,
functionDescriptor
@@ -70,7 +71,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
descriptor: FunctionDescriptor,
generateBody: BodyGenerator.() -> IrBody?
): IrSimpleFunction =
context.symbolTable.declareSimpleFunction(
context.symbolTable.declareSimpleFunctionWithOverrides(
ktFunction.startOffset, ktFunction.endOffset, origin, descriptor
).buildWithScope { irFunction ->
generateFunctionParameterDeclarations(irFunction, ktFunction, ktReceiver)
@@ -91,7 +92,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
ktProperty: KtProperty,
ktAccessor: KtPropertyAccessor?
): IrSimpleFunction =
context.symbolTable.declareSimpleFunction(
context.symbolTable.declareSimpleFunctionWithOverrides(
ktAccessor?.startOffset ?: ktProperty.startOffset,
ktAccessor?.endOffset ?: ktProperty.endOffset,
if (ktAccessor != null) IrDeclarationOrigin.DEFINED else IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
@@ -110,7 +111,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
descriptor: PropertyAccessorDescriptor,
ktParameter: KtParameter
): IrFunction =
context.symbolTable.declareSimpleFunction(
context.symbolTable.declareSimpleFunctionWithOverrides(
ktParameter.startOffsetOrUndefined,
ktParameter.endOffsetOrUndefined,
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.name.Name
@@ -34,5 +35,7 @@ interface IrTypeParameter : IrSymbolDeclaration<IrTypeParameterSymbol> {
val index: Int
val upperBounds: List<KotlinType>
val superClassifiers: MutableList<IrClassifierSymbol>
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrTypeParameter
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.SmartList
class IrTypeParameterImpl(
startOffset: Int,
@@ -56,6 +58,8 @@ class IrTypeParameterImpl(
override val descriptor: TypeParameterDescriptor get() = symbol.descriptor
override val superClassifiers: MutableList<IrClassifierSymbol> = SmartList<IrClassifierSymbol>()
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitTypeParameter(this, data)
@@ -71,7 +71,7 @@ class DeclarationStubGenerator(
}
fun generateFunctionStub(descriptor: FunctionDescriptor): IrSimpleFunction =
symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original).also { irFunction ->
symbolTable.declareSimpleFunctionWithOverrides(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original).also { irFunction ->
generateTypeParameterStubs(descriptor.typeParameters, irFunction)
generateValueParametersStubs(descriptor.valueParameters, irFunction)
}
@@ -24,10 +24,8 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
@@ -188,7 +186,25 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
originalTypeParameter.startOffset, originalTypeParameter.endOffset,
mapDeclarationOrigin(originalTypeParameter.origin),
newTypeParameterDescriptor
)
).apply {
for (i in upperBounds.indices) {
val upperBoundClassifier = upperBounds[i].constructor.declarationDescriptor ?: continue
val oldSuperClassifierSymbol = originalTypeParameter.superClassifiers[i]
val newSuperClassifierSymbol =
if (upperBoundClassifier == oldSuperClassifierSymbol.descriptor)
oldSuperClassifierSymbol
else
createUnboundClassifierSymbol(upperBoundClassifier)
superClassifiers.add(newSuperClassifierSymbol)
}
}
protected fun createUnboundClassifierSymbol(classifier: ClassifierDescriptor): IrClassifierSymbol =
when (classifier) {
is TypeParameterDescriptor -> IrTypeParameterSymbolImpl(classifier)
is ClassDescriptor -> IrClassSymbolImpl(classifier)
else -> throw IllegalArgumentException("Unexpected classifier descriptor: $classifier")
}
protected fun copyValueParameter(
originalValueParameter: IrValueParameter,
@@ -196,7 +196,11 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
symbolRemapper.getDeclaredTypeParameter(declaration.symbol)
)
).apply {
declaration.superClassifiers.mapTo(superClassifiers) {
symbolRemapper.getReferencedClassifier(it)
}
}
override fun visitValueParameter(declaration: IrValueParameter): IrValueParameter =
IrValueParameterImpl(
@@ -16,10 +16,7 @@
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.descriptors.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
@@ -42,13 +39,8 @@ class DependenciesCollector {
assert(symbolTable.unboundValueParameters.isEmpty()) { "Unbound value parameters: ${symbolTable.unboundValueParameters}" }
assert(symbolTable.unboundVariables.isEmpty()) { "Unbound variables: ${symbolTable.unboundVariables}" }
for (unboundClass in symbolTable.unboundClasses.toTypedArray()) {
for (superClassifier in unboundClass.descriptor.getAllSuperClassifiers()) {
if (superClassifier is ClassDescriptor) {
symbolTable.referenceClass(superClassifier)
}
}
}
symbolTable.markOverriddenFunctionsForUnboundFunctionsReferenced()
symbolTable.markSuperClassesForUnboundClassesReferenced()
symbolTable.unboundClasses.addTopLevelDeclarations()
symbolTable.unboundConstructors.addTopLevelDeclarations()
@@ -57,14 +49,39 @@ class DependenciesCollector {
symbolTable.unboundSimpleFunctions.addTopLevelDeclarations()
}
private fun Collection<IrSymbol>.addTopLevelDeclarations() {
forEach { addTopLevelDeclaration(it) }
private fun SymbolTable.markOverriddenFunctionsForUnboundFunctionsReferenced() {
for (unboundFunction in unboundSimpleFunctions.toTypedArray()) {
markOverriddenFunctionsReferenced(unboundFunction.descriptor, HashSet())
}
}
fun addTopLevelDeclaration(symbol: IrSymbol) {
val descriptor = symbol.descriptor
val topLevelDeclaration = getTopLevelDeclaration(descriptor)
addTopLevelDescriptor(topLevelDeclaration)
private fun SymbolTable.markOverriddenFunctionsReferenced(
function: FunctionDescriptor,
visitedFunctions: MutableSet<FunctionDescriptor>
) {
for (overridden in function.overriddenDescriptors) {
if (overridden !in visitedFunctions) {
visitedFunctions.add(overridden)
referenceFunction(overridden.original)
markOverriddenFunctionsReferenced(overridden, visitedFunctions)
}
}
}
private fun SymbolTable.markSuperClassesForUnboundClassesReferenced() {
for (unboundClass in unboundClasses.toTypedArray()) {
for (superClassifier in unboundClass.descriptor.getAllSuperClassifiers()) {
if (superClassifier is ClassDescriptor) {
referenceClass(superClassifier)
}
}
}
}
private fun Collection<IrSymbol>.addTopLevelDeclarations() {
forEach {
addTopLevelDescriptor(getTopLevelDeclaration(it.descriptor))
}
}
private fun getTopLevelDeclaration(descriptor: DeclarationDescriptor): DeclarationDescriptor {
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrBindableSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -86,6 +87,12 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
}
}
override fun visitTypeParameter(declaration: IrTypeParameter, data: String) {
declaration.dumpLabeledElementWith(data) {
declaration.superClassifiers.renderDeclarationElementsOrDescriptors("superClassifiers")
}
}
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: String) {
declaration.dumpLabeledElementWith(data) {
declaration.overriddenSymbols.renderDeclarationElementsOrDescriptors("overridden")
@@ -97,9 +104,7 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
}
}
private fun <D : DeclarationDescriptor, B : IrSymbolOwner> Collection<IrBindableSymbol<D, B>>.renderDeclarationElementsOrDescriptors(
caption: String
) {
private fun Collection<IrSymbol>.renderDeclarationElementsOrDescriptors(caption: String) {
if (isNotEmpty()) {
indented(caption) {
for (symbol in this) {
@@ -109,7 +114,7 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
}
}
private fun <D : DeclarationDescriptor, B : IrSymbolOwner> IrBindableSymbol<D, B>.renderDeclarationElementOrDescriptor() {
private fun IrSymbol.renderDeclarationElementOrDescriptor() {
if (isBound)
owner.render()
else
@@ -1,34 +0,0 @@
/*
* Copyright 2000-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.ir.util
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
fun <T : IrElement> T.patchOverriddenFunctionsFromDescriptors(symbolTable: SymbolTable) =
apply {
acceptVoid(PatchOverriddenFunctionsFromDescriptorsVisitor(symbolTable))
}
class PatchOverriddenFunctionsFromDescriptorsVisitor(
private val symbolTable: SymbolTable
) : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
declaration.descriptor.overriddenDescriptors.mapTo(declaration.overriddenSymbols) {
symbolTable.referenceSimpleFunction(it.original)
}
super.visitSimpleFunction(declaration)
}
}
@@ -0,0 +1,29 @@
/*
* Copyright 2000-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.ir.util
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
fun SymbolTable.declareSimpleFunctionWithOverrides(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: FunctionDescriptor
) =
declareSimpleFunction(startOffset, endOffset, origin, descriptor).also { declaration ->
generateOverriddenSymbols(declaration, this)
}
fun generateOverriddenSymbols(
declaration: IrSimpleFunction,
symbolTable: SymbolTable
) {
declaration.descriptor.overriddenDescriptors.mapTo(declaration.overriddenSymbols) {
symbolTable.referenceSimpleFunction(it.original)
}
}