summaryrefslogtreecommitdiff
path: root/plugins/kotlin/fir-fe10-binding/src/org/jetbrains/kotlin/idea/fir/fe10/BaseDescriptorsWrappers.kt
blob: cd45a8b534d283287441df9c9ab8364a9bbcebe7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.

package org.jetbrains.kotlin.idea.fir.fe10

import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue
import org.jetbrains.kotlin.analysis.api.annotations.*
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AbstractReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.KtPureElement
import org.jetbrains.kotlin.resolve.constants.*
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.source.toSourceElement
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.utils.addToStdlib.safeAs


/**
 * List of known problems/not-implemented:
 * - getOrigin return itself all the time. Formally it should return "unsubstituted" version of itself, but it isn't clear,
 *      if we really needed that nor how to implemented it. Btw, it is relevant only to member functions/properties (unlikely, but may be to
 *      inner classes) and not for "resulting descriptor". I.e. only class/interface type parameters could be substituted in FIR,
 *      there is no "resulting descriptor" and type arguments are passed together with the target function.
 * - equals on descriptors and type constructors. It isn't clear what type of equality we should implement,
 *      will figure that later o real cases.
 * See the functions below
 */

internal fun FE10BindingContext.containerDeclarationImplementationPostponed(): Nothing =
    implementationPostponed("It isn't clear what we really need and how to implement it")

internal fun FE10BindingContext.typeAliasImplementationPlanned(): Nothing =
    implementationPlanned("It is easy to implement, but it isn't first priority")

interface KtSymbolBasedNamed : Named {
    val ktSymbol: KtNamedSymbol
    override fun getName(): Name = ktSymbol.name
}

private fun Visibility.toDescriptorVisibility(): DescriptorVisibility =
    when (this) {
        Visibilities.Public -> DescriptorVisibilities.PUBLIC
        Visibilities.Private -> DescriptorVisibilities.PRIVATE
        Visibilities.PrivateToThis -> DescriptorVisibilities.PRIVATE_TO_THIS
        Visibilities.Protected -> DescriptorVisibilities.PROTECTED
        Visibilities.Internal -> DescriptorVisibilities.INTERNAL
        Visibilities.Local -> DescriptorVisibilities.LOCAL
        else -> error("Unknown visibility: $this")
    }

private fun KtClassKind.toDescriptorKlassKind(): ClassKind =
    when (this) {
        KtClassKind.CLASS -> ClassKind.CLASS
        KtClassKind.ENUM_CLASS -> ClassKind.ENUM_CLASS
        KtClassKind.ENUM_ENTRY -> ClassKind.ENUM_ENTRY
        KtClassKind.ANNOTATION_CLASS -> ClassKind.ANNOTATION_CLASS
        KtClassKind.OBJECT, KtClassKind.COMPANION_OBJECT, KtClassKind.ANONYMOUS_OBJECT -> ClassKind.OBJECT
        KtClassKind.INTERFACE -> ClassKind.INTERFACE
    }

private fun KtAnnotationValue.toConstantValue(): ConstantValue<*> {
    return when (this) {
        KtUnsupportedAnnotationValue -> ErrorValue.create("Unsupported annotation value")
        is KtArrayAnnotationValue -> ArrayValue(values.map { it.toConstantValue() }) { TODO() }
        is KtAnnotationApplicationValue -> TODO()
        is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> KClassValue(classId, arrayDimensions = 0)
        is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> TODO()
        is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> ErrorValue.create("Unresolved class")
        is KtEnumEntryAnnotationValue -> {
            val callableId = callableId ?: return ErrorValue.create("Unresolved enum entry")
            val classId = callableId.classId ?: return ErrorValue.create("Unresolved enum entry")
            EnumValue(classId, callableId.callableName)
        }
        is KtConstantAnnotationValue -> constantValue.toConstantValue()
    }
}

private fun KtConstantValue.toConstantValue(): ConstantValue<*> =
    when (this) {
        is KtConstantValue.KtErrorConstantValue -> ErrorValue.create(errorMessage)
        else -> when (constantValueKind) {
            ConstantValueKind.Null -> NullValue()
            ConstantValueKind.Boolean -> BooleanValue(value as Boolean)
            ConstantValueKind.Char -> CharValue(value as Char)
            ConstantValueKind.Byte -> ByteValue(value as Byte)
            ConstantValueKind.Short -> ShortValue(value as Short)
            ConstantValueKind.Int -> IntValue(value as Int)
            ConstantValueKind.Long -> LongValue(value as Long)
            ConstantValueKind.String -> StringValue(value as String)
            ConstantValueKind.Float -> FloatValue(value as Float)
            ConstantValueKind.Double -> DoubleValue(value as Double)
            ConstantValueKind.UnsignedByte -> UByteValue(value as Byte)
            ConstantValueKind.UnsignedShort -> UShortValue(value as Short)
            ConstantValueKind.UnsignedInt -> UIntValue(value as Int)
            ConstantValueKind.UnsignedLong -> ULongValue(value as Long)
            else -> error("Unexpected constant KtSimpleConstantValue: $value (class: ${value?.javaClass}")
        }
    }

