FIR IDE: avoid finding symbol for function type parameter

This commit is contained in:
Jinseong Jeon
2021-07-13 12:07:43 -07:00
committed by Ilya Kirillov
parent 2e502bd01e
commit 9ec4d19a3f
6 changed files with 173 additions and 5 deletions
@@ -140,8 +140,39 @@ public class KtParameter extends KtNamedDeclarationStub<KotlinParameterStub> imp
return getParent() instanceof KtForExpression;
}
private <T extends PsiElement> boolean checkParentOfParentType(Class<T> klass) {
// `parent` is supposed to be [KtParameterList]
PsiElement parent = getParent();
if (parent == null) {
return false;
}
return klass.isInstance(parent.getParent());
}
public boolean isCatchParameter() {
return getParent().getParent() instanceof KtCatchClause;
return checkParentOfParentType(KtCatchClause.class);
}
/**
* For example,
* lambdaConsumer { lambdaParameter ->
* ...
* }
*
* @return [true] if this [KtParameter] is a parameter of a lambda.
*/
public boolean isLambdaParameter() {
return checkParentOfParentType(KtFunctionLiteral.class);
}
/**
* For example,
* fun foo(lambdaArgument: (functionTypeParameter: T, ...) -> R) { ... }
*
* @return [true] if this [KtParameter] is a parameter of a function type.
*/
public boolean isFunctionTypeParameter() {
return checkParentOfParentType(KtFunctionType.class);
}
@Nullable
@@ -57,6 +57,12 @@ public interface KtSymbolProviderMixIn : KtAnalysisSessionMixIn {
public fun KtDeclaration.getSymbol(): KtSymbol =
analysisSession.symbolProvider.getSymbol(this)
/**
* Creates [KtValueParameterSymbol] by [KtParameter]
*
* If [KtParameter.isFunctionTypeParameter] is `true`, i.e., if the given [KtParameter] is used as a function type parameter,
* it is not possible to create [KtValueParameterSymbol], hence an error will be raised.
*/
public fun KtParameter.getParameterSymbol(): KtValueParameterSymbol =
analysisSession.symbolProvider.getParameterSymbol(this)
@@ -117,4 +123,4 @@ public interface KtSymbolProviderMixIn : KtAnalysisSessionMixIn {
@Suppress("PropertyName")
public val ROOT_PACKAGE_SYMBOL: KtPackageSymbol
get() = analysisSession.symbolProvider.ROOT_PACKAGE_SYMBOL
}
}
@@ -35,6 +35,9 @@ internal class KtFirSymbolProvider(
private val firSymbolProvider by weakRef(firSymbolProvider)
override fun getParameterSymbol(psi: KtParameter): KtValueParameterSymbol = withValidityAssertion {
if (psi.isFunctionTypeParameter) {
error("Creating KtValueParameterSymbol for function type parameter is not possible. Please see the KDoc of getParameterSymbol")
}
psi.withFirDeclarationOfType<FirValueParameter, KtValueParameterSymbol>(resolveState) {
firSymbolBuilder.variableLikeBuilder.buildValueParameterSymbol(it)
}
@@ -11,6 +11,16 @@ fun foo() {
else
a - c
}
bar {
if (it > 5) return
val b = 1
it + b
}
}
private inline fun bar(lmbd: (Int) -> Int) {
lmbd(1)
}
// RESULT
@@ -99,6 +109,25 @@ KtFirLocalVariableSymbol:
receiverType: null
symbolKind: LOCAL
KtFirLocalVariableSymbol:
annotatedType: [] kotlin/Int
callableIdIfNonLocal: null
isExtension: false
isVal: true
name: b
origin: SOURCE
receiverType: null
symbolKind: LOCAL
KtFirAnonymousFunctionSymbol:
annotatedType: [] kotlin/Int
callableIdIfNonLocal: null
isExtension: false
origin: SOURCE
receiverType: null
symbolKind: LOCAL
valueParameters: [KtFirValueParameterSymbol(it)]
KtFirFunctionSymbol:
annotatedType: [] kotlin/Unit
annotationClassIds: []
@@ -121,4 +150,40 @@ KtFirFunctionSymbol:
typeParameters: []
valueParameters: []
visibility: Public
*/
KtFirValueParameterSymbol:
annotatedType: [] kotlin/Function1<kotlin/Int, kotlin/Int>
annotationClassIds: []
annotations: []
callableIdIfNonLocal: null
hasDefaultValue: false
isExtension: false
isVararg: false
name: lmbd
origin: SOURCE
receiverType: null
symbolKind: LOCAL
KtFirFunctionSymbol:
annotatedType: [] kotlin/Unit
annotationClassIds: []
annotations: []
callableIdIfNonLocal: /bar
dispatchType: null
isExtension: false
isExternal: false
isInfix: false
isInline: true
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: bar
origin: SOURCE
receiverType: null
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [KtFirValueParameterSymbol(lmbd)]
visibility: Private
*/
@@ -82,6 +82,25 @@ KtFirLocalVariableSymbol:
receiverType: null
symbolKind: LOCAL
KtFirLocalVariableSymbol:
annotatedType: [] kotlin/Int
callableIdIfNonLocal: null
isExtension: false
isVal: true
name: b
origin: SOURCE
receiverType: null
symbolKind: LOCAL
KtFirAnonymousFunctionSymbol:
annotatedType: [] kotlin/Int
callableIdIfNonLocal: null
isExtension: false
origin: SOURCE
receiverType: null
symbolKind: LOCAL
valueParameters: [KtFirValueParameterSymbol(it)]
KtFirFunctionSymbol:
annotatedType: [] kotlin/Unit
annotationClassIds: []
@@ -104,3 +123,39 @@ KtFirFunctionSymbol:
typeParameters: []
valueParameters: []
visibility: Public
KtFirValueParameterSymbol:
annotatedType: [] kotlin/Function1<kotlin/Int, kotlin/Int>
annotationClassIds: []
annotations: []
callableIdIfNonLocal: null
hasDefaultValue: false
isExtension: false
isVararg: false
name: lmbd
origin: SOURCE
receiverType: null
symbolKind: LOCAL
KtFirFunctionSymbol:
annotatedType: [] kotlin/Unit
annotationClassIds: []
annotations: []
callableIdIfNonLocal: /bar
dispatchType: null
isExtension: false
isExternal: false
isInfix: false
isInline: true
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: bar
origin: SOURCE
receiverType: null
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [KtFirValueParameterSymbol(lmbd)]
visibility: Private
@@ -9,13 +9,21 @@ import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.test.services.TestServices
abstract class AbstractSymbolByPsiTest : AbstractSymbolTest() {
override fun KtAnalysisSession.collectSymbols(ktFile: KtFile, testServices: TestServices): List<KtSymbol> {
return ktFile.collectDescendantsOfType<KtDeclaration>().map { declaration ->
return ktFile.collectDescendantsOfType<KtDeclaration> { it.isValidForSymbolCreation }.map { declaration ->
declaration.getSymbol()
}
}
}
private val KtDeclaration.isValidForSymbolCreation
get() =
when (this) {
is KtParameter -> !this.isFunctionTypeParameter
else -> true
}
}