FIR IDE: new symbol/kind/pointer/resolver for SAM constructor

This commit is contained in:
Jinseong Jeon
2021-08-17 23:32:35 -07:00
committed by Ilya Kirillov
parent 7df5ebf6ee
commit da3f2c2095
22 changed files with 264 additions and 24 deletions
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.psi.KtFile
public abstract class KtAnalysisSession(final override val token: ValidityToken) : ValidityTokenOwner,
KtSmartCastProviderMixIn,
KtCallResolverMixIn,
KtSamResolverMixIn,
KtDiagnosticProviderMixIn,
KtScopeProviderMixIn,
KtCompletionCandidateCheckerMixIn,
@@ -75,6 +76,9 @@ public abstract class KtAnalysisSession(final override val token: ValidityToken)
internal val callResolver: KtCallResolver get() = callResolverImpl
protected abstract val callResolverImpl: KtCallResolver
internal val samResolver: KtSamResolver get() = samResolverImpl
protected abstract val samResolverImpl: KtSamResolver
internal val completionCandidateChecker: KtCompletionCandidateChecker get() = completionCandidateCheckerImpl
protected abstract val completionCandidateCheckerImpl: KtCompletionCandidateChecker
@@ -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)
}
@@ -85,6 +85,7 @@ public object DebugSymbolRenderer {
val symbolTag = when (value) {
is KtClassLikeSymbol -> renderValue(value.classIdIfNonLocal ?: "<local>/${value.name}")
is KtFunctionSymbol -> renderValue(value.callableIdIfNonLocal ?: "<local>/${value.name}")
is KtSamConstructorSymbol -> renderValue(value.callableIdIfNonLocal ?: "<local>/${value.name}")
is KtConstructorSymbol -> "<constructor>"
is KtNamedSymbol -> renderValue(value.name)
is KtPropertyGetterSymbol -> "<getter>"
@@ -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.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
public abstract class KtFunctionLikeSymbol : KtCallableSymbol(), KtSymbolWithKind {
public abstract val valueParameters: List<KtValueParameterSymbol>
@@ -31,6 +30,12 @@ public abstract class KtAnonymousFunctionSymbol : KtFunctionLikeSymbol() {
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(),
KtNamedSymbol,
KtPossibleMemberSymbol,
@@ -64,4 +69,4 @@ public abstract class KtConstructorSymbol : KtFunctionLikeSymbol(),
final override val receiverType: KtTypeAndAnnotations? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtConstructorSymbol>
}
}
@@ -67,6 +67,12 @@ public enum class KtSymbolOrigin {
*/
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,
/**
@@ -102,4 +108,4 @@ public enum class KtSymbolOrigin {
* @see KtBackingFieldSymbol
*/
PROPERTY_BACKING_FIELD,
}
}
@@ -15,6 +15,10 @@ public interface KtSymbolWithKind : KtSymbol {
}
public enum class KtSymbolKind {
TOP_LEVEL, MEMBER, LOCAL, ACCESSOR
TOP_LEVEL,
MEMBER,
LOCAL,
ACCESSOR,
SAM_CONSTRUCTOR,
}
@@ -6,4 +6,9 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols.pointers
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"
)
@@ -50,6 +50,8 @@ private constructor(
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 symbolProviderImpl =
@@ -191,7 +191,13 @@ internal class KtSymbolByFirBuilder private constructor(
inner class FunctionLikeSymbolBuilder {
fun buildFunctionLikeSymbol(fir: FirFunction): KtFunctionLikeSymbol {
return when (fir) {
is FirSimpleFunction -> buildFunctionSymbol(fir)
is FirSimpleFunction -> {
if (fir.origin == FirDeclarationOrigin.SamConstructor) {
buildSamConstructorSymbol(fir)
} else {
buildFunctionSymbol(fir)
}
}
is FirConstructor -> buildConstructorSymbol(fir)
is FirAnonymousFunction -> buildAnonymousFunctionSymbol(fir)
else -> throwUnexpectedElementError(fir)
@@ -199,6 +205,7 @@ internal class KtSymbolByFirBuilder private constructor(
}
fun buildFunctionSymbol(fir: FirSimpleFunction): KtFirFunctionSymbol {
check(fir.origin != FirDeclarationOrigin.SamConstructor)
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)
}
}
fun buildSamConstructorSymbol(fir: FirSimpleFunction): KtFirSamConstructorSymbol {
check(fir.origin == FirDeclarationOrigin.SamConstructor)
return symbolsCache.cache(fir) { KtFirSamConstructorSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder) }
}
}
inner class VariableLikeSymbolBuilder {
@@ -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
}
}
}
@@ -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.fir.KtFirAnalysisSession
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.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind
@@ -43,7 +42,7 @@ internal class KtFirSymbolContainingDeclarationProvider(
getContainingDeclarationForLibrarySymbol(symbol)
KtSymbolOrigin.PROPERTY_BACKING_FIELD -> getContainingDeclarationForBackingFieldSymbol(symbol)
KtSymbolOrigin.INTERSECTION_OVERRIDE -> TODO()
KtSymbolOrigin.SAM_CONSTRUCTOR -> TODO()
KtSymbolOrigin.SAM_CONSTRUCTOR -> null
KtSymbolOrigin.DELEGATED -> TODO()
}
}
@@ -121,4 +120,4 @@ internal class KtFirSymbolContainingDeclarationProvider(
val containingClass = containingClassId.getCorrespondingToplevelClassOrObjectSymbol()
return containingClass ?: error("Class with id $containingClassId should exists")
}
}
}
@@ -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.KtSymbolKind
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.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.*
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.name.CallableId
@@ -118,6 +116,7 @@ internal class KtFirFunctionSymbol(
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(
callableIdIfNonLocal?.toString() ?: name.asString()
)
KtSymbolKind.SAM_CONSTRUCTOR -> throw WrongSymbolForSamConstructor(this::class.java.simpleName)
}
}
@@ -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.KtSymbolKind
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.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.*
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
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.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(name.asString())
KtSymbolKind.SAM_CONSTRUCTOR -> throw WrongSymbolForSamConstructor(this::class.java.simpleName)
}
}
@@ -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))
}
}
}
@@ -47,7 +47,13 @@ internal class KtFirSymbolProvider(
override fun getFunctionLikeSymbol(psi: KtNamedFunction): KtFunctionLikeSymbol = withValidityAssertion {
psi.withFirDeclarationOfType<FirFunction, KtFunctionLikeSymbol>(resolveState) { 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)
else -> error("Unexpected ${fir.renderWithType()}")
}
@@ -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.declarations.FirRegularClass
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.unsubstitutedScope
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
@@ -37,7 +36,3 @@ internal abstract class KtFirMemberSymbolPointer<S : KtSymbol>(
firSession: FirSession
): S?
}
private fun KtFirAnalysisSession.getClassLikeSymbol(classId: ClassId) =
firResolveState.rootModuleSession.symbolProvider.getClassLikeSymbolByFqName(classId)?.fir
@@ -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()
}
}
}
@@ -9,11 +9,14 @@ import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
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.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
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.name.ClassId
internal inline fun <reified D : FirDeclaration> FirScope.findDeclarationWithSignature(
signature: IdSignature,
@@ -50,3 +53,6 @@ internal fun FirDeclaration.createSignature(): IdSignature {
return signatureComposer.composeSignature(this)
?: 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
@@ -68,7 +68,7 @@ abstract class AbstractSymbolTest : AbstractHLApiSingleFileTest() {
val restored = analyseOnPooledThreadInReadAction(ktFile) {
pointersWithRendered.map { (pointer, expectedRender) ->
val restored = pointer!!.restoreSymbol()
?: error("Symbol $expectedRender was not not restored")
?: error("Symbol $expectedRender was not restored")
with(DebugSymbolRenderer) { renderExtra(restored) }
}
}
@@ -84,9 +84,9 @@ abstract class AbstractSymbolTest : AbstractHLApiSingleFileTest() {
private object SymbolTestDirectives : SimpleDirectivesContainer() {
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
)
}
private data class PointerWithRenderedSymbol(val pointer: KtSymbolPointer<*>?, val rendered: String)
private data class PointerWithRenderedSymbol(val pointer: KtSymbolPointer<*>?, val rendered: String)
@@ -35,4 +35,10 @@ public class SymbolByReferenceTestGenerated extends AbstractSymbolByReferenceTes
public void testConstructorViaTypeAlias() throws Exception {
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");
}
}