abstract class KtSymbolBasedDeclarationDescriptor(val context: FE10BindingContext) : DeclarationDescriptorWithSource {
    abstract val ktSymbol: KtSymbol
    override val annotations: Annotations
        get() {
            val ktAnnotations = (ktSymbol as? KtAnnotatedSymbol)?.annotations ?: return Annotations.EMPTY
            return Annotations.create(ktAnnotations.map { KtSymbolBasedAnnotationDescriptor(it, context) })
        }

    override fun getSource(): SourceElement = ktSymbol.psi.safeAs<KtPureElement>().toSourceElement()

    override fun getContainingDeclaration(): DeclarationDescriptor {
        if (ktSymbol !is KtSymbolWithKind) error("ContainingDeclaration should be overridden")

        val containerSymbol = context.withAnalysisSession {
            (ktSymbol as KtSymbolWithKind).getContainingSymbol()
        }
        if (containerSymbol != null)
            return containerSymbol.toDeclarationDescriptor(context)

        // i.e. declaration is top-level
        return KtSymbolBasedPackageFragmentDescriptor(getPackageFqNameIfTopLevel(), context)
    }

    protected abstract fun getPackageFqNameIfTopLevel(): FqName

    private fun KtSymbol.toSignature(): IdSignature = context.ktAnalysisSessionFacade.toSignature(this)

    override fun equals(other: Any?): Boolean {
        if (other === this) return true
        if (other !is KtSymbolBasedDeclarationDescriptor) return false

        ktSymbol.psi?.let {
            return other.ktSymbol.psi == it
        }

        return ktSymbol.toSignature() == other.ktSymbol.toSignature()
    }

    override fun hashCode(): Int {
        ktSymbol.psi?.let { return it.hashCode() }
        return ktSymbol.toSignature().hashCode()
    }

    override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R = noImplementation()
    override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?): Unit = noImplementation()

    // stub for automatic Substitutable<T> implementation for all relevant subclasses
    fun substitute(substitutor: TypeSubstitutor): Nothing = noImplementation()

    protected fun noImplementation(): Nothing = context.noImplementation("ktSymbol = $ktSymbol")
    protected fun implementationPostponed(): Nothing = context.implementationPostponed("ktSymbol = $ktSymbol")
    protected fun implementationPlanned(): Nothing = context.implementationPlanned("ktSymbol = $ktSymbol")
}

class KtSymbolBasedAnnotationDescriptor(
    private val ktAnnotationCall: KtAnnotationApplication,
    val context: FE10BindingContext
) : AnnotationDescriptor {
    override val type: KotlinType
        get() = context.implementationPlanned("ktAnnotationCall = $ktAnnotationCall")

    override val fqName: FqName?
        get() = ktAnnotationCall.classId?.asSingleFqName()

    override val allValueArguments: Map<Name, ConstantValue<*>> =
        ktAnnotationCall.arguments.associate { it.name to it.expression.toConstantValue() }

    override val source: SourceElement
        get() = ktAnnotationCall.psi.toSourceElement()

}

