Add first prototype of BindingContext implementation by FIR
Add ImportMemberIntention intention as a test. In this commit all failed test were disabled, necessary fixes will be added in the following commits
This commit is contained in:
committed by
teamcityserver
parent
6919f3dbb5
commit
7ac599520e
+2
-1
@@ -850,7 +850,8 @@ tasks {
|
||||
":idea:idea-frontend-api:test",
|
||||
":idea:idea-frontend-fir:test",
|
||||
":idea:idea-frontend-fir:idea-fir-low-level-api:test",
|
||||
":plugins:uast-kotlin-fir:test"
|
||||
":plugins:uast-kotlin-fir:test",
|
||||
":idea:idea-fir-fe10-binding:test"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ inline val FirCall.resolvedArgumentMapping: Map<FirExpression, FirValueParameter
|
||||
else -> null
|
||||
}
|
||||
|
||||
inline val FirCall.argumentMapping: Map<FirExpression, FirValueParameter>?
|
||||
inline val FirCall.argumentMapping: LinkedHashMap<FirExpression, FirValueParameter>?
|
||||
get() = when (val argumentList = argumentList) {
|
||||
is FirResolvedArgumentList -> argumentList.mapping
|
||||
is FirPartiallyResolvedArgumentList -> argumentList.mapping
|
||||
|
||||
@@ -49,6 +49,7 @@ dependencies {
|
||||
testCompile(projectTests(":idea:idea-fir-performance-tests"))
|
||||
testCompile(projectTests(":idea:idea-frontend-fir"))
|
||||
testCompile(projectTests(":idea:idea-frontend-fir:idea-fir-low-level-api"))
|
||||
testCompile(projectTests(":idea:idea-fir-fe10-binding"))
|
||||
testCompile(projectTests(":j2k"))
|
||||
testCompile(projectTests(":nj2k"))
|
||||
if (Ide.IJ()) {
|
||||
|
||||
@@ -109,10 +109,7 @@ import org.jetbrains.kotlin.idea.highlighter.*
|
||||
import org.jetbrains.kotlin.idea.imports.AbstractJsOptimizeImportsTest
|
||||
import org.jetbrains.kotlin.idea.imports.AbstractJvmOptimizeImportsTest
|
||||
import org.jetbrains.kotlin.idea.index.AbstractKotlinTypeAliasByExpansionShortNameIndexTest
|
||||
import org.jetbrains.kotlin.idea.inspections.AbstractHLInspectionTest
|
||||
import org.jetbrains.kotlin.idea.inspections.AbstractHLLocalInspectionTest
|
||||
import org.jetbrains.kotlin.idea.inspections.AbstractLocalInspectionTest
|
||||
import org.jetbrains.kotlin.idea.inspections.AbstractMultiFileLocalInspectionTest
|
||||
import org.jetbrains.kotlin.idea.inspections.*
|
||||
import org.jetbrains.kotlin.idea.intentions.*
|
||||
import org.jetbrains.kotlin.idea.intentions.declarations.AbstractJoinLinesTest
|
||||
import org.jetbrains.kotlin.idea.internal.AbstractBytecodeToolWindowTest
|
||||
@@ -1246,6 +1243,13 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("idea/idea-fir-fe10-binding/tests", "idea") {
|
||||
testClass<AbstractFe10BindingIntentionTest> {
|
||||
val pattern = "^([\\w\\-_]+)\\.(kt|kts)$"
|
||||
model("testData/intentions/conventionNameCalls/replaceContains", pattern = pattern)
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("idea/scripting-support/test", "idea/scripting-support/testData") {
|
||||
testClass<AbstractScratchRunActionTest> {
|
||||
model(
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":idea:idea-frontend-fir"))
|
||||
|
||||
testImplementation(projectTests(":idea:idea-fir"))
|
||||
testImplementation(projectTests(":idea:idea-frontend-independent"))
|
||||
|
||||
testImplementation(intellijDep())
|
||||
testImplementation(intellijCoreDep())
|
||||
testImplementation(toolsJar())
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
testsJar()
|
||||
|
||||
projectTest {
|
||||
dependsOn(":dist")
|
||||
workingDir = rootDir
|
||||
val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin
|
||||
doFirst {
|
||||
if (!useFirIdeaPlugin) {
|
||||
error("Test task in the module should be executed with -Pidea.fir.plugin=true")
|
||||
}
|
||||
}
|
||||
}
|
||||
+742
@@ -0,0 +1,742 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.idea.fir.fe10
|
||||
|
||||
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.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.*
|
||||
import org.jetbrains.kotlin.idea.frontend.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 KtConstantValue.toConstantValue(): ConstantValue<*> =
|
||||
when (this) {
|
||||
KtUnsupportedConstantValue -> ErrorValue.create("Error value for KtUnsupportedConstantValue")
|
||||
is KtSimpleConstantValue<*> -> 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 overriden")
|
||||
|
||||
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: KtAnnotationCall,
|
||||
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 { Name.identifier(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(
|
||||
Annotations.EMPTY, typeConstructor, arguments, false,
|
||||
MemberScopeForKtSymbolBasedDescriptors { "ktSymbol = $ktSymbol" }
|
||||
)
|
||||
}
|
||||
|
||||
override fun getThisAsReceiverParameter(): ReceiverParameterDescriptor =
|
||||
ReceiverParameterDescriptorImpl(this, ImplicitClassReceiver(this), Annotations.EMPTY)
|
||||
|
||||
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 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(
|
||||
Annotations.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.annotatedType.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 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 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_FUNCTION
|
||||
|
||||
override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = getExtensionReceiverParameter(ktSymbol)
|
||||
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = null
|
||||
|
||||
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: KtPossibleMemberSymbol): ReceiverParameterDescriptor? {
|
||||
val ktDispatchTypeAndAnnotations = ktSymbol.dispatchType ?: return null
|
||||
return KtSymbolStubDispatchReceiverParameterDescriptor(ktDispatchTypeAndAnnotations, context)
|
||||
}
|
||||
|
||||
private fun <T> T.getExtensionReceiverParameter(
|
||||
ktSymbol: KtPossibleExtensionSymbol
|
||||
): ReceiverParameterDescriptor? where T : KtSymbolBasedDeclarationDescriptor, T : CallableDescriptor {
|
||||
val receiverTypeAndAnnotation = ktSymbol.receiverType ?: return null
|
||||
val receiverValue = ExtensionReceiver(this, receiverTypeAndAnnotation.type.toKotlinType(context), null)
|
||||
return ReceiverParameterDescriptorImpl(this, receiverValue, receiverTypeAndAnnotation.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 getTypeParameters(): List<TypeParameterDescriptor> = emptyList()
|
||||
|
||||
override fun getReturnType(): KotlinType = ktSymbol.annotatedType.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.annotatedType.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 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 getTypeParameters(): List<TypeParameterDescriptor> = emptyList()
|
||||
|
||||
override fun getReturnType(): KotlinType = ktSymbol.annotatedType.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.annotatedType.toKotlinType(context)
|
||||
|
||||
override fun isVar(): Boolean = !ktSymbol.isVal
|
||||
|
||||
override fun getCompileTimeInitializer(): ConstantValue<*>? = ktSymbol.initializer?.toConstantValue()
|
||||
|
||||
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 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 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")
|
||||
}
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.idea.fir.fe10
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||
import org.jetbrains.kotlin.idea.fir.fe10.*
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getResolveState
|
||||
import org.jetbrains.kotlin.idea.frontend.api.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.EntityWasGarbageCollectedException
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.KtAnalysisSessionFe10BindingHolder
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.HackToForceAllowRunningAnalyzeOnEDT
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.assertIsValidAndAccessible
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.trackers.createProjectWideOutOfBlockModificationTracker
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
interface FE10BindingContext {
|
||||
val builtIns: KotlinBuiltIns
|
||||
val ktAnalysisSessionFacade: KtAnalysisSessionFe10BindingHolder
|
||||
val moduleDescriptor: ModuleDescriptor
|
||||
|
||||
/**
|
||||
* Legend:
|
||||
* - where was decided, that KtSymbolBased descriptor is not support method, noImplementation() method is called.
|
||||
* - where the implementation planned, but not yet here: implementationPlanned()
|
||||
* - if there is no simple implementation and it isn't clear if it really needed -- implementationPostponed()
|
||||
* - if there were no investigation -- autogenerated TODO("not implemented") called
|
||||
* - if we could implement it right now, but not entirely correct -- wrap it into incorrect implementation
|
||||
*/
|
||||
fun noImplementation(additionalInfo: String = ""): Nothing
|
||||
fun implementationPostponed(additionalInfo: String = ""): Nothing
|
||||
fun implementationPlanned(additionalInfo: String = ""): Nothing
|
||||
|
||||
fun <R> incorrectImplementation(block: () -> R) = block()
|
||||
}
|
||||
|
||||
fun KtSymbol.toDeclarationDescriptor(context: FE10BindingContext): DeclarationDescriptor =
|
||||
when (this) {
|
||||
is KtNamedClassOrObjectSymbol -> KtSymbolBasedClassDescriptor(this, context)
|
||||
is KtFunctionLikeSymbol -> toDeclarationDescriptor(context)
|
||||
is KtValueParameterSymbol -> {
|
||||
val containingSymbol = context.withAnalysisSession { this@toDeclarationDescriptor.getContainingSymbol() }
|
||||
check(containingSymbol is KtFunctionLikeSymbol) {
|
||||
"Unexpected containing symbol = $containingSymbol"
|
||||
}
|
||||
KtSymbolBasedValueParameterDescriptor(this, context, containingSymbol.toDeclarationDescriptor(context))
|
||||
}
|
||||
else -> context.implementationPlanned()
|
||||
}
|
||||
|
||||
fun KtFunctionLikeSymbol.toDeclarationDescriptor(context: FE10BindingContext): KtSymbolBasedFunctionLikeDescriptor =
|
||||
when (this) {
|
||||
is KtFunctionSymbol -> KtSymbolBasedFunctionDescriptor(this, context)
|
||||
is KtAnonymousFunctionSymbol -> KtSymbolBasedAnonymousFunctionDescriptor(this, context)
|
||||
is KtConstructorSymbol -> {
|
||||
val ktConstructorSymbol = this
|
||||
val ktClassOrObject = context.withAnalysisSession { ktConstructorSymbol.getContainingSymbol() as KtNamedClassOrObjectSymbol }
|
||||
KtSymbolBasedConstructorDescriptor(ktConstructorSymbol, KtSymbolBasedClassDescriptor(ktClassOrObject, context))
|
||||
}
|
||||
else -> error("Unexpected kind of KtFunctionLikeSymbol: ${this.javaClass}")
|
||||
}
|
||||
|
||||
inline fun <R> FE10BindingContext.withAnalysisSession(f: KtAnalysisSession.() -> R): R = f(ktAnalysisSessionFacade.analysisSession)
|
||||
|
||||
class FE10BindingContextImpl(
|
||||
val project: Project,
|
||||
val ktElement: KtElement
|
||||
) : FE10BindingContext {
|
||||
private val token: ValidityToken = ValidityTokenForKtSymbolBasedWrappers(project)
|
||||
|
||||
private val moduleInfo = ktElement.getModuleInfo()
|
||||
|
||||
@OptIn(InvalidWayOfUsingAnalysisSession::class)
|
||||
override val ktAnalysisSessionFacade = KtAnalysisSessionFe10BindingHolder.create(ktElement.getResolveState(), token)
|
||||
|
||||
override val moduleDescriptor: ModuleDescriptor = KtSymbolBasedModuleDescriptorImpl(this, moduleInfo)
|
||||
|
||||
override val builtIns: KotlinBuiltIns
|
||||
get() = incorrectImplementation { DefaultBuiltIns.Instance }
|
||||
|
||||
override fun noImplementation(additionalInfo: String): Nothing =
|
||||
error("This method should not be called for wrappers. $additionalInfo")
|
||||
|
||||
override fun implementationPostponed(additionalInfo: String): Nothing =
|
||||
TODO("InvestigateLater and implement if needed. $additionalInfo")
|
||||
|
||||
override fun implementationPlanned(additionalInfo: String): Nothing =
|
||||
TODO("SE_to_implement. $additionalInfo")
|
||||
}
|
||||
|
||||
private class ValidityTokenForKtSymbolBasedWrappers(val project: Project) : ValidityToken() {
|
||||
private val modificationTracker = project.createProjectWideOutOfBlockModificationTracker()
|
||||
private val onCreatedTimeStamp = modificationTracker.modificationCount
|
||||
|
||||
override fun isValid(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getInvalidationReason(): String {
|
||||
if (onCreatedTimeStamp != modificationTracker.modificationCount) return "PSI has changed since creation"
|
||||
error("Getting invalidation reason for valid validity token")
|
||||
}
|
||||
|
||||
override fun isAccessible(): Boolean = true
|
||||
|
||||
@OptIn(HackToForceAllowRunningAnalyzeOnEDT::class)
|
||||
override fun getInaccessibilityReason(): String = error("Getting inaccessibility reason for validity token when it is accessible")
|
||||
}
|
||||
|
||||
// This class supposed to be used for non-declaration resolved fir elements, because of that we don't case about FIR phases.
|
||||
// TODO: review FIR access -- by common IDEA FIR design access FIR should be under read lock
|
||||
internal class FirWeakReference<out T : FirElement>(firElement: T, private val token: ValidityToken) {
|
||||
private val firWeakRef = WeakReference(firElement)
|
||||
|
||||
inline fun <R> withFir(action: (T) -> R): R {
|
||||
return action(getFir())
|
||||
}
|
||||
|
||||
fun getFir(): T {
|
||||
token.assertIsValidAndAccessible()
|
||||
return firWeakRef.get() ?: throw EntityWasGarbageCollectedException("FirElement")
|
||||
}
|
||||
}
|
||||
|
||||
private class KtSymbolBasedModuleDescriptorImpl(
|
||||
val context: FE10BindingContext,
|
||||
val moduleInfo: IdeaModuleInfo
|
||||
) : ModuleDescriptor {
|
||||
override val builtIns: KotlinBuiltIns
|
||||
get() = context.builtIns
|
||||
|
||||
override val stableName: Name?
|
||||
get() = context.noImplementation()
|
||||
override val platform: TargetPlatform?
|
||||
get() = moduleInfo.platform
|
||||
|
||||
override fun shouldSeeInternalsOf(targetModule: ModuleDescriptor): Boolean = context.noImplementation()
|
||||
override fun getPackage(fqName: FqName): PackageViewDescriptor = context.noImplementation()
|
||||
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> = context.noImplementation()
|
||||
|
||||
override val allDependencyModules: List<ModuleDescriptor>
|
||||
get() = context.implementationPostponed()
|
||||
override val expectedByModules: List<ModuleDescriptor>
|
||||
get() = context.implementationPostponed()
|
||||
override val allExpectedByModules: Set<ModuleDescriptor>
|
||||
get() = context.implementationPostponed()
|
||||
|
||||
override fun <T> getCapability(capability: ModuleCapability<T>): T? = null
|
||||
|
||||
override val isValid: Boolean
|
||||
get() = context.ktAnalysisSessionFacade.analysisSession.token.isValid()
|
||||
|
||||
override fun assertValid() {
|
||||
assert(context.ktAnalysisSessionFacade.analysisSession.token.isValid())
|
||||
}
|
||||
|
||||
override fun getName(): Name = moduleInfo.name
|
||||
|
||||
override fun getOriginal(): DeclarationDescriptor = this
|
||||
|
||||
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) = context.noImplementation()
|
||||
|
||||
override val annotations: Annotations
|
||||
get() = context.incorrectImplementation { Annotations.EMPTY }
|
||||
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.idea.fir.fe10
|
||||
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtStarProjectionTypeArgument
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgument
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgumentWithVariance
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtAnonymousObjectSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtNamedClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtTypeAndAnnotations
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
abstract class KtSymbolBasedAbstractTypeConstructor<T> internal constructor(
|
||||
val ktSBDescriptor: T
|
||||
) : TypeConstructor where T : KtSymbolBasedDeclarationDescriptor, T : ClassifierDescriptor {
|
||||
override fun getDeclarationDescriptor(): ClassifierDescriptor = ktSBDescriptor
|
||||
|
||||
// TODO: captured types
|
||||
override fun isDenotable(): Boolean = true
|
||||
|
||||
// for Intention|inspection it shouldn't be important what to use.
|
||||
override fun getBuiltIns(): KotlinBuiltIns = DefaultBuiltIns.Instance
|
||||
|
||||
// I don't think that we need to implement this method
|
||||
override fun isFinal(): Boolean = ktSBDescriptor.context.implementationPostponed("ktSBDescriptor = $ktSBDescriptor")
|
||||
|
||||
@TypeRefinement
|
||||
override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): TypeConstructor =
|
||||
ktSBDescriptor.context.noImplementation("ktSBDescriptor = $ktSBDescriptor")
|
||||
}
|
||||
|
||||
class KtSymbolBasedClassTypeConstructor(ktSBDescriptor: KtSymbolBasedClassDescriptor) :
|
||||
KtSymbolBasedAbstractTypeConstructor<KtSymbolBasedClassDescriptor>(ktSBDescriptor) {
|
||||
override fun getParameters(): List<TypeParameterDescriptor> =
|
||||
ktSBDescriptor.ktSymbol.typeParameters.map { KtSymbolBasedTypeParameterDescriptor(it, ktSBDescriptor.context) }
|
||||
|
||||
override fun getSupertypes(): Collection<KotlinType> =
|
||||
ktSBDescriptor.ktSymbol.superTypes.map { it.toKotlinType(ktSBDescriptor.context) }
|
||||
}
|
||||
|
||||
class KtSymbolBasedTypeParameterTypeConstructor(ktSBDescriptor: KtSymbolBasedTypeParameterDescriptor) :
|
||||
KtSymbolBasedAbstractTypeConstructor<KtSymbolBasedTypeParameterDescriptor>(ktSBDescriptor) {
|
||||
override fun getParameters(): List<TypeParameterDescriptor> = emptyList()
|
||||
|
||||
override fun getSupertypes(): Collection<KotlinType> =
|
||||
ktSBDescriptor.ktSymbol.upperBounds.map { it.toKotlinType(ktSBDescriptor.context) }
|
||||
}
|
||||
|
||||
// This class is not suppose to be used as "is instance of" because scopes could be wrapped into other scopes
|
||||
// so generally it isn't a good idea
|
||||
internal class MemberScopeForKtSymbolBasedDescriptors(lazyDebugInfo: () -> String) : MemberScope {
|
||||
private val additionalInfo by lazy(lazyDebugInfo)
|
||||
|
||||
private fun noImplementation(): Nothing =
|
||||
error("Scope for descriptors based on KtSymbols should not be used, additional info: $additionalInfo")
|
||||
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> = noImplementation()
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> = noImplementation()
|
||||
override fun getFunctionNames(): Set<Name> = noImplementation()
|
||||
override fun getVariableNames(): Set<Name> = noImplementation()
|
||||
override fun getClassifierNames(): Set<Name> = noImplementation()
|
||||
override fun printScopeStructure(p: Printer): Unit = noImplementation()
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor = noImplementation()
|
||||
|
||||
override fun getContributedDescriptors(
|
||||
kindFilter: DescriptorKindFilter,
|
||||
nameFilter: (Name) -> Boolean
|
||||
): Collection<DeclarationDescriptor> = noImplementation()
|
||||
}
|
||||
|
||||
fun KtTypeAndAnnotations.getDescriptorsAnnotations(context: FE10BindingContext): Annotations =
|
||||
Annotations.create(annotations.map { KtSymbolBasedAnnotationDescriptor(it, context) })
|
||||
|
||||
fun KtTypeAndAnnotations.toKotlinType(context: FE10BindingContext): UnwrappedType =
|
||||
type.toKotlinType(context, getDescriptorsAnnotations(context))
|
||||
|
||||
fun KtTypeArgument.toTypeProjection(context: FE10BindingContext): TypeProjection =
|
||||
when (this) {
|
||||
KtStarProjectionTypeArgument -> StarProjectionForAbsentTypeParameter(context.builtIns)
|
||||
is KtTypeArgumentWithVariance -> TypeProjectionImpl(variance, type.toKotlinType(context))
|
||||
}
|
||||
|
||||
fun KtType.toKotlinType(context: FE10BindingContext, annotations: Annotations = Annotations.EMPTY): UnwrappedType {
|
||||
if (this is KtNonDenotableType) return toKotlinType(context, annotations)
|
||||
|
||||
val typeConstructor = when (this) {
|
||||
is KtTypeParameterType -> KtSymbolBasedTypeParameterDescriptor(this.symbol, context).typeConstructor
|
||||
is KtClassType -> when (val classLikeSymbol = classSymbol) {
|
||||
is KtTypeAliasSymbol -> context.typeAliasImplementationPlanned()
|
||||
is KtNamedClassOrObjectSymbol -> KtSymbolBasedClassDescriptor(classLikeSymbol, context).typeConstructor
|
||||
is KtAnonymousObjectSymbol -> context.implementationPostponed()
|
||||
}
|
||||
is KtErrorType -> ErrorUtils.createErrorTypeConstructorWithCustomDebugName(error)
|
||||
else -> error("Unexpected subclass: ${this.javaClass}")
|
||||
}
|
||||
|
||||
val ktTypeArguments = this.safeAs<KtClassType>()?.typeArguments ?: emptyList()
|
||||
|
||||
val markedAsNullable = this.safeAs<KtTypeWithNullability>()?.nullability == KtTypeNullability.NULLABLE
|
||||
|
||||
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||
annotations, typeConstructor, ktTypeArguments.map { it.toTypeProjection(context) }, markedAsNullable,
|
||||
MemberScopeForKtSymbolBasedDescriptors { this.asStringForDebugging() }
|
||||
)
|
||||
}
|
||||
|
||||
fun KtNonDenotableType.toKotlinType(context: FE10BindingContext, annotations: Annotations = Annotations.EMPTY): UnwrappedType =
|
||||
when (this) {
|
||||
is KtFlexibleType -> KotlinTypeFactory.flexibleType(
|
||||
lowerBound.toKotlinType(context, annotations) as SimpleType,
|
||||
upperBound.toKotlinType(context, annotations) as SimpleType
|
||||
)
|
||||
// most likely it isn't correct and intersectTypes(List<UnwrappedType>) should be used,
|
||||
// but I don't think that we will have the real problem with that implementation
|
||||
is KtIntersectionType -> IntersectionTypeConstructor(conjuncts.map { it.toKotlinType(context) }).createType()
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.idea.fir.fe10
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ResolverForProject
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.caches.resolve.PlatformAnalysisSettings
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.idea.FrontendInternals
|
||||
import org.jetbrains.kotlin.idea.fir.fe10.binding.KtSymbolBasedBindingContext
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.BindingContextSuppressCache
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
|
||||
class KtSymbolBasedResolutionFacade(
|
||||
override val project: Project,
|
||||
val context: FE10BindingContext
|
||||
) : ResolutionFacade {
|
||||
override fun analyze(element: KtElement, bodyResolveMode: BodyResolveMode): BindingContext = KtSymbolBasedBindingContext(context)
|
||||
|
||||
override fun analyze(elements: Collection<KtElement>, bodyResolveMode: BodyResolveMode): BindingContext =
|
||||
KtSymbolBasedBindingContext(context)
|
||||
|
||||
override fun analyzeWithAllCompilerChecks(elements: Collection<KtElement>, callback: DiagnosticSink.DiagnosticsCallback?): AnalysisResult {
|
||||
return AnalysisResult.success(KtSymbolBasedBindingContext(context), context.moduleDescriptor)
|
||||
}
|
||||
|
||||
override fun resolveToDescriptor(declaration: KtDeclaration, bodyResolveMode: BodyResolveMode): DeclarationDescriptor {
|
||||
val ktSymbol = context.withAnalysisSession {
|
||||
declaration.getSymbol()
|
||||
}
|
||||
return ktSymbol.toDeclarationDescriptor(context)
|
||||
}
|
||||
|
||||
override val moduleDescriptor: ModuleDescriptor
|
||||
get() = context.moduleDescriptor
|
||||
|
||||
@FrontendInternals
|
||||
override fun <T : Any> getFrontendService(serviceClass: Class<T>): T {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
@FrontendInternals
|
||||
override fun <T : Any> getFrontendService(element: PsiElement, serviceClass: Class<T>): T {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
@FrontendInternals
|
||||
override fun <T : Any> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun <T : Any> getIdeService(serviceClass: Class<T>): T {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
@FrontendInternals
|
||||
override fun <T : Any> tryGetFrontendService(element: PsiElement, serviceClass: Class<T>): T? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getResolverForProject(): ResolverForProject<out ModuleInfo> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class KtSymbolBasedKotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
|
||||
override fun getResolutionFacade(elements: List<KtElement>): ResolutionFacade =
|
||||
KtSymbolBasedResolutionFacade(project, FE10BindingContextImpl(project, elements.first()))
|
||||
|
||||
// todo: platform are ignored
|
||||
override fun getResolutionFacade(elements: List<KtElement>, platform: TargetPlatform): ResolutionFacade =
|
||||
KtSymbolBasedResolutionFacade(project, FE10BindingContextImpl(project, elements.first()))
|
||||
|
||||
override fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade? =
|
||||
file.safeAs<KtFile>()?.let { KtSymbolBasedResolutionFacade(project, FE10BindingContextImpl(project, it)) }
|
||||
|
||||
override fun getSuppressionCache(): KotlinSuppressCache {
|
||||
return BindingContextSuppressCache(BindingContext.EMPTY)
|
||||
}
|
||||
|
||||
override fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, platform: TargetPlatform): ResolutionFacade? =
|
||||
TODO("Not yet implemented")
|
||||
|
||||
override fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, settings: PlatformAnalysisSettings): ResolutionFacade? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.idea.fir.fe10.binding
|
||||
|
||||
import com.intellij.lang.ASTNode
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.realPsi
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance
|
||||
import org.jetbrains.kotlin.idea.fir.fe10.*
|
||||
import org.jetbrains.kotlin.idea.fir.fe10.FirWeakReference
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFir
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import java.util.*
|
||||
|
||||
private fun FirExpression?.toExpressionReceiverValue(context: FE10BindingContext): ReceiverValue? {
|
||||
if (this == null) return null
|
||||
|
||||
if (this is FirThisReceiverExpression) {
|
||||
val ktClassSymbol =
|
||||
context.ktAnalysisSessionFacade.buildClassLikeSymbol(calleeReference.boundSymbol?.fir as FirClassLikeDeclaration<*>)
|
||||
return ImplicitClassReceiver(ktClassSymbol.toDeclarationDescriptor(context) as ClassDescriptor)
|
||||
}
|
||||
val expression = realPsi.safeAs<KtExpression>() ?: context.implementationPostponed()
|
||||
return ExpressionReceiver.create(
|
||||
expression,
|
||||
context.ktAnalysisSessionFacade.buildKtType(typeRef).toKotlinType(context),
|
||||
context.incorrectImplementation { BindingContext.EMPTY }
|
||||
)
|
||||
}
|
||||
|
||||
internal class FirSimpleWrapperCall(
|
||||
val ktCall: KtCallExpression,
|
||||
val firCall: FirWeakReference<FirFunctionCall>,
|
||||
val context: FE10BindingContext
|
||||
) : Call {
|
||||
override fun getCallOperationNode(): ASTNode = ktCall.node
|
||||
|
||||
override fun getExplicitReceiver(): Receiver? = firCall.withFir { it.explicitReceiver.toExpressionReceiverValue(context) }
|
||||
|
||||
override fun getDispatchReceiver(): ReceiverValue? = null
|
||||
|
||||
override fun getCalleeExpression(): KtExpression? = ktCall.calleeExpression
|
||||
|
||||
override fun getValueArgumentList(): KtValueArgumentList? = ktCall.valueArgumentList
|
||||
|
||||
override fun getValueArguments(): List<ValueArgument> = ktCall.valueArguments
|
||||
|
||||
override fun getFunctionLiteralArguments(): List<LambdaArgument> = ktCall.lambdaArguments
|
||||
|
||||
override fun getTypeArguments(): List<KtTypeProjection> = ktCall.typeArguments
|
||||
|
||||
override fun getTypeArgumentList(): KtTypeArgumentList? = ktCall.typeArgumentList
|
||||
|
||||
override fun getCallElement(): KtElement = ktCall
|
||||
|
||||
override fun getCallType(): Call.CallType = Call.CallType.DEFAULT
|
||||
}
|
||||
|
||||
internal class FirWrapperResolvedCall(val firSimpleWrapperCall: FirSimpleWrapperCall) : ResolvedCall<CallableDescriptor> {
|
||||
private val firCall get() = firSimpleWrapperCall.firCall
|
||||
private val context get() = firSimpleWrapperCall.context
|
||||
|
||||
private val ktFunctionSymbol = firCall.withFir {
|
||||
context.ktAnalysisSessionFacade.buildSymbol((it.calleeReference as FirResolvedNamedReference).resolvedSymbol.fir) as KtFunctionLikeSymbol
|
||||
}
|
||||
|
||||
private val _typeArguments: Map<TypeParameterDescriptor, KotlinType> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
|
||||
if (firCall.getFir().typeArguments.isEmpty()) return@lazy emptyMap()
|
||||
|
||||
val typeArguments = linkedMapOf<TypeParameterDescriptor, KotlinType>()
|
||||
for ((index, parameter) in candidateDescriptor.typeParameters.withIndex()) {
|
||||
val firTypeProjectionWithVariance = firCall.getFir().typeArguments[index] as FirTypeProjectionWithVariance
|
||||
val kotlinType = context.ktAnalysisSessionFacade.buildKtType(firTypeProjectionWithVariance.typeRef).toKotlinType(context)
|
||||
typeArguments[parameter] = kotlinType
|
||||
}
|
||||
typeArguments
|
||||
}
|
||||
|
||||
private val arguments: Map<ValueParameterDescriptor, ResolvedValueArgument> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
val firArguments = firCall.withFir { it.argumentMapping } ?: context.implementationPostponed()
|
||||
|
||||
val firParameterToResolvedValueArgument = hashMapOf<FirValueParameter, ResolvedValueArgument>()
|
||||
val allArguments = firSimpleWrapperCall.valueArguments + firSimpleWrapperCall.functionLiteralArguments
|
||||
var argumentIndex = 0
|
||||
for ((firExpression, firValueParameter) in firArguments.entries) {
|
||||
if (firExpression is FirVarargArgumentsExpression) {
|
||||
val varargArguments = mutableListOf<ValueArgument>()
|
||||
for (subExpression in firExpression.arguments) {
|
||||
val currentArgument = allArguments[argumentIndex]; argumentIndex++
|
||||
check(currentArgument.getArgumentExpression() === subExpression.realPsi) {
|
||||
"Different psi: ${currentArgument.getArgumentExpression()} !== ${subExpression.realPsi}"
|
||||
}
|
||||
varargArguments.add(currentArgument)
|
||||
}
|
||||
firParameterToResolvedValueArgument[firValueParameter] = VarargValueArgument(varargArguments)
|
||||
} else {
|
||||
val currentArgument = allArguments[argumentIndex]; argumentIndex++
|
||||
check(currentArgument.getArgumentExpression() === firExpression.realPsi) {
|
||||
"Different psi: ${currentArgument.getArgumentExpression()} !== ${firExpression.realPsi}"
|
||||
}
|
||||
firParameterToResolvedValueArgument[firValueParameter] = ExpressionValueArgument(currentArgument)
|
||||
}
|
||||
}
|
||||
|
||||
val arguments = linkedMapOf<ValueParameterDescriptor, ResolvedValueArgument>()
|
||||
for ((parameterIndex, parameter) in ktFunctionSymbol.valueParameters.withIndex()) {
|
||||
val resolvedValueArgument = context.ktAnalysisSessionFacade.withFir(parameter) { it: FirValueParameter ->
|
||||
firParameterToResolvedValueArgument[it]
|
||||
} ?: DefaultValueArgument.DEFAULT
|
||||
arguments[candidateDescriptor.valueParameters[parameterIndex]] = resolvedValueArgument
|
||||
}
|
||||
arguments
|
||||
}
|
||||
|
||||
override fun getStatus(): ResolutionStatus =
|
||||
if (firCall.getFir().calleeReference is FirResolvedNamedReference) ResolutionStatus.SUCCESS else ResolutionStatus.OTHER_ERROR
|
||||
|
||||
override fun getCall(): Call = firSimpleWrapperCall
|
||||
|
||||
override fun getCandidateDescriptor(): CallableDescriptor {
|
||||
return ktFunctionSymbol.toDeclarationDescriptor(context)
|
||||
}
|
||||
|
||||
override fun getResultingDescriptor(): CallableDescriptor = context.incorrectImplementation { candidateDescriptor }
|
||||
|
||||
override fun getExtensionReceiver(): ReceiverValue? {
|
||||
if (firCall.getFir().extensionReceiver === FirNoReceiverExpression) return null
|
||||
|
||||
return firCall.getFir().extensionReceiver.toExpressionReceiverValue(context)
|
||||
}
|
||||
|
||||
override fun getDispatchReceiver(): ReceiverValue? {
|
||||
if (firCall.getFir().dispatchReceiver === FirNoReceiverExpression) return null
|
||||
|
||||
return firCall.getFir().dispatchReceiver.toExpressionReceiverValue(context)
|
||||
}
|
||||
|
||||
override fun getExplicitReceiverKind(): ExplicitReceiverKind {
|
||||
if (firCall.getFir().explicitReceiver === null) return ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||
if (firCall.getFir().explicitReceiver === firCall.getFir().extensionReceiver) return ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||
return ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||
}
|
||||
|
||||
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> = arguments
|
||||
|
||||
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument> = valueArguments.values.toList()
|
||||
|
||||
override fun getArgumentMapping(valueArgument: ValueArgument): ArgumentMapping {
|
||||
val firArguments = firCall.withFir { it.argumentMapping } ?: context.implementationPostponed()
|
||||
val argumentExpression = valueArgument.getArgumentExpression() ?: context.implementationPostponed()
|
||||
|
||||
var targetFirParameter: FirValueParameter? = null
|
||||
outer@ for ((firExpression, firValueParameter) in firArguments.entries) {
|
||||
if (firExpression is FirVarargArgumentsExpression) {
|
||||
for (subExpression in firExpression.arguments)
|
||||
if (subExpression.realPsi === argumentExpression) {
|
||||
targetFirParameter = firValueParameter
|
||||
break@outer
|
||||
}
|
||||
} else if (firExpression.realPsi === argumentExpression) {
|
||||
targetFirParameter = firValueParameter
|
||||
break@outer
|
||||
}
|
||||
}
|
||||
if (targetFirParameter == null) return ArgumentUnmapped
|
||||
|
||||
val parameterIndex = ktFunctionSymbol.valueParameters.indexOfFirst {
|
||||
context.ktAnalysisSessionFacade.withFir(it) { it: FirValueParameter -> it === targetFirParameter }
|
||||
}
|
||||
if (parameterIndex == -1) error("Fir parameter not found :(")
|
||||
|
||||
val parameterDescriptor = candidateDescriptor.valueParameters[parameterIndex]
|
||||
return ArgumentMatchImpl(parameterDescriptor)
|
||||
}
|
||||
|
||||
override fun getTypeArguments(): Map<TypeParameterDescriptor, KotlinType> = _typeArguments
|
||||
|
||||
override fun getDataFlowInfoForArguments(): DataFlowInfoForArguments = context.noImplementation()
|
||||
override fun getSmartCastDispatchReceiverType(): KotlinType? = context.noImplementation()
|
||||
}
|
||||
|
||||
class CallAndResolverCallWrappers(bindingContext: KtSymbolBasedBindingContext) {
|
||||
private val context = bindingContext.context
|
||||
|
||||
init {
|
||||
bindingContext.registerGetterByKey(BindingContext.CALL, this::getCall)
|
||||
bindingContext.registerGetterByKey(BindingContext.RESOLVED_CALL, this::getResolvedCall)
|
||||
bindingContext.registerGetterByKey(BindingContext.REFERENCE_TARGET, this::getReferenceTarget)
|
||||
}
|
||||
|
||||
private fun getCall(element: KtElement): Call {
|
||||
val ktCall = element.parent.safeAs<KtCallExpression>() ?: context.implementationPostponed()
|
||||
val firCall = when (val fir = element.getOrBuildFir(context.ktAnalysisSessionFacade.firResolveState)) {
|
||||
is FirFunctionCall -> fir
|
||||
is FirSafeCallExpression -> fir.regularQualifiedAccess as? FirFunctionCall
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (firCall != null) return FirSimpleWrapperCall(ktCall, FirWeakReference(firCall, context.ktAnalysisSessionFacade.analysisSession.token), context)
|
||||
|
||||
// Call for property
|
||||
context.implementationPostponed()
|
||||
}
|
||||
|
||||
private fun getResolvedCall(call: Call): ResolvedCall<*> {
|
||||
check(call is FirSimpleWrapperCall) {
|
||||
"Incorrect Call type: $call"
|
||||
}
|
||||
return FirWrapperResolvedCall(call)
|
||||
}
|
||||
|
||||
private fun getReferenceTarget(key: KtReferenceExpression): DeclarationDescriptor? {
|
||||
val ktSymbol = context.withAnalysisSession { key.mainReference.resolveToSymbols().singleOrNull() } ?: return null
|
||||
return ktSymbol.toDeclarationDescriptor(context)
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.idea.fir.fe10.binding
|
||||
|
||||
import com.google.common.collect.ImmutableMap
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import org.jetbrains.kotlin.idea.fir.fe10.FE10BindingContext
|
||||
import org.jetbrains.kotlin.idea.fir.fe10.toKotlinType
|
||||
import org.jetbrains.kotlin.idea.fir.fe10.withAnalysisSession
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
|
||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice
|
||||
|
||||
class KtSymbolBasedBindingContext(val context: FE10BindingContext) : BindingContext {
|
||||
private val LOG = Logger.getInstance(KtSymbolBasedBindingContext::class.java)
|
||||
|
||||
private val getterBySlice: MutableMap<ReadOnlySlice<*, *>, (Nothing) -> Any?> = hashMapOf()
|
||||
|
||||
init {
|
||||
CallAndResolverCallWrappers(this)
|
||||
ToDescriptorBindingContextValueProviders(this)
|
||||
}
|
||||
|
||||
fun <K, V> registerGetterByKey(slice: ReadOnlySlice<K, V>, getter: (K) -> V?) {
|
||||
check(!getterBySlice.containsKey(slice)) {
|
||||
"Key $slice already registered: ${getterBySlice[slice]}"
|
||||
}
|
||||
getterBySlice[slice] = getter
|
||||
}
|
||||
|
||||
override fun getDiagnostics(): Diagnostics = context.incorrectImplementation { Diagnostics.EMPTY }
|
||||
|
||||
override fun <K : Any?, V : Any?> get(slice: ReadOnlySlice<K, V>, key: K): V? {
|
||||
val getter = getterBySlice[slice]
|
||||
if (getter == null) {
|
||||
LOG.info("Key not registered: $slice")
|
||||
return null
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return (getter as (K) -> V?)(key)
|
||||
}
|
||||
|
||||
override fun getType(expression: KtExpression): KotlinType? =
|
||||
context.withAnalysisSession {
|
||||
expression.getKtType().toKotlinType(context)
|
||||
}
|
||||
|
||||
override fun <K : Any?, V : Any?> getKeys(slice: WritableSlice<K, V>?): Collection<K> =
|
||||
context.noImplementation()
|
||||
|
||||
override fun <K : Any?, V : Any?> getSliceContents(slice: ReadOnlySlice<K, V>): ImmutableMap<K, V> =
|
||||
context.noImplementation()
|
||||
|
||||
override fun addOwnDataTo(trace: BindingTrace, commitDiagnostics: Boolean) =
|
||||
context.noImplementation()
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.idea.fir.fe10.binding
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.fir.fe10.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
internal class ToDescriptorBindingContextValueProviders(bindingContext: KtSymbolBasedBindingContext) {
|
||||
private val context = bindingContext.context
|
||||
private val declarationToDescriptorGetters = mutableListOf<(PsiElement) -> DeclarationDescriptor?>()
|
||||
|
||||
private inline fun <reified K : PsiElement, V : DeclarationDescriptor> KtSymbolBasedBindingContext.registerDeclarationToDescriptorByKey(
|
||||
slice: ReadOnlySlice<K, V>,
|
||||
crossinline getter: (K) -> V?
|
||||
) {
|
||||
declarationToDescriptorGetters.add {
|
||||
if (it is K) getter(it) else null
|
||||
}
|
||||
registerGetterByKey(slice, { getter(it) })
|
||||
}
|
||||
|
||||
init {
|
||||
bindingContext.registerDeclarationToDescriptorByKey(BindingContext.CLASS, this::getClass)
|
||||
bindingContext.registerDeclarationToDescriptorByKey(BindingContext.TYPE_PARAMETER, this::getTypeParameter)
|
||||
bindingContext.registerDeclarationToDescriptorByKey(BindingContext.FUNCTION, this::getFunction)
|
||||
bindingContext.registerDeclarationToDescriptorByKey(BindingContext.CONSTRUCTOR, this::getConstructor)
|
||||
|
||||
|
||||
bindingContext.registerGetterByKey(BindingContext.DECLARATION_TO_DESCRIPTOR, this::getDeclarationToDescriptor)
|
||||
}
|
||||
|
||||
private inline fun <reified T : Any> PsiElement.getKtSymbolOfTypeOrNull(): T? =
|
||||
this@ToDescriptorBindingContextValueProviders.context.withAnalysisSession {
|
||||
this@getKtSymbolOfTypeOrNull.safeAs<KtDeclaration>()?.getSymbol().safeAs<T>()
|
||||
}
|
||||
|
||||
private fun getClass(key: PsiElement): ClassDescriptor? {
|
||||
val ktClassSymbol = key.getKtSymbolOfTypeOrNull<KtNamedClassOrObjectSymbol>() ?: return null
|
||||
|
||||
return KtSymbolBasedClassDescriptor(ktClassSymbol, context)
|
||||
}
|
||||
|
||||
private fun getTypeParameter(key: KtTypeParameter): TypeParameterDescriptor {
|
||||
val ktTypeParameterSymbol = context.withAnalysisSession { key.getTypeParameterSymbol() }
|
||||
return KtSymbolBasedTypeParameterDescriptor(ktTypeParameterSymbol, context)
|
||||
}
|
||||
|
||||
private fun getFunction(key: PsiElement): SimpleFunctionDescriptor? {
|
||||
val ktFunctionLikeSymbol = key.getKtSymbolOfTypeOrNull<KtFunctionLikeSymbol>() ?: return null
|
||||
return ktFunctionLikeSymbol.toDeclarationDescriptor(context).safeAs()
|
||||
}
|
||||
|
||||
private fun getConstructor(key: PsiElement): ConstructorDescriptor? {
|
||||
val ktConstructorSymbol = key.getKtSymbolOfTypeOrNull<KtConstructorSymbol>() ?: return null
|
||||
val containerClass = context.withAnalysisSession { ktConstructorSymbol.getContainingSymbol() }
|
||||
check(containerClass is KtNamedClassOrObjectSymbol) {
|
||||
"Unexpected contained for Constructor symbol: $containerClass, ktConstructorSymbol = $ktConstructorSymbol"
|
||||
}
|
||||
|
||||
return KtSymbolBasedConstructorDescriptor(ktConstructorSymbol, KtSymbolBasedClassDescriptor(containerClass, context))
|
||||
}
|
||||
|
||||
private fun getDeclarationToDescriptor(key: PsiElement): DeclarationDescriptor? {
|
||||
for (getter in declarationToDescriptorGetters) {
|
||||
getter(key)?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.idea.inspections
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.idea.intentions.AbstractIntentionTest
|
||||
import org.jetbrains.kotlin.test.utils.IgnoreTests
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractFe10BindingIntentionTest : AbstractIntentionTest() {
|
||||
override fun isFirPlugin() = true
|
||||
|
||||
// left empty because error reporting in FIR and old FE is different
|
||||
override fun checkForErrorsBefore(fileText: String) {}
|
||||
override fun checkForErrorsAfter(fileText: String) {}
|
||||
|
||||
override fun doTestFor(mainFile: File, pathToFiles: Map<String, PsiFile>, intentionAction: IntentionAction, fileText: String) {
|
||||
IgnoreTests.runTestIfNotDisabledByFileDirective(mainFile.toPath(), IgnoreTests.DIRECTIVES.IGNORE_FE10_BINDING_BY_FIR, "after") {
|
||||
super.doTestFor(mainFile, pathToFiles, intentionAction, fileText)
|
||||
}
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.idea.inspections;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("idea/testData/intentions/conventionNameCalls/replaceContains")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class Fe10BindingIntentionTestGenerated extends AbstractFe10BindingIntentionTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInReplaceContains() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/intentions/conventionNameCalls/replaceContains"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("containsFromJava.kt")
|
||||
public void testContainsFromJava() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/containsFromJava.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("containsInExpression.kt")
|
||||
public void testContainsInExpression() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/containsInExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionFunction.kt")
|
||||
public void testExtensionFunction() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/extensionFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("functionLiteralArgument.kt")
|
||||
public void testFunctionLiteralArgument() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/functionLiteralArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("functionLiteralArgumentAfterSemicolon.kt")
|
||||
public void testFunctionLiteralArgumentAfterSemicolon() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/functionLiteralArgumentAfterSemicolon.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("functionLiteralArgumentAtStartOfBlock.kt")
|
||||
public void testFunctionLiteralArgumentAtStartOfBlock() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/functionLiteralArgumentAtStartOfBlock.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("functionLiteralArgumentInExpression.kt")
|
||||
public void testFunctionLiteralArgumentInExpression() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/functionLiteralArgumentInExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invalidArgument.kt")
|
||||
public void testInvalidArgument() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/invalidArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("missingArgument.kt")
|
||||
public void testMissingArgument() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/missingArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("missingDefaultArgument.kt")
|
||||
public void testMissingDefaultArgument() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/missingDefaultArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleArguments.kt")
|
||||
public void testMultipleArguments() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/multipleArguments.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notContains.kt")
|
||||
public void testNotContains() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/notContains.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("qualifier.kt")
|
||||
public void testQualifier() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/qualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleArgument.kt")
|
||||
public void testSimpleArgument() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/simpleArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleStringLiteral.kt")
|
||||
public void testSimpleStringLiteral() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/simpleStringLiteral.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("super.kt")
|
||||
public void testSuper() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/super.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("twoArgsContainsFromJava.kt")
|
||||
public void testTwoArgsContainsFromJava() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/twoArgsContainsFromJava.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeArguments.kt")
|
||||
public void testTypeArguments() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/typeArguments.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unacceptableVararg1.kt")
|
||||
public void testUnacceptableVararg1() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/unacceptableVararg1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unacceptableVararg2.kt")
|
||||
public void testUnacceptableVararg2() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/unacceptableVararg2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withoutOperatorModifier.kt")
|
||||
public void testWithoutOperatorModifier() throws Exception {
|
||||
runTest("idea/testData/intentions/conventionNameCalls/replaceContains/withoutOperatorModifier.kt");
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ dependencies {
|
||||
compile(project(":idea:formatter"))
|
||||
compile(intellijDep())
|
||||
compile(intellijCoreDep())
|
||||
implementation(project(":idea:idea-fir-fe10-binding"))
|
||||
|
||||
// <temp>
|
||||
compile(project(":idea:idea-core"))
|
||||
@@ -26,6 +27,7 @@ dependencies {
|
||||
|
||||
testCompileOnly(intellijDep())
|
||||
testRuntime(intellijDep())
|
||||
testImplementation(project(":idea:idea-fir-fe10-binding"))
|
||||
|
||||
compile(intellijPluginDep("java"))
|
||||
}
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.idea.frontend.api.fir.utils
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
|
||||
import org.jetbrains.kotlin.idea.frontend.api.InvalidWayOfUsingAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.buildSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
|
||||
|
||||
class KtAnalysisSessionFe10BindingHolder private constructor(
|
||||
internal val firAnalysisSession: KtFirAnalysisSession
|
||||
) {
|
||||
val analysisSession: KtAnalysisSession get() = firAnalysisSession
|
||||
|
||||
val firResolveState: FirModuleResolveState get() = firAnalysisSession.firResolveState
|
||||
|
||||
fun buildClassLikeSymbol(fir: FirClassLikeDeclaration<*>): KtClassLikeSymbol =
|
||||
firAnalysisSession.firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(fir)
|
||||
|
||||
fun buildKtType(coneType: FirTypeRef): KtType =
|
||||
firAnalysisSession.firSymbolBuilder.typeBuilder.buildKtType(coneType)
|
||||
|
||||
fun buildSymbol(firElement: FirElement): KtSymbol? = firElement.buildSymbol(firAnalysisSession.firSymbolBuilder)
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
|
||||
inline fun <T : FirDeclaration, R> withFir(ktSymbol: KtSymbol, crossinline action: (T) -> R) =
|
||||
(ktSymbol as KtFirSymbol<T>).firRef.withFir(action = action)
|
||||
|
||||
fun toSignature(ktSymbol: KtSymbol): IdSignature = (ktSymbol as KtFirSymbol<*>).firRef.withFir { it.createSignature() }
|
||||
|
||||
companion object {
|
||||
@InvalidWayOfUsingAnalysisSession
|
||||
fun create(firResolveState: FirModuleResolveState, token: ValidityToken): KtAnalysisSessionFe10BindingHolder {
|
||||
val firAnalysisSession = KtFirAnalysisSession.createAnalysisSessionByResolveState(firResolveState, token)
|
||||
return KtAnalysisSessionFe10BindingHolder(firAnalysisSession)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,6 +181,8 @@ object IgnoreTests {
|
||||
|
||||
const val FIX_ME = "// FIX_ME: "
|
||||
const val FIR_IDENTICAL = "// FIR_IDENTICAL"
|
||||
|
||||
const val IGNORE_FE10_BINDING_BY_FIR = "// IGNORE_FE10_BINDING_BY_FIR"
|
||||
}
|
||||
|
||||
enum class DirectivePosition {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.caches.resolve.KotlinCacheService"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.fir.fe10.KtSymbolBasedKotlinCacheServiceImpl"/>
|
||||
|
||||
<!-- Supported Intentions -->
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.conventionNameCalls.ReplaceContainsIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -39,6 +39,7 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu
|
||||
<xi:include href="caches.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="firInspections.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="firIntentions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="fe10Binding.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="extensions/ide-frontend-independent.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun foo() {
|
||||
val c = Container()
|
||||
c.cont<caret>ains(1)
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun foo() {
|
||||
val c = Container()
|
||||
1 in c
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun <T> doSomething(a: T) {}
|
||||
|
||||
fun test() {
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun <T> doSomething(a: T) {}
|
||||
|
||||
fun test() {
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test()
|
||||
operator fun Test.contains(a: Int) : Boolean = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test()
|
||||
operator fun Test.contains(a: Int) : Boolean = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(fn: () -> Boolean) : Boolean = true
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(fn: () -> Boolean) : Boolean = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(fn: () -> Boolean) : Boolean = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(fn: () -> Boolean) : Boolean = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(fn: () -> Boolean) : Boolean = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(fn: () -> Boolean) : Boolean = true
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun <T> doSomething(a: T) {}
|
||||
|
||||
fun test() {
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun <T> doSomething(a: T) {}
|
||||
|
||||
fun test() {
|
||||
|
||||
+1
@@ -1,6 +1,7 @@
|
||||
// IS_APPLICABLE: false
|
||||
// ERROR: Cannot find a parameter with this name: c
|
||||
// ERROR: 'operator' modifier is inapplicable on this function: must have a single value parameter
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(a: Int=1, b: Int=2): Boolean = true
|
||||
|
||||
+1
@@ -1,6 +1,7 @@
|
||||
// IS_APPLICABLE: false
|
||||
// ERROR: No value passed for parameter 'b'
|
||||
// ERROR: 'operator' modifier is inapplicable on this function: must have a single value parameter
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(a: Int, b: Int): Boolean = true
|
||||
|
||||
+2
@@ -1,5 +1,7 @@
|
||||
// IS_APPLICABLE: false
|
||||
// ERROR: 'operator' modifier is inapplicable on this function: must have a single value parameter
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(a: Int=1, b: Int=2) : Boolean = true
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(a: Int) : Boolean = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(a: Int) : Boolean = true
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
class C {
|
||||
companion object {
|
||||
operator fun contains(s: String) = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
class C {
|
||||
companion object {
|
||||
operator fun contains(s: String) = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(a: Int) : Boolean = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(a: Int) : Boolean = true
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
@Suppress("INAPPLICABLE_OPERATOR_MODIFIER")
|
||||
public operator fun CharSequence.contains(other: CharSequence, ignoreCase: Boolean = false): Boolean = false
|
||||
fun test() {
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
@Suppress("INAPPLICABLE_OPERATOR_MODIFIER")
|
||||
public operator fun CharSequence.contains(other: CharSequence, ignoreCase: Boolean = false): Boolean = false
|
||||
fun test() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun <T> contains(a: T): Boolean = false
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun <T> contains(a: T): Boolean = false
|
||||
|
||||
+1
@@ -1,5 +1,6 @@
|
||||
// IS_APPLICABLE: false
|
||||
// ERROR: 'operator' modifier is inapplicable on this function: must have a single value parameter
|
||||
// IGNORE_FE10_BINDING_BY_FIR
|
||||
fun test() {
|
||||
class Test{
|
||||
operator fun contains(vararg b: Int, c: Int = 0): Boolean = true
|
||||
|
||||
@@ -344,6 +344,7 @@ include ":compiler:test-infrastructure",
|
||||
include ":idea:idea-frontend-fir:idea-fir-low-level-api"
|
||||
include ":idea:idea-frontend-fir:idea-frontend-fir-generator"
|
||||
include ":idea:idea-fir-performance-tests"
|
||||
include ":idea:idea-fir-fe10-binding"
|
||||
|
||||
include ":plugins:parcelize:parcelize-compiler",
|
||||
":plugins:parcelize:parcelize-ide",
|
||||
|
||||
Reference in New Issue
Block a user