FIR IDE: new symbol/kind/pointer/resolver for SAM constructor
This commit is contained in:
committed by
Ilya Kirillov
parent
7df5ebf6ee
commit
da3f2c2095
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
public abstract class KtAnalysisSession(final override val token: ValidityToken) : ValidityTokenOwner,
|
public abstract class KtAnalysisSession(final override val token: ValidityToken) : ValidityTokenOwner,
|
||||||
KtSmartCastProviderMixIn,
|
KtSmartCastProviderMixIn,
|
||||||
KtCallResolverMixIn,
|
KtCallResolverMixIn,
|
||||||
|
KtSamResolverMixIn,
|
||||||
KtDiagnosticProviderMixIn,
|
KtDiagnosticProviderMixIn,
|
||||||
KtScopeProviderMixIn,
|
KtScopeProviderMixIn,
|
||||||
KtCompletionCandidateCheckerMixIn,
|
KtCompletionCandidateCheckerMixIn,
|
||||||
@@ -75,6 +76,9 @@ public abstract class KtAnalysisSession(final override val token: ValidityToken)
|
|||||||
internal val callResolver: KtCallResolver get() = callResolverImpl
|
internal val callResolver: KtCallResolver get() = callResolverImpl
|
||||||
protected abstract val callResolverImpl: KtCallResolver
|
protected abstract val callResolverImpl: KtCallResolver
|
||||||
|
|
||||||
|
internal val samResolver: KtSamResolver get() = samResolverImpl
|
||||||
|
protected abstract val samResolverImpl: KtSamResolver
|
||||||
|
|
||||||
internal val completionCandidateChecker: KtCompletionCandidateChecker get() = completionCandidateCheckerImpl
|
internal val completionCandidateChecker: KtCompletionCandidateChecker get() = completionCandidateCheckerImpl
|
||||||
protected abstract val completionCandidateCheckerImpl: KtCompletionCandidateChecker
|
protected abstract val completionCandidateCheckerImpl: KtCompletionCandidateChecker
|
||||||
|
|
||||||
|
|||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSamConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
|
public abstract class KtSamResolver : KtAnalysisSessionComponent() {
|
||||||
|
public abstract fun getSamConstructor(ktClassLikeSymbol: KtClassLikeSymbol): KtSamConstructorSymbol?
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface KtSamResolverMixIn : KtAnalysisSessionMixIn {
|
||||||
|
/**
|
||||||
|
* Returns [KtSamConstructorSymbol] if the given [KtClassLikeSymbol] is a functional interface type, a.k.a. SAM.
|
||||||
|
*/
|
||||||
|
public fun KtClassLikeSymbol.getSamConstructor(): KtSamConstructorSymbol? =
|
||||||
|
analysisSession.samResolver.getSamConstructor(this)
|
||||||
|
}
|
||||||
+1
@@ -85,6 +85,7 @@ public object DebugSymbolRenderer {
|
|||||||
val symbolTag = when (value) {
|
val symbolTag = when (value) {
|
||||||
is KtClassLikeSymbol -> renderValue(value.classIdIfNonLocal ?: "<local>/${value.name}")
|
is KtClassLikeSymbol -> renderValue(value.classIdIfNonLocal ?: "<local>/${value.name}")
|
||||||
is KtFunctionSymbol -> renderValue(value.callableIdIfNonLocal ?: "<local>/${value.name}")
|
is KtFunctionSymbol -> renderValue(value.callableIdIfNonLocal ?: "<local>/${value.name}")
|
||||||
|
is KtSamConstructorSymbol -> renderValue(value.callableIdIfNonLocal ?: "<local>/${value.name}")
|
||||||
is KtConstructorSymbol -> "<constructor>"
|
is KtConstructorSymbol -> "<constructor>"
|
||||||
is KtNamedSymbol -> renderValue(value.name)
|
is KtNamedSymbol -> renderValue(value.name)
|
||||||
is KtPropertyGetterSymbol -> "<getter>"
|
is KtPropertyGetterSymbol -> "<getter>"
|
||||||
|
|||||||
+7
-2
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.*
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
|
|
||||||
public abstract class KtFunctionLikeSymbol : KtCallableSymbol(), KtSymbolWithKind {
|
public abstract class KtFunctionLikeSymbol : KtCallableSymbol(), KtSymbolWithKind {
|
||||||
public abstract val valueParameters: List<KtValueParameterSymbol>
|
public abstract val valueParameters: List<KtValueParameterSymbol>
|
||||||
@@ -31,6 +30,12 @@ public abstract class KtAnonymousFunctionSymbol : KtFunctionLikeSymbol() {
|
|||||||
abstract override fun createPointer(): KtSymbolPointer<KtAnonymousFunctionSymbol>
|
abstract override fun createPointer(): KtSymbolPointer<KtAnonymousFunctionSymbol>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract class KtSamConstructorSymbol : KtFunctionLikeSymbol(), KtNamedSymbol {
|
||||||
|
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.SAM_CONSTRUCTOR
|
||||||
|
|
||||||
|
abstract override fun createPointer(): KtSymbolPointer<KtSamConstructorSymbol>
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class KtFunctionSymbol : KtFunctionLikeSymbol(),
|
public abstract class KtFunctionSymbol : KtFunctionLikeSymbol(),
|
||||||
KtNamedSymbol,
|
KtNamedSymbol,
|
||||||
KtPossibleMemberSymbol,
|
KtPossibleMemberSymbol,
|
||||||
@@ -64,4 +69,4 @@ public abstract class KtConstructorSymbol : KtFunctionLikeSymbol(),
|
|||||||
final override val receiverType: KtTypeAndAnnotations? get() = null
|
final override val receiverType: KtTypeAndAnnotations? get() = null
|
||||||
|
|
||||||
abstract override fun createPointer(): KtSymbolPointer<KtConstructorSymbol>
|
abstract override fun createPointer(): KtSymbolPointer<KtConstructorSymbol>
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -67,6 +67,12 @@ public enum class KtSymbolOrigin {
|
|||||||
*/
|
*/
|
||||||
JAVA,
|
JAVA,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A synthetic function that is called as a lambda argument when creating a SAM interface object, e.g.,
|
||||||
|
* ```
|
||||||
|
* val isEven = <caret>IntPredicate { it % 2 == 0 }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
SAM_CONSTRUCTOR,
|
SAM_CONSTRUCTOR,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,4 +108,4 @@ public enum class KtSymbolOrigin {
|
|||||||
* @see KtBackingFieldSymbol
|
* @see KtBackingFieldSymbol
|
||||||
*/
|
*/
|
||||||
PROPERTY_BACKING_FIELD,
|
PROPERTY_BACKING_FIELD,
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -15,6 +15,10 @@ public interface KtSymbolWithKind : KtSymbol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum class KtSymbolKind {
|
public enum class KtSymbolKind {
|
||||||
TOP_LEVEL, MEMBER, LOCAL, ACCESSOR
|
TOP_LEVEL,
|
||||||
|
MEMBER,
|
||||||
|
LOCAL,
|
||||||
|
ACCESSOR,
|
||||||
|
SAM_CONSTRUCTOR,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -6,4 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.idea.frontend.api.symbols.pointers
|
package org.jetbrains.kotlin.idea.frontend.api.symbols.pointers
|
||||||
|
|
||||||
public class CanNotCreateSymbolPointerForLocalLibraryDeclarationException(description: String) :
|
public class CanNotCreateSymbolPointerForLocalLibraryDeclarationException(description: String) :
|
||||||
IllegalStateException("Could not create a symbol pointer for local symbol $description")
|
IllegalStateException("Could not create a symbol pointer for local symbol $description")
|
||||||
|
|
||||||
|
public class WrongSymbolForSamConstructor(symbolKind: String) :
|
||||||
|
IllegalStateException(
|
||||||
|
"For symbol with kind = KtSymbolKind.SAM_CONSTRUCTOR, KtSamConstructorSymbol should be created, but was $symbolKind"
|
||||||
|
)
|
||||||
+2
@@ -50,6 +50,8 @@ private constructor(
|
|||||||
|
|
||||||
override val callResolverImpl = KtFirCallResolver(this, token)
|
override val callResolverImpl = KtFirCallResolver(this, token)
|
||||||
|
|
||||||
|
override val samResolverImpl = KtFirSamResolver(this, token)
|
||||||
|
|
||||||
override val scopeProviderImpl by threadLocal { KtFirScopeProvider(this, firSymbolBuilder, project, firResolveState, token) }
|
override val scopeProviderImpl by threadLocal { KtFirScopeProvider(this, firSymbolBuilder, project, firResolveState, token) }
|
||||||
|
|
||||||
override val symbolProviderImpl =
|
override val symbolProviderImpl =
|
||||||
|
|||||||
+13
-1
@@ -191,7 +191,13 @@ internal class KtSymbolByFirBuilder private constructor(
|
|||||||
inner class FunctionLikeSymbolBuilder {
|
inner class FunctionLikeSymbolBuilder {
|
||||||
fun buildFunctionLikeSymbol(fir: FirFunction): KtFunctionLikeSymbol {
|
fun buildFunctionLikeSymbol(fir: FirFunction): KtFunctionLikeSymbol {
|
||||||
return when (fir) {
|
return when (fir) {
|
||||||
is FirSimpleFunction -> buildFunctionSymbol(fir)
|
is FirSimpleFunction -> {
|
||||||
|
if (fir.origin == FirDeclarationOrigin.SamConstructor) {
|
||||||
|
buildSamConstructorSymbol(fir)
|
||||||
|
} else {
|
||||||
|
buildFunctionSymbol(fir)
|
||||||
|
}
|
||||||
|
}
|
||||||
is FirConstructor -> buildConstructorSymbol(fir)
|
is FirConstructor -> buildConstructorSymbol(fir)
|
||||||
is FirAnonymousFunction -> buildAnonymousFunctionSymbol(fir)
|
is FirAnonymousFunction -> buildAnonymousFunctionSymbol(fir)
|
||||||
else -> throwUnexpectedElementError(fir)
|
else -> throwUnexpectedElementError(fir)
|
||||||
@@ -199,6 +205,7 @@ internal class KtSymbolByFirBuilder private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun buildFunctionSymbol(fir: FirSimpleFunction): KtFirFunctionSymbol {
|
fun buildFunctionSymbol(fir: FirSimpleFunction): KtFirFunctionSymbol {
|
||||||
|
check(fir.origin != FirDeclarationOrigin.SamConstructor)
|
||||||
return symbolsCache.cache(fir) { KtFirFunctionSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder) }
|
return symbolsCache.cache(fir) { KtFirFunctionSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +219,11 @@ internal class KtSymbolByFirBuilder private constructor(
|
|||||||
KtFirConstructorSymbol(originalFir, resolveState, token, this@KtSymbolByFirBuilder)
|
KtFirConstructorSymbol(originalFir, resolveState, token, this@KtSymbolByFirBuilder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun buildSamConstructorSymbol(fir: FirSimpleFunction): KtFirSamConstructorSymbol {
|
||||||
|
check(fir.origin == FirDeclarationOrigin.SamConstructor)
|
||||||
|
return symbolsCache.cache(fir) { KtFirSamConstructorSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class VariableLikeSymbolBuilder {
|
inner class VariableLikeSymbolBuilder {
|
||||||
|
|||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.components.KtSamResolver
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.getClassLikeSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSamConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||||
|
|
||||||
|
internal class KtFirSamResolver(
|
||||||
|
override val analysisSession: KtFirAnalysisSession,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtSamResolver(), KtFirAnalysisSessionComponent {
|
||||||
|
|
||||||
|
override fun getSamConstructor(ktClassLikeSymbol: KtClassLikeSymbol): KtSamConstructorSymbol? {
|
||||||
|
val classId = ktClassLikeSymbol.classIdIfNonLocal ?: return null
|
||||||
|
val owner = analysisSession.getClassLikeSymbol(classId) as? FirRegularClass ?: return null
|
||||||
|
val resolver = LocalSamResolver(analysisSession.rootModuleSession)
|
||||||
|
return resolver.getSamConstructor(owner)?.let {
|
||||||
|
analysisSession.firSymbolBuilder.functionLikeBuilder.buildSamConstructorSymbol(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LocalSamResolver(
|
||||||
|
private val firSession: FirSession,
|
||||||
|
) {
|
||||||
|
private val scopeSession = ScopeSession()
|
||||||
|
|
||||||
|
// TODO: This transformer is not intended for actual transformations and
|
||||||
|
// created here only to simplify access to SAM resolver in body resolve components
|
||||||
|
private val stubBodyResolveTransformer = object : FirBodyResolveTransformer(
|
||||||
|
session = firSession,
|
||||||
|
phase = FirResolvePhase.BODY_RESOLVE,
|
||||||
|
implicitTypeOnly = false,
|
||||||
|
scopeSession = scopeSession,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private val bodyResolveComponents =
|
||||||
|
FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents(
|
||||||
|
firSession,
|
||||||
|
scopeSession,
|
||||||
|
stubBodyResolveTransformer,
|
||||||
|
stubBodyResolveTransformer.context,
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: this doesn't guarantee that the same synthetic function (as a SAM constructor) is created/returned
|
||||||
|
fun getSamConstructor(firClass: FirRegularClass): FirSimpleFunction? {
|
||||||
|
val samConstructor = bodyResolveComponents.samResolver.getSamConstructor(firClass) ?: return null
|
||||||
|
if (samConstructor.origin != FirDeclarationOrigin.SamConstructor) return null
|
||||||
|
return samConstructor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-3
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.components.KtSymbolContainingDeclarationProvider
|
import org.jetbrains.kotlin.idea.frontend.api.components.KtSymbolContainingDeclarationProvider
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind
|
||||||
@@ -43,7 +42,7 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
|||||||
getContainingDeclarationForLibrarySymbol(symbol)
|
getContainingDeclarationForLibrarySymbol(symbol)
|
||||||
KtSymbolOrigin.PROPERTY_BACKING_FIELD -> getContainingDeclarationForBackingFieldSymbol(symbol)
|
KtSymbolOrigin.PROPERTY_BACKING_FIELD -> getContainingDeclarationForBackingFieldSymbol(symbol)
|
||||||
KtSymbolOrigin.INTERSECTION_OVERRIDE -> TODO()
|
KtSymbolOrigin.INTERSECTION_OVERRIDE -> TODO()
|
||||||
KtSymbolOrigin.SAM_CONSTRUCTOR -> TODO()
|
KtSymbolOrigin.SAM_CONSTRUCTOR -> null
|
||||||
KtSymbolOrigin.DELEGATED -> TODO()
|
KtSymbolOrigin.DELEGATED -> TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,4 +120,4 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
|||||||
val containingClass = containingClassId.getCorrespondingToplevelClassOrObjectSymbol()
|
val containingClass = containingClassId.getCorrespondingToplevelClassOrObjectSymbol()
|
||||||
return containingClass ?: error("Class with id $containingClassId should exists")
|
return containingClass ?: error("Class with id $containingClassId should exists")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -29,9 +29,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtValueParameterSymbol
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotationCall
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotationCall
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtTypeAndAnnotations
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtTypeAndAnnotations
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.*
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
@@ -118,6 +116,7 @@ internal class KtFirFunctionSymbol(
|
|||||||
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(
|
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(
|
||||||
callableIdIfNonLocal?.toString() ?: name.asString()
|
callableIdIfNonLocal?.toString() ?: name.asString()
|
||||||
)
|
)
|
||||||
|
KtSymbolKind.SAM_CONSTRUCTOR -> throw WrongSymbolForSamConstructor(this::class.java.simpleName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -32,9 +32,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotationCall
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtConstantValue
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtConstantValue
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtTypeAndAnnotations
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtTypeAndAnnotations
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.*
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
@@ -127,6 +125,7 @@ internal class KtFirKotlinPropertySymbol(
|
|||||||
}
|
}
|
||||||
KtSymbolKind.ACCESSOR -> TODO("Creating symbol for accessors is not supported yet")
|
KtSymbolKind.ACCESSOR -> TODO("Creating symbol for accessors is not supported yet")
|
||||||
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(name.asString())
|
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(name.asString())
|
||||||
|
KtSymbolKind.SAM_CONSTRUCTOR -> throw WrongSymbolForSamConstructor(this::class.java.simpleName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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.symbols
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.getHasStableParameterNames
|
||||||
|
import org.jetbrains.kotlin.idea.fir.findPsi
|
||||||
|
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirSamConstructorSymbolPointer
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSamConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtValueParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtTypeAndAnnotations
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||||
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
internal class KtFirSamConstructorSymbol(
|
||||||
|
fir: FirSimpleFunction,
|
||||||
|
resolveState: FirModuleResolveState,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
_builder: KtSymbolByFirBuilder
|
||||||
|
) : KtSamConstructorSymbol(), KtFirSymbol<FirSimpleFunction> {
|
||||||
|
private val builder by weakRef(_builder)
|
||||||
|
override val firRef = firRef(fir, resolveState)
|
||||||
|
override val psi: PsiElement? by firRef.withFirAndCache { fir -> fir.findPsi(fir.moduleData.session) }
|
||||||
|
override val name: Name get() = firRef.withFir { it.name }
|
||||||
|
override val annotatedType: KtTypeAndAnnotations by cached {
|
||||||
|
firRef.returnTypeAndAnnotations(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE, builder)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val valueParameters: List<KtValueParameterSymbol> by firRef.withFirAndCache { fir ->
|
||||||
|
fir.valueParameters.map { valueParameter ->
|
||||||
|
builder.variableLikeBuilder.buildValueParameterSymbol(valueParameter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val hasStableParameterNames: Boolean = firRef.withFir { it.getHasStableParameterNames(it.moduleData.session) }
|
||||||
|
|
||||||
|
override val isExtension: Boolean get() = firRef.withFir { it.receiverTypeRef != null }
|
||||||
|
override val receiverType: KtTypeAndAnnotations? by cached {
|
||||||
|
firRef.receiverTypeAndAnnotations(builder)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val callableIdIfNonLocal: CallableId? get() = getCallableIdIfNonLocal()
|
||||||
|
|
||||||
|
override fun createPointer(): KtSymbolPointer<KtSamConstructorSymbol> {
|
||||||
|
return firRef.withFir { fir ->
|
||||||
|
val callableId = fir.symbol.callableId
|
||||||
|
KtFirSamConstructorSymbolPointer(ClassId(callableId.packageName, callableId.callableName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-1
@@ -47,7 +47,13 @@ internal class KtFirSymbolProvider(
|
|||||||
override fun getFunctionLikeSymbol(psi: KtNamedFunction): KtFunctionLikeSymbol = withValidityAssertion {
|
override fun getFunctionLikeSymbol(psi: KtNamedFunction): KtFunctionLikeSymbol = withValidityAssertion {
|
||||||
psi.withFirDeclarationOfType<FirFunction, KtFunctionLikeSymbol>(resolveState) { fir ->
|
psi.withFirDeclarationOfType<FirFunction, KtFunctionLikeSymbol>(resolveState) { fir ->
|
||||||
when (fir) {
|
when (fir) {
|
||||||
is FirSimpleFunction -> firSymbolBuilder.functionLikeBuilder.buildFunctionSymbol(fir)
|
is FirSimpleFunction -> {
|
||||||
|
if (fir.origin == FirDeclarationOrigin.SamConstructor) {
|
||||||
|
firSymbolBuilder.functionLikeBuilder.buildSamConstructorSymbol(fir)
|
||||||
|
} else {
|
||||||
|
firSymbolBuilder.functionLikeBuilder.buildFunctionSymbol(fir)
|
||||||
|
}
|
||||||
|
}
|
||||||
is FirAnonymousFunction -> firSymbolBuilder.functionLikeBuilder.buildAnonymousFunctionSymbol(fir)
|
is FirAnonymousFunction -> firSymbolBuilder.functionLikeBuilder.buildAnonymousFunctionSymbol(fir)
|
||||||
else -> error("Unexpected ${fir.renderWithType()}")
|
else -> error("Unexpected ${fir.renderWithType()}")
|
||||||
}
|
}
|
||||||
|
|||||||
-5
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||||
@@ -37,7 +36,3 @@ internal abstract class KtFirMemberSymbolPointer<S : KtSymbol>(
|
|||||||
firSession: FirSession
|
firSession: FirSession
|
||||||
): S?
|
): S?
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtFirAnalysisSession.getClassLikeSymbol(classId: ClassId) =
|
|
||||||
firResolveState.rootModuleSession.symbolProvider.getClassLikeSymbolByFqName(classId)?.fir
|
|
||||||
|
|
||||||
|
|||||||
+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.frontend.api.fir.symbols.pointers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSamConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
|
internal class KtFirSamConstructorSymbolPointer(
|
||||||
|
private val ownerClassId: ClassId,
|
||||||
|
) : KtSymbolPointer<KtSamConstructorSymbol>() {
|
||||||
|
override fun restoreSymbol(analysisSession: KtAnalysisSession): KtSamConstructorSymbol? {
|
||||||
|
require(analysisSession is KtFirAnalysisSession)
|
||||||
|
val owner = analysisSession.getClassLikeSymbol(ownerClassId) as? FirRegularClass ?: return null
|
||||||
|
val classSymbol = analysisSession.firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(owner)
|
||||||
|
with(analysisSession) {
|
||||||
|
return classSymbol.getSamConstructor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -9,11 +9,14 @@ import org.jetbrains.kotlin.fir.FirRenderer
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.renderWithType
|
import org.jetbrains.kotlin.fir.renderWithType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.ideSessionComponents
|
import org.jetbrains.kotlin.idea.fir.low.level.api.ideSessionComponents
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
||||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
internal inline fun <reified D : FirDeclaration> FirScope.findDeclarationWithSignature(
|
internal inline fun <reified D : FirDeclaration> FirScope.findDeclarationWithSignature(
|
||||||
signature: IdSignature,
|
signature: IdSignature,
|
||||||
@@ -50,3 +53,6 @@ internal fun FirDeclaration.createSignature(): IdSignature {
|
|||||||
return signatureComposer.composeSignature(this)
|
return signatureComposer.composeSignature(this)
|
||||||
?: error("Could not compose signature for ${this.renderWithType(FirRenderer.RenderMode.WithResolvePhases)}, looks like it is private or local")
|
?: error("Could not compose signature for ${this.renderWithType(FirRenderer.RenderMode.WithResolvePhases)}, looks like it is private or local")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun KtFirAnalysisSession.getClassLikeSymbol(classId: ClassId) =
|
||||||
|
firResolveState.rootModuleSession.symbolProvider.getClassLikeSymbolByFqName(classId)?.fir
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
val greeter = <caret>Runnable { println("Howdy") }
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
KtFirSamConstructorSymbol:
|
||||||
|
annotatedType: [] java/lang/Runnable
|
||||||
|
callableIdIfNonLocal: java/lang/Runnable
|
||||||
|
hasStableParameterNames: true
|
||||||
|
isExtension: false
|
||||||
|
name: Runnable
|
||||||
|
origin: SAM_CONSTRUCTOR
|
||||||
|
receiverType: null
|
||||||
|
symbolKind: SAM_CONSTRUCTOR
|
||||||
|
valueParameters: [
|
||||||
|
KtFirValueParameterSymbol(block)
|
||||||
|
]
|
||||||
|
deprecationStatus: null
|
||||||
+3
-3
@@ -68,7 +68,7 @@ abstract class AbstractSymbolTest : AbstractHLApiSingleFileTest() {
|
|||||||
val restored = analyseOnPooledThreadInReadAction(ktFile) {
|
val restored = analyseOnPooledThreadInReadAction(ktFile) {
|
||||||
pointersWithRendered.map { (pointer, expectedRender) ->
|
pointersWithRendered.map { (pointer, expectedRender) ->
|
||||||
val restored = pointer!!.restoreSymbol()
|
val restored = pointer!!.restoreSymbol()
|
||||||
?: error("Symbol $expectedRender was not not restored")
|
?: error("Symbol $expectedRender was not restored")
|
||||||
with(DebugSymbolRenderer) { renderExtra(restored) }
|
with(DebugSymbolRenderer) { renderExtra(restored) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,9 +84,9 @@ abstract class AbstractSymbolTest : AbstractHLApiSingleFileTest() {
|
|||||||
|
|
||||||
private object SymbolTestDirectives : SimpleDirectivesContainer() {
|
private object SymbolTestDirectives : SimpleDirectivesContainer() {
|
||||||
val DO_NOT_CHECK_SYMBOL_RESTORE by directive(
|
val DO_NOT_CHECK_SYMBOL_RESTORE by directive(
|
||||||
description = "Symbol restoring for some symbols in current test is not yet supported yet",
|
description = "Symbol restoring for some symbols in current test is not supported yet",
|
||||||
applicability = DirectiveApplicability.Global
|
applicability = DirectiveApplicability.Global
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class PointerWithRenderedSymbol(val pointer: KtSymbolPointer<*>?, val rendered: String)
|
private data class PointerWithRenderedSymbol(val pointer: KtSymbolPointer<*>?, val rendered: String)
|
||||||
|
|||||||
+6
@@ -35,4 +35,10 @@ public class SymbolByReferenceTestGenerated extends AbstractSymbolByReferenceTes
|
|||||||
public void testConstructorViaTypeAlias() throws Exception {
|
public void testConstructorViaTypeAlias() throws Exception {
|
||||||
runTest("idea/idea-frontend-fir/testData/symbols/symbolByReference/constructorViaTypeAlias.kt");
|
runTest("idea/idea-frontend-fir/testData/symbols/symbolByReference/constructorViaTypeAlias.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("samConstructor.kt")
|
||||||
|
public void testSamConstructor() throws Exception {
|
||||||
|
runTest("idea/idea-frontend-fir/testData/symbols/symbolByReference/samConstructor.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user