class KtSymbolBasedClassDescriptor(override val ktSymbol: KtNamedClassOrObjectSymbol, context: FE10BindingContext) :
    KtSymbolBasedDeclarationDescriptor(context), KtSymbolBasedNamed, ClassDescriptor {

    override fun isInner(): Boolean = ktSymbol.isInner
    override fun isCompanionObject(): Boolean = ktSymbol.classKind == KtClassKind.COMPANION_OBJECT
    override fun isData(): Boolean = ktSymbol.isData
    override fun isInline(): Boolean = ktSymbol.isInline // seems like th`is `flag should be removed in favor of isValue
    override fun isValue(): Boolean = ktSymbol.isInline
    override fun isFun(): Boolean = ktSymbol.isFun

    override fun isExpect(): Boolean = implementationPostponed()
    override fun isActual(): Boolean = implementationPostponed()
    override fun isExternal(): Boolean = ktSymbol.isExternal

    override fun getVisibility(): DescriptorVisibility = ktSymbol.visibility.toDescriptorVisibility()
    override fun getModality(): Modality = ktSymbol.modality

    override fun getKind(): ClassKind = ktSymbol.classKind.toDescriptorKlassKind()

    override fun getCompanionObjectDescriptor(): ClassDescriptor? = ktSymbol.companionObject?.let {
        KtSymbolBasedClassDescriptor(it, context)
    }

    override fun getTypeConstructor(): TypeConstructor = KtSymbolBasedClassTypeConstructor(this)

    override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> = getTypeParameters(ktSymbol)

    override fun getDefaultType(): SimpleType {
        val arguments = TypeUtils.getDefaultTypeProjections(typeConstructor.parameters)
        return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
            TypeAttributes.Empty, typeConstructor, arguments, false,
            MemberScopeForKtSymbolBasedDescriptors { "ktSymbol = $ktSymbol" }
        )
    }

    override fun getThisAsReceiverParameter(): ReceiverParameterDescriptor =
        ReceiverParameterDescriptorImpl(this, ImplicitClassReceiver(this), Annotations.EMPTY)

    override fun getContextReceivers(): List<ReceiverParameterDescriptor> = implementationPlanned()

    override fun getOriginal(): ClassDescriptor = this

    override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = context.withAnalysisSession {
        ktSymbol.getDeclaredMemberScope().getConstructors().firstOrNull { it.isPrimary }
            ?.let { KtSymbolBasedConstructorDescriptor(it, this@KtSymbolBasedClassDescriptor) }
    }

    @OptIn(ExperimentalStdlibApi::class)
    override fun getConstructors(): Collection<ClassConstructorDescriptor> = context.withAnalysisSession {
        ktSymbol.getDeclaredMemberScope().getConstructors().map {
            KtSymbolBasedConstructorDescriptor(it, this@KtSymbolBasedClassDescriptor)
        }.toList()
    }

    override fun getPackageFqNameIfTopLevel(): FqName = (ktSymbol.classIdIfNonLocal ?: error("should be top-level")).packageFqName

    override fun getSealedSubclasses(): Collection<ClassDescriptor> = implementationPostponed()

    override fun getValueClassRepresentation(): ValueClassRepresentation<SimpleType> = TODO("Not yet implemented")

    override fun getMemberScope(typeArguments: MutableList<out TypeProjection>): MemberScope = noImplementation()
    override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope = noImplementation()
    override fun getUnsubstitutedMemberScope(): MemberScope = noImplementation()
    override fun getUnsubstitutedInnerClassesScope(): MemberScope = noImplementation()
    override fun getStaticScope(): MemberScope = noImplementation()

    override fun isDefinitelyNotSamInterface(): Boolean = noImplementation()
    override fun getDefaultFunctionTypeForSamInterface(): SimpleType = noImplementation()
}

class KtSymbolBasedTypeParameterDescriptor(
    override val ktSymbol: KtTypeParameterSymbol, context: FE10BindingContext
) : KtSymbolBasedDeclarationDescriptor(context), KtSymbolBasedNamed, TypeParameterDescriptor {
    override fun isReified(): Boolean = ktSymbol.isReified
    override fun getVariance(): Variance = ktSymbol.variance

    override fun getTypeConstructor(): TypeConstructor = KtSymbolBasedTypeParameterTypeConstructor(this)

    override fun getDefaultType(): SimpleType =
        KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
            TypeAttributes.Empty, typeConstructor, emptyList(), false,
            MemberScopeForKtSymbolBasedDescriptors { "ktSymbol = $ktSymbol" }
        )

    override fun getUpperBounds(): List<KotlinType> = ktSymbol.upperBounds.map { it.toKotlinType(context) }
    override fun getOriginal(): TypeParameterDescriptor = this

    override fun getContainingDeclaration(): DeclarationDescriptor = context.containerDeclarationImplementationPostponed()
    override fun getPackageFqNameIfTopLevel(): FqName = error("Should be called")

    // there is no such thing in FIR, and it seems like it isn't really needed for IDE and could be bypassed on client site
    override fun getIndex(): Int = implementationPostponed()

    override fun isCapturedFromOuterDeclaration(): Boolean = noImplementation()
    override fun getStorageManager(): StorageManager = noImplementation()
}

abstract class KtSymbolBasedFunctionLikeDescriptor(context: FE10BindingContext) :
    KtSymbolBasedDeclarationDescriptor(context), FunctionDescriptor {
    abstract override val ktSymbol: KtFunctionLikeSymbol

    override fun getReturnType(): KotlinType = ktSymbol.returnType.toKotlinType(context)

    override fun getValueParameters(): List<ValueParameterDescriptor> = ktSymbol.valueParameters.mapIndexed { index, it ->
        KtSymbolBasedValueParameterDescriptor(it, context,this, index)
    }

    override fun hasStableParameterNames(): Boolean = implementationPostponed()
    override fun hasSynthesizedParameterNames(): Boolean = implementationPostponed()
    override fun getKind(): CallableMemberDescriptor.Kind = implementationPostponed()

    override fun <V : Any?> getUserData(key: CallableDescriptor.UserDataKey<V>?): V? = null

    override fun getOriginal(): FunctionDescriptor = this

    override fun isHiddenForResolutionEverywhereBesideSupercalls(): Boolean = implementationPostponed()

    override fun getInitialSignatureDescriptor(): FunctionDescriptor? = noImplementation()
    override fun isHiddenToOvercomeSignatureClash(): Boolean = noImplementation()

    override fun setOverriddenDescriptors(overriddenDescriptors: MutableCollection<out CallableMemberDescriptor>) = noImplementation()
    override fun newCopyBuilder(): FunctionDescriptor.CopyBuilder<out FunctionDescriptor> = noImplementation()
    override fun copy(
        newOwner: DeclarationDescriptor?,
        modality: Modality?,
        visibility: DescriptorVisibility?,
        kind: CallableMemberDescriptor.Kind?,
        copyOverrides: Boolean
    ): FunctionDescriptor = noImplementation()
}

class KtSymbolBasedFunctionDescriptor(override val ktSymbol: KtFunctionSymbol, context: FE10BindingContext) :
    KtSymbolBasedFunctionLikeDescriptor(context),
    SimpleFunctionDescriptor,
    KtSymbolBasedNamed {
    override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = getExtensionReceiverParameter(ktSymbol)
    override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = getDispatchReceiverParameter(ktSymbol)
    override fun getContextReceiverParameters(): List<ReceiverParameterDescriptor> = implementationPlanned()

    override fun getPackageFqNameIfTopLevel(): FqName = (ktSymbol.callableIdIfNonLocal ?: error("should be top-level")).packageName

    override fun isSuspend(): Boolean = ktSymbol.isSuspend
    override fun isOperator(): Boolean = ktSymbol.isOperator
    override fun isExternal(): Boolean = ktSymbol.isExternal
    override fun isInline(): Boolean = ktSymbol.isInline
    override fun isInfix(): Boolean = implementationPostponed()
    override fun isTailrec(): Boolean = implementationPostponed()

    override fun isExpect(): Boolean = context.incorrectImplementation { false }
    override fun isActual(): Boolean = context.incorrectImplementation { false }

    override fun getVisibility(): DescriptorVisibility = ktSymbol.visibility.toDescriptorVisibility()
    override fun getModality(): Modality = ktSymbol.modality

    override fun getTypeParameters(): List<TypeParameterDescriptor> = getTypeParameters(ktSymbol)

    override fun getOverriddenDescriptors(): Collection<FunctionDescriptor> {
        val overriddenKtSymbols = context.withAnalysisSession {
            ktSymbol.getAllOverriddenSymbols()
        }

        return overriddenKtSymbols.map { KtSymbolBasedFunctionDescriptor(it as KtFunctionSymbol, context) }
    }

    override fun copy(
        newOwner: DeclarationDescriptor?,
        modality: Modality?,
        visibility: DescriptorVisibility?,
        kind: CallableMemberDescriptor.Kind?,
        copyOverrides: Boolean
    ): SimpleFunctionDescriptor = context.noImplementation()

    override fun getOriginal(): SimpleFunctionDescriptor = context.incorrectImplementation { this }

    override fun newCopyBuilder(): FunctionDescriptor.CopyBuilder<out SimpleFunctionDescriptor> =
        context.noImplementation()
}

class KtSymbolBasedConstructorDescriptor(
    override val ktSymbol: KtConstructorSymbol,
    private val ktSBClassDescriptor: KtSymbolBasedClassDescriptor
) : KtSymbolBasedFunctionLikeDescriptor(ktSBClassDescriptor.context),
    ClassConstructorDescriptor {
    override fun getName(): Name = Name.special("<init>")

    override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = null
    override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = getDispatchReceiverParameter(ktSymbol)
    override fun getContextReceiverParameters(): List<ReceiverParameterDescriptor> = ktSBClassDescriptor.contextReceivers

    override fun getConstructedClass(): ClassDescriptor = ktSBClassDescriptor
    override fun getContainingDeclaration(): ClassDescriptor = ktSBClassDescriptor
    override fun getPackageFqNameIfTopLevel(): FqName = error("should not be called")

    override fun isPrimary(): Boolean = ktSymbol.isPrimary

    override fun getReturnType(): KotlinType = ktSBClassDescriptor.defaultType

    override fun isSuspend(): Boolean = false
    override fun isOperator(): Boolean = false
    override fun isExternal(): Boolean = false
    override fun isInline(): Boolean = false
    override fun isInfix(): Boolean = false
    override fun isTailrec(): Boolean = false

    override fun isExpect(): Boolean = implementationPostponed()
    override fun isActual(): Boolean = implementationPostponed()

    override fun getVisibility(): DescriptorVisibility = ktSymbol.visibility.toDescriptorVisibility()
    override fun getModality(): Modality = Modality.FINAL

    override fun getTypeParameters(): List<TypeParameterDescriptor> = getTypeParameters(ktSymbol)

    override fun getOriginal(): ClassConstructorDescriptor = this

    override fun getOverriddenDescriptors(): Collection<FunctionDescriptor> = emptyList()

    override fun copy(
        newOwner: DeclarationDescriptor,
        modality: Modality,
        visibility: DescriptorVisibility,
        kind: CallableMemberDescriptor.Kind,
        copyOverrides: Boolean
    ): ClassConstructorDescriptor = noImplementation()
}

class KtSymbolBasedAnonymousFunctionDescriptor(
    override val ktSymbol: KtAnonymousFunctionSymbol,
    context: FE10BindingContext
) : KtSymbolBasedFunctionLikeDescriptor(context), SimpleFunctionDescriptor {
    override fun getName(): Name = SpecialNames.ANONYMOUS

    override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = getExtensionReceiverParameter(ktSymbol)
    override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = null
    override fun getContextReceiverParameters(): List<ReceiverParameterDescriptor> = implementationPlanned()

    override fun getPackageFqNameIfTopLevel(): FqName = error("Impossible to be a top-level declaration")

    override fun isOperator(): Boolean = false
    override fun isExternal(): Boolean = false
    override fun isInline(): Boolean = false
    override fun isInfix(): Boolean = false
    override fun isTailrec(): Boolean = false
    override fun isExpect(): Boolean = false
    override fun isActual(): Boolean = false

    override fun getVisibility(): DescriptorVisibility = DescriptorVisibilities.LOCAL
    override fun getModality(): Modality = Modality.FINAL
    override fun getTypeParameters(): List<TypeParameterDescriptor> = emptyList()

    // it doesn't seems like isSuspend are used in FIR for anonymous functions, but it used in FIR2IR so if we really need that
    // we could implement that later
    override fun isSuspend(): Boolean = implementationPostponed()

    override fun getOverriddenDescriptors(): Collection<FunctionDescriptor> = emptyList()

    override fun copy(
        newOwner: DeclarationDescriptor?,
        modality: Modality?,
        visibility: DescriptorVisibility?,
        kind: CallableMemberDescriptor.Kind?,
        copyOverrides: Boolean
    ): SimpleFunctionDescriptor = noImplementation()

    override fun getOriginal(): SimpleFunctionDescriptor = this

    override fun newCopyBuilder(): FunctionDescriptor.CopyBuilder<out SimpleFunctionDescriptor> = noImplementation()
}

private fun KtSymbolBasedDeclarationDescriptor.getDispatchReceiverParameter(ktSymbol: KtCallableSymbol): ReceiverParameterDescriptor? {
    val ktDispatchTypeAndAnnotations = context.withAnalysisSession { ktSymbol.getDispatchReceiverType() } ?: return null
    return KtSymbolStubDispatchReceiverParameterDescriptor(ktDispatchTypeAndAnnotations, context)
}

private fun <T> T.getExtensionReceiverParameter(
    ktSymbol: KtCallableSymbol,
): ReceiverParameterDescriptor? where T : KtSymbolBasedDeclarationDescriptor, T : CallableDescriptor {
    val receiverType = ktSymbol.receiverType ?: return null
    val receiverValue = ExtensionReceiver(this, receiverType.toKotlinType(context), null)
    return ReceiverParameterDescriptorImpl(this, receiverValue, receiverType.getDescriptorsAnnotations(context))
}

private fun KtSymbolBasedDeclarationDescriptor.getTypeParameters(ktSymbol: KtSymbolWithTypeParameters) =
    ktSymbol.typeParameters.map { KtSymbolBasedTypeParameterDescriptor(it, context) }

private class KtSymbolBasedReceiverValue(val ktType: KtType, val context: FE10BindingContext) : ReceiverValue {
    override fun getType(): KotlinType = ktType.toKotlinType(context)

    override fun replaceType(newType: KotlinType): ReceiverValue = context.noImplementation("Should be called from IDE")
    override fun getOriginal(): ReceiverValue = this
}

// Don't think that annotation is important here, because containingDeclaration used way more then annotation and they are not supported here
private class KtSymbolStubDispatchReceiverParameterDescriptor(
    val receiverType: KtType,
    val context: FE10BindingContext
) : AbstractReceiverParameterDescriptor(Annotations.EMPTY) {
    override fun getContainingDeclaration(): DeclarationDescriptor = context.containerDeclarationImplementationPostponed()

    override fun getValue(): ReceiverValue = KtSymbolBasedReceiverValue(receiverType, context)

    override fun copy(newOwner: DeclarationDescriptor): ReceiverParameterDescriptor =
        context.noImplementation("Copy should be called from IDE code")
}

class KtSymbolBasedValueParameterDescriptor(
    override val ktSymbol: KtValueParameterSymbol,
    context: FE10BindingContext,
    val containingDeclaration: KtSymbolBasedFunctionLikeDescriptor,
    index: Int = -1,
) : KtSymbolBasedDeclarationDescriptor(context), KtSymbolBasedNamed, ValueParameterDescriptor {
    override val index: Int

    init {
        if (index != -1) {
            this.index = index
        } else {
            val containerSymbol = containingDeclaration.ktSymbol
            this.index = containerSymbol.valueParameters.indexOfFirst {
                it === ktSymbol
            }
            check(this.index != -1) {
                "Parameter not found in container symbol = $containerSymbol"
            }
        }
    }

    override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = null
    override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = null
    override fun getContextReceiverParameters(): List<ReceiverParameterDescriptor> = emptyList()

    override fun getTypeParameters(): List<TypeParameterDescriptor> = emptyList()

    override fun getReturnType(): KotlinType = ktSymbol.returnType.toKotlinType(context)

    override fun getValueParameters(): List<ValueParameterDescriptor> = emptyList()
    override fun hasStableParameterNames(): Boolean = false
    override fun hasSynthesizedParameterNames(): Boolean = false

    override fun <V : Any?> getUserData(key: CallableDescriptor.UserDataKey<V>?): V? = null

    override fun getVisibility(): DescriptorVisibility = DescriptorVisibilities.LOCAL

    override fun getType(): KotlinType = ktSymbol.returnType.toKotlinType(context)
    override fun getContainingDeclaration(): CallableDescriptor = containingDeclaration
    override fun getPackageFqNameIfTopLevel(): FqName = error("Couldn't be top-level")

    override fun declaresDefaultValue(): Boolean = ktSymbol.hasDefaultValue

    override val varargElementType: KotlinType?
        get() {
            if (!ktSymbol.isVararg) return null
            return context.builtIns.getArrayElementType(type)
        }

    override fun cleanCompileTimeInitializerCache() {}

    override fun getOriginal(): ValueParameterDescriptor = context.incorrectImplementation { this }

    override fun copy(newOwner: CallableDescriptor, newName: Name, newIndex: Int): ValueParameterDescriptor =
        context.noImplementation()

    override fun getOverriddenDescriptors(): Collection<ValueParameterDescriptor> {
        return containingDeclaration.overriddenDescriptors.map { valueParameters[index] }
    }

    override val isCrossinline: Boolean
        get() = implementationPostponed()
    override val isNoinline: Boolean
        get() = implementationPostponed()

    override fun isVar(): Boolean = false
    override fun getCompileTimeInitializer(): ConstantValue<*>? = null
    override fun isConst(): Boolean = false

    override fun equals(other: Any?): Boolean {
        if (other === this) return true
        if (other !is KtSymbolBasedValueParameterDescriptor) return false
        return index == other.index && containingDeclaration == other.containingDeclaration
    }

    override fun hashCode(): Int = containingDeclaration.hashCode() * 37 + index

}

class KtSymbolBasedPropertyDescriptor(
    override val ktSymbol: KtPropertySymbol,
    context: FE10BindingContext
) : KtSymbolBasedDeclarationDescriptor(context), KtSymbolBasedNamed, PropertyDescriptor {
    override fun getPackageFqNameIfTopLevel(): FqName = (ktSymbol.callableIdIfNonLocal ?: error("should be top-level")).packageName
    override fun getOriginal(): PropertyDescriptor = context.incorrectImplementation { this }

    override fun getVisibility(): DescriptorVisibility = ktSymbol.visibility.toDescriptorVisibility()

    override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = getExtensionReceiverParameter(ktSymbol)

    override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = getDispatchReceiverParameter(ktSymbol)

    override fun getContextReceiverParameters(): List<ReceiverParameterDescriptor> = implementationPlanned()

    override fun getTypeParameters(): List<TypeParameterDescriptor> = emptyList()

    override fun getReturnType(): KotlinType = ktSymbol.returnType.toKotlinType(context)

    override fun getValueParameters(): List<ValueParameterDescriptor> = emptyList()
    override fun hasStableParameterNames(): Boolean = false
    override fun hasSynthesizedParameterNames(): Boolean = false

    override fun getOverriddenDescriptors(): Collection<PropertyDescriptor> = implementationPostponed()

    override fun <V : Any?> getUserData(key: CallableDescriptor.UserDataKey<V>?): V? = null

    override fun getType(): KotlinType = ktSymbol.returnType.toKotlinType(context)

    override fun isVar(): Boolean = !ktSymbol.isVal

    override fun getCompileTimeInitializer(): ConstantValue<*>? {
        val constantInitializer = ktSymbol.initializer as? KtConstantInitializerValue ?: return null
        return constantInitializer.constant.toConstantValue()
    }

    override fun cleanCompileTimeInitializerCache() {}

    override fun isConst(): Boolean = ktSymbol.initializer != null

    override fun isLateInit(): Boolean = implementationPostponed()

    override fun getModality(): Modality = implementationPlanned()

    override fun isExpect(): Boolean = implementationPostponed()
    override fun isActual(): Boolean = implementationPostponed()
    override fun isExternal(): Boolean = implementationPlanned()

    override fun getInType(): KotlinType? = implementationPostponed()

    override fun setOverriddenDescriptors(overriddenDescriptors: MutableCollection<out CallableMemberDescriptor>) =
        noImplementation()

    override fun getKind(): CallableMemberDescriptor.Kind = implementationPlanned()

    override fun copy(
        newOwner: DeclarationDescriptor?,
        modality: Modality?,
        visibility: DescriptorVisibility?,
        kind: CallableMemberDescriptor.Kind?,
        copyOverrides: Boolean
    ): CallableMemberDescriptor = noImplementation()

    override fun newCopyBuilder(): CallableMemberDescriptor.CopyBuilder<out PropertyDescriptor> = noImplementation()

    override fun isSetterProjectedOut(): Boolean = implementationPostponed()

    override fun getAccessors(): List<PropertyAccessorDescriptor> = listOfNotNull(getter, setter)

    override fun getBackingField(): FieldDescriptor? = implementationPostponed()
    override fun getDelegateField(): FieldDescriptor? = implementationPostponed()
    override val isDelegated: Boolean
        get() = implementationPostponed()

    override val getter: PropertyGetterDescriptor?
        get() = ktSymbol.getter?.let { KtSymbolBasedPropertyGetterDescriptor(it, this) }

    override val setter: PropertySetterDescriptor?
        get() = ktSymbol.setter?.let { KtSymbolBasedPropertySetterDescriptor(it, this) }
}

abstract class KtSymbolBasedVariableAccessorDescriptor(
    val propertyDescriptor: KtSymbolBasedPropertyDescriptor
) : KtSymbolBasedDeclarationDescriptor(propertyDescriptor.context), VariableAccessorDescriptor {
    override abstract val ktSymbol: KtPropertyAccessorSymbol

    override fun getPackageFqNameIfTopLevel(): FqName = error("should be called")
    override fun getContainingDeclaration(): DeclarationDescriptor = propertyDescriptor
    override val correspondingVariable: VariableDescriptorWithAccessors
        get() = propertyDescriptor

    override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = propertyDescriptor.extensionReceiverParameter
    override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = propertyDescriptor.dispatchReceiverParameter
    override fun getContextReceiverParameters(): List<ReceiverParameterDescriptor> = propertyDescriptor.contextReceiverParameters

    override fun getTypeParameters(): List<TypeParameterDescriptor> = emptyList()

    override fun getValueParameters(): List<ValueParameterDescriptor> = emptyList()
    override fun hasStableParameterNames(): Boolean = false
    override fun hasSynthesizedParameterNames(): Boolean = false
    override fun <V : Any?> getUserData(key: CallableDescriptor.UserDataKey<V>?): V? = null

    override fun setOverriddenDescriptors(overriddenDescriptors: MutableCollection<out CallableMemberDescriptor>) =
        noImplementation()

    override fun getKind(): CallableMemberDescriptor.Kind = propertyDescriptor.kind
    override fun getVisibility(): DescriptorVisibility = propertyDescriptor.visibility

    override fun getInitialSignatureDescriptor(): FunctionDescriptor? =
        noImplementation()

    override fun isHiddenToOvercomeSignatureClash(): Boolean = false

    override fun isOperator(): Boolean = false

    override fun isInfix(): Boolean = false

    override fun isInline(): Boolean = ktSymbol.isInline

    override fun isTailrec(): Boolean = false

    override fun isHiddenForResolutionEverywhereBesideSupercalls(): Boolean =
        implementationPostponed()

    override fun isSuspend(): Boolean = false

    override fun newCopyBuilder(): FunctionDescriptor.CopyBuilder<out FunctionDescriptor> =
        noImplementation()

    override fun getModality(): Modality = implementationPlanned()

    override fun isExpect(): Boolean = implementationPostponed()
    override fun isActual(): Boolean = implementationPostponed()
    override fun isExternal(): Boolean = implementationPostponed()
}

class KtSymbolBasedPropertyGetterDescriptor(
    override val ktSymbol: KtPropertyGetterSymbol,
    propertyDescriptor: KtSymbolBasedPropertyDescriptor
) : KtSymbolBasedVariableAccessorDescriptor(propertyDescriptor), PropertyGetterDescriptor {
    override fun getReturnType(): KotlinType = propertyDescriptor.returnType

    override fun getName(): Name = Name.special("<get-${propertyDescriptor.name}>")
    override fun isDefault(): Boolean = ktSymbol.isDefault

    override fun getCorrespondingProperty(): PropertyDescriptor = propertyDescriptor

    override fun copy(
        newOwner: DeclarationDescriptor?,
        modality: Modality?,
        visibility: DescriptorVisibility?,
        kind: CallableMemberDescriptor.Kind?,
        copyOverrides: Boolean
    ): PropertyAccessorDescriptor = noImplementation()

    override fun getOriginal(): PropertyGetterDescriptor = context.incorrectImplementation { this }
    override fun getOverriddenDescriptors(): Collection<PropertyGetterDescriptor> = implementationPostponed()
}

class KtSymbolBasedPropertySetterDescriptor(
    override val ktSymbol: KtPropertySetterSymbol,
    propertyDescriptor: KtSymbolBasedPropertyDescriptor
) : KtSymbolBasedVariableAccessorDescriptor(propertyDescriptor), PropertySetterDescriptor {
    override fun getReturnType(): KotlinType = propertyDescriptor.returnType

    override fun getName(): Name = Name.special("<set-${propertyDescriptor.name}>")
    override fun isDefault(): Boolean = ktSymbol.isDefault

    override fun getCorrespondingProperty(): PropertyDescriptor = propertyDescriptor

    override fun copy(
        newOwner: DeclarationDescriptor?,
        modality: Modality?,
        visibility: DescriptorVisibility?,
        kind: CallableMemberDescriptor.Kind?,
        copyOverrides: Boolean
    ): PropertyAccessorDescriptor = noImplementation()

    override fun getOriginal(): PropertySetterDescriptor = context.incorrectImplementation { this }
    override fun getOverriddenDescriptors(): Collection<PropertySetterDescriptor> = implementationPostponed()
}

class KtSymbolBasedPackageFragmentDescriptor(
    override val fqName: FqName,
    val context: FE10BindingContext
) : PackageFragmentDescriptor {

    override fun getName(): Name = fqName.shortName()

    override fun getOriginal(): DeclarationDescriptorWithSource = this

    override fun getSource(): SourceElement = SourceElement.NO_SOURCE

    override val annotations: Annotations
        get() = Annotations.EMPTY

    override fun getContainingDeclaration(): ModuleDescriptor = context.moduleDescriptor

    override fun getMemberScope(): MemberScope = context.noImplementation()

    override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R =
        context.noImplementation("IDE shouldn't use visitor on descriptors")

    override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) =
        context.noImplementation("IDE shouldn't use visitor on descriptors")
}