diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt index b42980a0e3a..ff57dc6eb27 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt @@ -6,14 +6,13 @@ package org.jetbrains.kotlin.idea.completion import com.intellij.codeInsight.completion.* +import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.patterns.PlatformPatterns -import com.intellij.patterns.PsiJavaPatterns import com.intellij.util.ProcessingContext import org.jetbrains.kotlin.idea.frontend.api.getAnalysisSessionFor import org.jetbrains.kotlin.idea.frontend.api.symbols.* import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.references.mainReference -import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtLabelReferenceExpression import org.jetbrains.kotlin.psi.KtSimpleNameExpression @@ -38,40 +37,38 @@ private object KotlinHighLevelApiContributor : CompletionProvider + override fun visitExpression(expression: KtExpression) = with(analysisSession) { + expression.getImplicitReceiverSmartCasts().forEach { (types, kind) -> val receiverName = when (kind) { ImplicitReceiverSmartcastKind.EXTENSION -> KotlinIdeaAnalysisBundle.message("extension.implicit.receiver") ImplicitReceiverSmartcastKind.DISPATCH -> KotlinIdeaAnalysisBundle.message("implicit.receiver") @@ -34,7 +34,7 @@ internal class ExpressionsSmartcastHighlightingVisitor( ).textAttributes = org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingColors.SMART_CAST_RECEIVER } } - analysisSession.getSmartCastedToTypes(expression)?.forEach { type -> + expression.getSmartCasts()?.forEach { type -> createInfoAnnotation( getSmartCastTarget(expression), KotlinIdeaAnalysisBundle.message( diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/FunctionCallHighlightingVisitor.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/FunctionCallHighlightingVisitor.kt index 7648ed8a71b..1a64c3c9747 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/FunctionCallHighlightingVisitor.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/FunctionCallHighlightingVisitor.kt @@ -21,13 +21,13 @@ internal class FunctionCallHighlightingVisitor( analysisSession: KtAnalysisSession, holder: AnnotationHolder ) : FirAfterResolveHighlightingVisitor(analysisSession, holder) { - override fun visitBinaryExpression(expression: KtBinaryExpression) { + override fun visitBinaryExpression(expression: KtBinaryExpression) = with(analysisSession) { (expression.operationReference as? KtReferenceExpression) ?.takeIf { // do not highlight assignment statement (it as? KtOperationReferenceExpression)?.operationSignTokenType != KtTokens.EQ }?.let { callee -> - analysisSession.resolveCall(expression) + expression.resolveCall() ?.takeIf { callInfo -> // ignore arithmetic-like operator calls (callInfo.targetFunction as? KtFunctionSymbol)?.isOperator != true @@ -41,12 +41,12 @@ internal class FunctionCallHighlightingVisitor( super.visitBinaryExpression(expression) } - override fun visitCallExpression(expression: KtCallExpression) { + override fun visitCallExpression(expression: KtCallExpression) = with(analysisSession) { expression.calleeExpression ?.takeUnless { it is KtLambdaExpression } - ?.takeUnless { it is KtCallExpression /* KT-16159 */} + ?.takeUnless { it is KtCallExpression /* KT-16159 */ } ?.let { callee -> - analysisSession.resolveCall(expression)?.let { callInfo -> + expression.resolveCall()?.let { callInfo -> getTextAttributesForCal(callInfo)?.let { attributes -> highlightName(callee, attributes) } diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/inspections/AddFunctionReturnTypeIntention.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/inspections/AddFunctionReturnTypeIntention.kt index 9205b8a7893..ce5c37ccdaf 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/inspections/AddFunctionReturnTypeIntention.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/inspections/AddFunctionReturnTypeIntention.kt @@ -20,9 +20,9 @@ class AddFunctionReturnTypeIntention : element.typeReference == null && !element.hasBlockBody() override fun KtAnalysisSession.analyzeAndGetData(element: KtNamedFunction): TypeCandidate? { - val returnType = getReturnTypeForKtDeclaration(element) + val returnType = element.getReturnKtType() val approximated = approximateTypeToUpperDenotable(returnType) ?: return null - return TypeCandidate(KtTypeRenderer.render(approximated)) + return TypeCandidate(approximated.render()) } private tailrec fun approximateTypeToUpperDenotable(type: KtType): KtDenotableType? = when (type) { diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt index 17a00f68f33..dfa263399ba 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt @@ -6,10 +6,17 @@ package org.jetbrains.kotlin.idea.frontend.api import org.jetbrains.kotlin.diagnostics.Diagnostic -import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeProvider +import org.jetbrains.kotlin.idea.frontend.api.components.* +import org.jetbrains.kotlin.idea.frontend.api.scopes.* import org.jetbrains.kotlin.idea.frontend.api.symbols.* +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind +import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.references.KtReference +import org.jetbrains.kotlin.idea.references.KtSimpleReference import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* /** @@ -25,24 +32,86 @@ import org.jetbrains.kotlin.psi.* * To create analysis session consider using [analyze] */ abstract class KtAnalysisSession(override val token: ValidityToken) : ValidityTokenOwner { - abstract val symbolProvider: KtSymbolProvider - abstract val scopeProvider: KtScopeProvider - abstract val containingDeclarationProvider: KtSymbolContainingDeclarationProvider + protected abstract val smartCastProvider: KtSmartCastProvider + protected abstract val typeProvider: KtTypeProvider + protected abstract val diagnosticProvider: KtDiagnosticProvider + protected abstract val scopeProvider: KtScopeProvider + protected abstract val containingDeclarationProvider: KtSymbolContainingDeclarationProvider + protected abstract val symbolProvider: KtSymbolProvider + protected abstract val callResolver: KtCallResolver - abstract fun getSmartCastedToTypes(expression: KtExpression): Collection? - - abstract fun getImplicitReceiverSmartCasts(expression: KtExpression): Collection - - abstract fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType - - abstract fun getKtExpressionType(expression: KtExpression): KtType - - abstract fun isSubclassOf(klass: KtClassOrObject, superClassId: ClassId): Boolean - - abstract fun getDiagnosticsForElement(element: KtElement): Collection - - abstract fun resolveCall(call: KtCallExpression): CallInfo? - abstract fun resolveCall(call: KtBinaryExpression): CallInfo? + /// TODO: get rid of + @Deprecated("Used only in completion now, temporary") abstract fun createContextDependentCopy(): KtAnalysisSession + + + fun KtExpression.getSmartCasts(): Collection = smartCastProvider.getSmartCastedToTypes(this) + + fun KtExpression.getImplicitReceiverSmartCasts(): Collection = smartCastProvider.getImplicitReceiverSmartCasts(this) + + fun KtExpression.getKtType(): KtType = typeProvider.getKtExpressionType(this) + + fun KtDeclaration.getReturnKtType(): KtType = typeProvider.getReturnTypeForKtDeclaration(this) + + fun KtElement.getDiagnostics(): Collection = diagnosticProvider.getDiagnosticsForElement(this) + + fun KtSymbolWithKind.getContainingSymbol(): KtSymbolWithKind? = containingDeclarationProvider.getContainingDeclaration(this) + + fun KtClassOrObjectSymbol.getMemberScope(): KtMemberScope = scopeProvider.getMemberScope(this) + + fun KtClassOrObjectSymbol.getDeclaredMemberScope(): KtDeclaredMemberScope = scopeProvider.getDeclaredMemberScope(this) + + fun KtPackageSymbol.getPackageScope(): KtPackageScope = scopeProvider.getPackageScope(this) + + fun List.asCompositeScope(): KtCompositeScope = scopeProvider.getCompositeScope(this) + + fun KtType.getTypeScope(): KtScope? = scopeProvider.getTypeScope(this) + + fun KtFile.getScopeContextForPosition(positionInFakeFile: KtElement): KtScopeContext = scopeProvider.getScopeContextForPosition(this, positionInFakeFile) + + fun KtDeclaration.getSymbol(): KtSymbol = symbolProvider.getSymbol(this) + + fun KtParameter.getParameterSymbol(): KtParameterSymbol = symbolProvider.getParameterSymbol(this) + + fun KtNamedFunction.getFunctionSymbol(): KtFunctionSymbol = symbolProvider.getFunctionSymbol(this) + + fun KtConstructor<*>.getConstructorSymbol(): KtConstructorSymbol = symbolProvider.getConstructorSymbol(this) + + fun KtTypeParameter.getTypeParameterSymbol(): KtTypeParameterSymbol = symbolProvider.getTypeParameterSymbol(this) + + fun KtTypeAlias.getTypeAliasSymbol(): KtTypeAliasSymbol = symbolProvider.getTypeAliasSymbol(this) + + fun KtEnumEntry.getEnumEntrySymbol(): KtEnumEntrySymbol = symbolProvider.getEnumEntrySymbol(this) + + fun KtNamedFunction.getAnonymousFunctionSymbol(): KtAnonymousFunctionSymbol = symbolProvider.getAnonymousFunctionSymbol(this) + + fun KtLambdaExpression.getAnonymousFunctionSymbol(): KtAnonymousFunctionSymbol = symbolProvider.getAnonymousFunctionSymbol(this) + + fun KtProperty.getVariableSymbol(): KtVariableSymbol = symbolProvider.getVariableSymbol(this) + + fun KtClassOrObject.getClassOrObjectSymbol(): KtClassOrObjectSymbol = symbolProvider.getClassOrObjectSymbol(this) + + /** + * @return symbol with specified [this@getClassOrObjectSymbolByClassId] or `null` in case such symbol is not found + */ + fun ClassId.getCorrespondingToplevelClassOrObjectSymbol(): KtClassOrObjectSymbol? = symbolProvider.getClassOrObjectSymbolByClassId(this) + + fun FqName.getContainingCallableSymbolsWithName(name: Name): Sequence = symbolProvider.getTopLevelCallableSymbols(this, name) + + fun KtSymbolPointer.restoreSymbol(): S? = restoreSymbol(this@KtAnalysisSession) + + fun KtCallExpression.resolveCall(): CallInfo? = callResolver.resolveCall(this) + + fun KtBinaryExpression.resolveCall(): CallInfo? = callResolver.resolveCall(this) + + fun KtReference.resolveToSymbols(): Collection { + check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference" } + return this@KtAnalysisSession.resolveToSymbols() + } + + fun KtSimpleReference<*>.resolveToSymbol(): KtSymbol? { + check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference but was ${this::class}" } + return resolveToSymbols().singleOrNull() + } } diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtSymbolBasedReference.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtSymbolBasedReference.kt index f0c0e7ac57f..774cc6225bb 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtSymbolBasedReference.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtSymbolBasedReference.kt @@ -10,15 +10,5 @@ import org.jetbrains.kotlin.idea.references.KtReference import org.jetbrains.kotlin.idea.references.KtSimpleReference interface KtSymbolBasedReference : KtReference { - fun resolveToSymbols(analysisSession: KtAnalysisSession): Collection -} - -fun KtReference.resolveToSymbols(analysisSession: KtAnalysisSession): Collection { - check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference" } - return resolveToSymbols(analysisSession) -} - -fun KtSimpleReference<*>.resolveToSymbol(analysisSession: KtAnalysisSession): KtSymbol? { - check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference but was ${this::class}" } - return resolveToSymbols(analysisSession).singleOrNull() + fun KtAnalysisSession.resolveToSymbols(): Collection } \ No newline at end of file diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtAnalysisSessionComponent.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtAnalysisSessionComponent.kt new file mode 100644 index 00000000000..07b50d2df6b --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtAnalysisSessionComponent.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2020 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.KtAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.ValidityToken +import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner + +abstract class KtAnalysisSessionComponent : ValidityTokenOwner { + protected abstract val analysisSession: KtAnalysisSession + final override val token: ValidityToken get() = analysisSession.token +} \ No newline at end of file diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtCallResolver.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtCallResolver.kt new file mode 100644 index 00000000000..011ea9c37fb --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtCallResolver.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2020 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.CallInfo +import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtCallExpression + +abstract class KtCallResolver : KtAnalysisSessionComponent() { + abstract fun resolveCall(call: KtCallExpression): CallInfo? + abstract fun resolveCall(call: KtBinaryExpression): CallInfo? +} \ No newline at end of file diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtDiagnosticProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtDiagnosticProvider.kt new file mode 100644 index 00000000000..6b723f84066 --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtDiagnosticProvider.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2010-2020 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.diagnostics.Diagnostic +import org.jetbrains.kotlin.psi.KtElement + +abstract class KtDiagnosticProvider : KtAnalysisSessionComponent() { + abstract fun getDiagnosticsForElement(element: KtElement): Collection +} \ No newline at end of file diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/scopes/KtScopeProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtScopeProvider.kt similarity index 82% rename from idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/scopes/KtScopeProvider.kt rename to idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtScopeProvider.kt index 44ac3377cf7..b74f00b183c 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/scopes/KtScopeProvider.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtScopeProvider.kt @@ -3,22 +3,22 @@ * 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.scopes +package org.jetbrains.kotlin.idea.frontend.api.components -import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner +import org.jetbrains.kotlin.idea.frontend.api.scopes.* import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPackageSymbol import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile -abstract class KtScopeProvider : ValidityTokenOwner { +abstract class KtScopeProvider : KtAnalysisSessionComponent() { abstract fun getMemberScope(classSymbol: KtClassOrObjectSymbol): KtMemberScope abstract fun getDeclaredMemberScope(classSymbol: KtClassOrObjectSymbol): KtDeclaredMemberScope abstract fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope abstract fun getCompositeScope(subScopes: List): KtCompositeScope - abstract fun getScopeForType(type: KtType): KtScope? + abstract fun getTypeScope(type: KtType): KtScope? abstract fun getScopeContextForPosition(originalFile: KtFile, positionInFakeFile: KtElement): KtScopeContext } diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSmartCastProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSmartCastProvider.kt new file mode 100644 index 00000000000..1c80a97dcb8 --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSmartCastProvider.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2020 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.ImplicitReceiverSmartCast +import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.psi.KtExpression + +abstract class KtSmartCastProvider : KtAnalysisSessionComponent() { + abstract fun getSmartCastedToTypes(expression: KtExpression): Collection + abstract fun getImplicitReceiverSmartCasts(expression: KtExpression): Collection +} \ No newline at end of file diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbolContainingDeclarationProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSymbolContainingDeclarationProvider.kt similarity index 81% rename from idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbolContainingDeclarationProvider.kt rename to idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSymbolContainingDeclarationProvider.kt index 417cf8bfbd3..eea4d4181f5 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbolContainingDeclarationProvider.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSymbolContainingDeclarationProvider.kt @@ -3,11 +3,11 @@ * 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.symbols +package org.jetbrains.kotlin.idea.frontend.api.components import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind -abstract class KtSymbolContainingDeclarationProvider { +abstract class KtSymbolContainingDeclarationProvider : KtAnalysisSessionComponent() { /** * Returns containing declaration for symbol: * for top-level declarations returns null diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt new file mode 100644 index 00000000000..eb3f0d1ae46 --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2020 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.types.KtType +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtExpression + +abstract class KtTypeProvider : KtAnalysisSessionComponent() { + abstract fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType + abstract fun getKtExpressionType(expression: KtExpression): KtType +} \ No newline at end of file diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtPsiBasedSymbolPointer.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtPsiBasedSymbolPointer.kt index b218c704610..f95eca7f3ce 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtPsiBasedSymbolPointer.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtPsiBasedSymbolPointer.kt @@ -17,7 +17,7 @@ class KtPsiBasedSymbolPointer(private val psiPointer: SmartPsiElem val psi = psiPointer.element ?: return null @Suppress("UNCHECKED_CAST") - return analysisSession.symbolProvider.getSymbol(psi) as S? + return with(analysisSession) { psi.getSymbol() } as S? } companion object { diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtSymbolPointer.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtSymbolPointer.kt index 33f4e3e472c..c7bf5c01885 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtSymbolPointer.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtSymbolPointer.kt @@ -26,7 +26,10 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol abstract class KtSymbolPointer { /** * @return restored symbol (possibly the new symbol instance) if one is still valid, `null` otherwise + * + * Consider using [org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession.restoreSymbol] */ + @Deprecated("Consider using org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession.restoreSymbol") abstract fun restoreSymbol(analysisSession: KtAnalysisSession): S? } diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtTypeRenderer.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtTypeRenderer.kt index 1ceabb5f396..b488abec940 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtTypeRenderer.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtTypeRenderer.kt @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.idea.frontend.api.types import org.jetbrains.kotlin.idea.frontend.api.* import org.jetbrains.kotlin.name.ClassId -object KtTypeRenderer { +private object KtTypeRenderer { fun render(type: KtType, options: KtTypeRendererOptions = KtTypeRendererOptions.DEFAULT): String = type.withValidityAssertion { buildString { render(type, options) } } @@ -108,4 +108,8 @@ data class KtTypeRendererOptions( renderFqNames = true ) } -} \ No newline at end of file +} + +fun KtType.render(options: KtTypeRendererOptions = KtTypeRendererOptions.DEFAULT): String = + KtTypeRenderer.render(this, options) + diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt index 212d61fd074..ef35bfd513c 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt @@ -5,37 +5,20 @@ package org.jetbrains.kotlin.idea.frontend.api.fir -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.diagnostics.Diagnostic -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.declarations.FirClass -import org.jetbrains.kotlin.fir.declarations.isSuspend -import org.jetbrains.kotlin.fir.expressions.* -import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.firSymbolProvider -import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike import org.jetbrains.kotlin.fir.scopes.FirScope -import org.jetbrains.kotlin.fir.symbols.CallableId -import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol -import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.idea.fir.* import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade -import org.jetbrains.kotlin.idea.frontend.api.* -import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.KtFirScopeProvider -import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbolContainingDeclarationProvider +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.ReadActionConfinementValidityToken +import org.jetbrains.kotlin.idea.frontend.api.ValidityToken +import org.jetbrains.kotlin.idea.frontend.api.assertIsValid +import org.jetbrains.kotlin.idea.frontend.api.components.* +import org.jetbrains.kotlin.idea.frontend.api.fir.components.* import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbolProvider -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.* -import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeProvider -import org.jetbrains.kotlin.idea.frontend.api.symbols.* -import org.jetbrains.kotlin.idea.frontend.api.types.KtType -import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper -import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper.toTargetSymbol -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.idea.frontend.api.fir.utils.threadLocal +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolProvider +import org.jetbrains.kotlin.psi.KtElement internal class KtFirAnalysisSession private constructor( @@ -45,85 +28,23 @@ private constructor( token: ValidityToken, val isContextSession: Boolean, ) : KtAnalysisSession(token) { - private val project = element.project - - override val symbolProvider: KtSymbolProvider = - KtFirSymbolProvider( - token, - firResolveState.firIdeLibrariesSession.firSymbolProvider, - firResolveState, - firSymbolBuilder - ) - - private val firScopeStorage = FirScopeRegistry() - - override val scopeProvider: KtScopeProvider by threadLocal { - KtFirScopeProvider(token, firSymbolBuilder, project, firResolveState, firScopeStorage) - } - - override val containingDeclarationProvider: KtSymbolContainingDeclarationProvider = - KtFirSymbolContainingDeclarationProvider(this) - init { assertIsValid() } - override fun getSmartCastedToTypes(expression: KtExpression): Collection? = withValidityAssertion { - // TODO filter out not used smartcasts - expression.getOrBuildFirSafe(firResolveState)?.typesFromSmartCast?.map { it.asTypeInfo() } - } + private val project = element.project + private val firScopeStorage = FirScopeRegistry() - @OptIn(ExperimentalStdlibApi::class) - override fun getImplicitReceiverSmartCasts(expression: KtExpression): Collection = withValidityAssertion { - // TODO filter out not used smartcasts - val qualifiedExpression = expression.getOrBuildFirSafe(firResolveState) ?: return emptyList() - if (qualifiedExpression.dispatchReceiver !is FirExpressionWithSmartcast - && qualifiedExpression.extensionReceiver !is FirExpressionWithSmartcast - ) return emptyList() - buildList { - (qualifiedExpression.dispatchReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> - ImplicitReceiverSmartCast( - smartCasted.typesFromSmartCast.map { it.asTypeInfo() }, - ImplicitReceiverSmartcastKind.DISPATCH - ) - }?.let(::add) - (qualifiedExpression.extensionReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> - ImplicitReceiverSmartCast( - smartCasted.typesFromSmartCast.map { it.asTypeInfo() }, - ImplicitReceiverSmartcastKind.EXTENSION - ) - }?.let(::add) - } - } + override val smartCastProvider: KtSmartCastProvider = KtFirSmartcastProvider(this) + override val typeProvider: KtTypeProvider = KtFirTypeProvider(this) + override val diagnosticProvider: KtDiagnosticProvider = KtFirDiagnosticProvider(this) + override val containingDeclarationProvider = KtFirSymbolContainingDeclarationProvider(this) + override val callResolver: KtCallResolver = KtFirCallResolver(this) + override val scopeProvider by threadLocal { KtFirScopeProvider(this, firSymbolBuilder, project, firResolveState, firScopeStorage) } + override val symbolProvider: KtSymbolProvider = + KtFirSymbolProvider(token, firResolveState.firIdeLibrariesSession.firSymbolProvider, firResolveState, firSymbolBuilder) - override fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType = withValidityAssertion { - val firDeclaration = declaration.getOrBuildFirOfType>(firResolveState) - firDeclaration.returnTypeRef.coneType.asTypeInfo() - } - - override fun getKtExpressionType(expression: KtExpression): KtType = withValidityAssertion { - expression.getOrBuildFirOfType(firResolveState).typeRef.coneType.asTypeInfo() - } - - override fun isSubclassOf(klass: KtClassOrObject, superClassId: ClassId): Boolean { - assertIsValid() - var result = false - forEachSuperClass(klass.getOrBuildFirSafe(firResolveState) ?: return false) { type -> - result = result || type.firClassLike(firResolveState.firIdeSourcesSession)?.symbol?.classId == superClassId - } - return result - } - - override fun getDiagnosticsForElement(element: KtElement): Collection = withValidityAssertion { - LowLevelFirApiFacade.getDiagnosticsFor(element, firResolveState) - } - - override fun resolveCall(call: KtBinaryExpression): CallInfo? = withValidityAssertion { - val firCall = call.getOrBuildFirSafe(firResolveState) ?: return null - resolveCall(firCall, call) - } - override fun createContextDependentCopy(): KtAnalysisSession { check(!isContextSession) { "Cannot create context-dependent copy of KtAnalysis session from a context dependent one" } val contextResolveState = LowLevelFirApiFacade.getResolveStateForCompletion(element, firResolveState) @@ -136,68 +57,7 @@ private constructor( ) } - override fun resolveCall(call: KtCallExpression): CallInfo? = withValidityAssertion { - val firCall = when (val fir = call.getOrBuildFir(firResolveState)) { - is FirFunctionCall -> fir - is FirSafeCallExpression -> fir.regularQualifiedAccess as? FirFunctionCall - else -> null - } ?: return null - return resolveCall(firCall, call) - } - - private fun resolveCall(firCall: FirFunctionCall, callExpression: KtExpression): CallInfo? { - val session = firResolveState.firIdeSourcesSession - val resolvedFunctionSymbol = firCall.calleeReference.toTargetSymbol(session, firSymbolBuilder) - val resolvedCalleeSymbol = (firCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol - return when { - resolvedCalleeSymbol is FirConstructorSymbol -> { - val fir = resolvedCalleeSymbol.fir - FunctionCallInfo(firSymbolBuilder.buildConstructorSymbol(fir)) - } - firCall.dispatchReceiver is FirQualifiedAccessExpression && firCall.isImplicitFunctionCall() -> { - val target = with(FirReferenceResolveHelper) { - val calleeReference = (firCall.dispatchReceiver as FirQualifiedAccessExpression).calleeReference - calleeReference.toTargetSymbol(session, firSymbolBuilder) - } - when (target) { - null -> null - is KtVariableLikeSymbol -> { - val functionSymbol = - (firCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol - when (functionSymbol?.callableId) { - null -> null - in kotlinFunctionInvokeCallableIds -> VariableAsFunctionCallInfo(target, functionSymbol.fir.isSuspend) - else -> (resolvedFunctionSymbol as? KtFunctionSymbol) - ?.let { VariableAsFunctionLikeCallInfo(target, it) } - } - } - else -> resolvedFunctionSymbol?.asSimpleFunctionCall() - } - } - else -> resolvedFunctionSymbol?.asSimpleFunctionCall() - } - } - - private fun KtSymbol.asSimpleFunctionCall() = - (this as? KtFunctionSymbol)?.let(::FunctionCallInfo) - - private fun forEachSuperClass(firClass: FirClass<*>, action: (FirResolvedTypeRef) -> Unit) { - firClass.superTypeRefs.forEach { superType -> - (superType as? FirResolvedTypeRef)?.let(action) - (superType.firClassLike(firClass.session) as? FirClass<*>?)?.let { forEachSuperClass(it, action) } - } - } - - private fun ConeKotlinType.asTypeInfo() = firSymbolBuilder.buildKtType(this) - companion object { - private val kotlinFunctionInvokeCallableIds = (0..23).flatMapTo(hashSetOf()) { arity -> - listOf( - CallableId(KotlinBuiltIns.getFunctionClassId(arity), Name.identifier("invoke")), - CallableId(KotlinBuiltIns.getSuspendFunctionClassId(arity), Name.identifier("invoke")) - ) - } - @Deprecated("Please use org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSessionProviderKt.analyze") internal fun createForElement(element: KtElement): KtFirAnalysisSession { val firResolveState = LowLevelFirApiFacade.getResolveStateFor(element) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirAnalysisSessionComponent.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirAnalysisSessionComponent.kt new file mode 100644 index 00000000000..8087abcbbdc --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirAnalysisSessionComponent.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2020 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.types.ConeKotlinType +import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession + +internal interface KtFirAnalysisSessionComponent { + val analysisSession: KtFirAnalysisSession + + val firSymbolBuilder get() = analysisSession.firSymbolBuilder + val firResolveState get() = analysisSession.firResolveState + fun ConeKotlinType.asKtType() = analysisSession.firSymbolBuilder.buildKtType(this) +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt new file mode 100644 index 00000000000..5f936f1c9ba --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt @@ -0,0 +1,91 @@ +/* + * Copyright 2010-2020 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.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.fir.declarations.isSuspend +import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.symbols.CallableId +import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.idea.fir.getOrBuildFir +import org.jetbrains.kotlin.idea.fir.getOrBuildFirSafe +import org.jetbrains.kotlin.idea.fir.isImplicitFunctionCall +import org.jetbrains.kotlin.idea.frontend.api.* +import org.jetbrains.kotlin.idea.frontend.api.components.KtCallResolver +import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableLikeSymbol +import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper +import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper.toTargetSymbol +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtCallExpression +import org.jetbrains.kotlin.psi.KtExpression + +internal class KtFirCallResolver(override val analysisSession: KtFirAnalysisSession) : KtCallResolver(), KtFirAnalysisSessionComponent { + + override fun resolveCall(call: KtBinaryExpression): CallInfo? = withValidityAssertion { + val firCall = call.getOrBuildFirSafe(firResolveState) ?: return null + resolveCall(firCall, call) + } + + override fun resolveCall(call: KtCallExpression): CallInfo? = withValidityAssertion { + val firCall = when (val fir = call.getOrBuildFir(firResolveState)) { + is FirFunctionCall -> fir + is FirSafeCallExpression -> fir.regularQualifiedAccess as? FirFunctionCall + else -> null + } ?: return null + return resolveCall(firCall, call) + } + + private fun resolveCall(firCall: FirFunctionCall, callExpression: KtExpression): CallInfo? { + val session = firResolveState.firIdeSourcesSession + val resolvedFunctionSymbol = firCall.calleeReference.toTargetSymbol(session, firSymbolBuilder) + val resolvedCalleeSymbol = (firCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol + return when { + resolvedCalleeSymbol is FirConstructorSymbol -> { + val fir = resolvedCalleeSymbol.fir + FunctionCallInfo(firSymbolBuilder.buildConstructorSymbol(fir)) + } + firCall.dispatchReceiver is FirQualifiedAccessExpression && firCall.isImplicitFunctionCall() -> { + val target = with(FirReferenceResolveHelper) { + val calleeReference = (firCall.dispatchReceiver as FirQualifiedAccessExpression).calleeReference + calleeReference.toTargetSymbol(session, firSymbolBuilder) + } + when (target) { + null -> null + is KtVariableLikeSymbol -> { + val functionSymbol = + (firCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol + when (functionSymbol?.callableId) { + null -> null + in kotlinFunctionInvokeCallableIds -> VariableAsFunctionCallInfo(target, functionSymbol.fir.isSuspend) + else -> (resolvedFunctionSymbol as? KtFunctionSymbol) + ?.let { VariableAsFunctionLikeCallInfo(target, it) } + } + } + else -> resolvedFunctionSymbol?.asSimpleFunctionCall() + } + } + else -> resolvedFunctionSymbol?.asSimpleFunctionCall() + } + } + + private fun KtSymbol.asSimpleFunctionCall() = + (this as? KtFunctionSymbol)?.let(::FunctionCallInfo) + + companion object { + private val kotlinFunctionInvokeCallableIds = (0..23).flatMapTo(hashSetOf()) { arity -> + listOf( + CallableId(KotlinBuiltIns.getFunctionClassId(arity), Name.identifier("invoke")), + CallableId(KotlinBuiltIns.getSuspendFunctionClassId(arity), Name.identifier("invoke")) + ) + } + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirDiagnosticProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirDiagnosticProvider.kt new file mode 100644 index 00000000000..aff18cbe408 --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirDiagnosticProvider.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2020 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.diagnostics.Diagnostic +import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast +import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression +import org.jetbrains.kotlin.idea.fir.getOrBuildFirSafe +import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade +import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartCast +import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartcastKind +import org.jetbrains.kotlin.idea.frontend.api.components.KtDiagnosticProvider +import org.jetbrains.kotlin.idea.frontend.api.components.KtSmartCastProvider +import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtExpression + +internal class KtFirDiagnosticProvider( + override val analysisSession: KtFirAnalysisSession +) : KtDiagnosticProvider(), KtFirAnalysisSessionComponent { + override fun getDiagnosticsForElement(element: KtElement): Collection = withValidityAssertion { + LowLevelFirApiFacade.getDiagnosticsFor(element, firResolveState) + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirScopeProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt similarity index 88% rename from idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirScopeProvider.kt rename to idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt index 713b0b530be..8c8ea70c676 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirScopeProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt @@ -3,10 +3,9 @@ * 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.scopes +package org.jetbrains.kotlin.idea.frontend.api.fir.components import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.resolve.ScopeSession @@ -21,10 +20,20 @@ import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.idea.fir.getOrBuildFirOfType import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner +import org.jetbrains.kotlin.idea.frontend.api.components.KtScopeContext +import org.jetbrains.kotlin.idea.frontend.api.components.KtScopeProvider import org.jetbrains.kotlin.idea.frontend.api.fir.FirScopeRegistry import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder +import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.* +import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.KtFirDeclaredMemberScope +import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.KtFirDelegatingScope +import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.KtFirMemberScope +import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.KtFirNonStarImportingScope +import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.KtFirPackageScope +import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.KtFirStarImportingScope import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymbol import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef @@ -41,7 +50,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import java.util.* internal class KtFirScopeProvider( - override val token: ValidityToken, + override val analysisSession: KtAnalysisSession, private val builder: KtSymbolByFirBuilder, private val project: Project, firResolveState: FirModuleResolveState, @@ -89,7 +98,7 @@ internal class KtFirScopeProvider( KtFirCompositeScope(subScopes, token) } - override fun getScopeForType(type: KtType): KtScope? { + override fun getTypeScope(type: KtType): KtScope? { check(type is KtFirType) { "KtFirScopeProvider can only work with KtFirType, but ${type::class} was provided" } val firTypeScope = type.coneType.scope(firResolveState.firIdeSourcesSession, ScopeSession()) ?: return null diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt new file mode 100644 index 00000000000..60bc92430a2 --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2020 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.expressions.FirExpressionWithSmartcast +import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression +import org.jetbrains.kotlin.idea.fir.getOrBuildFirSafe +import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartCast +import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartcastKind +import org.jetbrains.kotlin.idea.frontend.api.components.KtSmartCastProvider +import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion +import org.jetbrains.kotlin.psi.KtExpression + +internal class KtFirSmartcastProvider( + override val analysisSession: KtFirAnalysisSession +) : KtSmartCastProvider(), KtFirAnalysisSessionComponent { + override fun getSmartCastedToTypes(expression: KtExpression): Collection = withValidityAssertion { + // TODO filter out not used smartcasts + expression.getOrBuildFirSafe(analysisSession.firResolveState) + ?.typesFromSmartCast + ?.map { it.asKtType() } + ?: emptyList() + } + + @OptIn(ExperimentalStdlibApi::class) + override fun getImplicitReceiverSmartCasts(expression: KtExpression): Collection = withValidityAssertion { + // TODO filter out not used smartcasts + val qualifiedExpression = + expression.getOrBuildFirSafe(analysisSession.firResolveState) ?: return emptyList() + if (qualifiedExpression.dispatchReceiver !is FirExpressionWithSmartcast + && qualifiedExpression.extensionReceiver !is FirExpressionWithSmartcast + ) return emptyList() + buildList { + (qualifiedExpression.dispatchReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> + ImplicitReceiverSmartCast( + smartCasted.typesFromSmartCast.map { it.asKtType() }, + ImplicitReceiverSmartcastKind.DISPATCH + ) + }?.let(::add) + (qualifiedExpression.extensionReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> + ImplicitReceiverSmartCast( + smartCasted.typesFromSmartCast.map { it.asKtType() }, + ImplicitReceiverSmartcastKind.EXTENSION + ) + }?.let(::add) + } + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbolContainingDeclarationProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt similarity index 68% rename from idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbolContainingDeclarationProvider.kt rename to idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt index 92eed7bfa37..56efa067213 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbolContainingDeclarationProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt @@ -3,18 +3,19 @@ * 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 +package org.jetbrains.kotlin.idea.frontend.api.fir.components import com.intellij.psi.util.parentOfType -import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession +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.symbols.* import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind import org.jetbrains.kotlin.psi.KtDeclaration -class KtFirSymbolContainingDeclarationProvider( - private val analysisSession: KtAnalysisSession -) : KtSymbolContainingDeclarationProvider() { +internal class KtFirSymbolContainingDeclarationProvider( + override val analysisSession: KtFirAnalysisSession +) : KtSymbolContainingDeclarationProvider(), KtFirAnalysisSessionComponent { override fun getContainingDeclaration(symbol: KtSymbolWithKind): KtSymbolWithKind? { if (symbol is KtPackageSymbol) return null if (symbol.symbolKind == KtSymbolKind.TOP_LEVEL) return null @@ -26,24 +27,25 @@ class KtFirSymbolContainingDeclarationProvider( } } - private fun getContainingDeclarationForKotlinInSourceSymbol(symbol: KtSymbolWithKind): KtSymbolWithKind { + private fun getContainingDeclarationForKotlinInSourceSymbol(symbol: KtSymbolWithKind): KtSymbolWithKind = with(analysisSession) { require(symbol.origin == KtSymbolOrigin.SOURCE) val psi = symbol.psi ?: error("PSI should present for declaration built by Kotlin code") check(psi is KtDeclaration) { "PSI of kotlin declaration should be KtDeclaration" } val containingDeclaration = psi.parentOfType() ?: error("Containing declaration should present for non-toplevel declaration") return with(analysisSession) { - val containingSymbol = symbolProvider.getSymbol(containingDeclaration) + val containingSymbol = containingDeclaration.getSymbol() check(containingSymbol is KtSymbolWithKind) containingSymbol } } - private fun getContainingDeclarationForLibrarySymbol(symbol: KtSymbolWithKind): KtSymbolWithKind { + private fun getContainingDeclarationForLibrarySymbol(symbol: KtSymbolWithKind): KtSymbolWithKind = with(analysisSession) { require(symbol.origin == KtSymbolOrigin.LIBRARY) check(symbol.symbolKind == KtSymbolKind.MEMBER) - val containingClassId = symbol.containingNonLocalClassIdIfMember ?: error("containingClassId should not be null for member declaration") - val containingClass = analysisSession.symbolProvider.getClassOrObjectSymbolByClassId(containingClassId) + val containingClassId = + symbol.containingNonLocalClassIdIfMember ?: error("containingClassId should not be null for member declaration") + val containingClass = containingClassId.getCorrespondingToplevelClassOrObjectSymbol() return containingClass ?: error("Class with id $containingClassId should exists") } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt new file mode 100644 index 00000000000..3259e413e75 --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2020 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.declarations.FirCallableDeclaration +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast +import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression +import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.idea.fir.getOrBuildFirOfType +import org.jetbrains.kotlin.idea.fir.getOrBuildFirSafe +import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartCast +import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartcastKind +import org.jetbrains.kotlin.idea.frontend.api.components.KtSmartCastProvider +import org.jetbrains.kotlin.idea.frontend.api.components.KtTypeProvider +import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtExpression + +internal class KtFirTypeProvider( + override val analysisSession: KtFirAnalysisSession +) : KtTypeProvider(), KtFirAnalysisSessionComponent { + override fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType = withValidityAssertion { + val firDeclaration = declaration.getOrBuildFirOfType>(firResolveState) + firDeclaration.returnTypeRef.coneType.asKtType() + } + + override fun getKtExpressionType(expression: KtExpression): KtType = withValidityAssertion { + expression.getOrBuildFirOfType(firResolveState).typeRef.coneType.asKtType() + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirSimpleNameReference.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirSimpleNameReference.kt index 7fe68ee5296..4d60ef2b400 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirSimpleNameReference.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirSimpleNameReference.kt @@ -16,9 +16,9 @@ import org.jetbrains.kotlin.psi.KtSimpleNameExpression internal class KtFirSimpleNameReference( expression: KtSimpleNameExpression ) : KtSimpleNameReference(expression), KtFirReference { - override fun resolveToSymbols(analysisSession: KtAnalysisSession): Collection { - check(analysisSession is KtFirAnalysisSession) - return FirReferenceResolveHelper.resolveSimpleNameReference(this, analysisSession) + override fun KtAnalysisSession.resolveToSymbols(): Collection { + check(this is KtFirAnalysisSession) + return FirReferenceResolveHelper.resolveSimpleNameReference(this@KtFirSimpleNameReference, this) } override fun doCanBeReferenceTo(candidateTarget: PsiElement): Boolean { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirArrayAccessReference.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirArrayAccessReference.kt index 45b8eaa844c..c4ed0e1f975 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirArrayAccessReference.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirArrayAccessReference.kt @@ -19,10 +19,10 @@ import org.jetbrains.kotlin.psi.KtExpression class KtFirArrayAccessReference( expression: KtArrayAccessExpression ) : KtArrayAccessReference(expression), KtFirReference { - override fun resolveToSymbols(analysisSession: KtAnalysisSession): Collection { - check(analysisSession is KtFirAnalysisSession) - val fir = element.getOrBuildFirSafe(analysisSession.firResolveState) ?: return emptyList() - return listOfNotNull(fir.getCalleeSymbol()?.fir?.buildSymbol(analysisSession.firSymbolBuilder)) + override fun KtAnalysisSession.resolveToSymbols(): Collection { + check(this is KtFirAnalysisSession) + val fir = element.getOrBuildFirSafe(firResolveState) ?: return emptyList() + return listOfNotNull(fir.getCalleeSymbol()?.fir?.buildSymbol(firSymbolBuilder)) } override fun moveFunctionLiteralOutsideParentheses(callExpression: KtCallExpression) { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirConstructorDelegationReference.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirConstructorDelegationReference.kt index b34a619e838..f682532f3bc 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirConstructorDelegationReference.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirConstructorDelegationReference.kt @@ -17,9 +17,9 @@ class KtFirConstructorDelegationReference( expression: KtConstructorDelegationReferenceExpression ) : KtConstructorDelegationReference(expression), KtFirReference { - override fun resolveToSymbols(analysisSession: KtAnalysisSession): Collection { - check(analysisSession is KtFirAnalysisSession) - val fir = expression.getOrBuildFirSafe(analysisSession.firResolveState) ?: return emptyList() - return listOfNotNull(fir.calleeReference.getResolvedKtSymbolOfNameReference(analysisSession.firSymbolBuilder)) + override fun KtAnalysisSession.resolveToSymbols(): Collection { + check(this is KtFirAnalysisSession) + val fir = expression.getOrBuildFirSafe(firResolveState) ?: return emptyList() + return listOfNotNull(fir.calleeReference.getResolvedKtSymbolOfNameReference(firSymbolBuilder)) } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirDestructuringDeclarationReference.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirDestructuringDeclarationReference.kt index 13fff9e8624..b405ffe69ad 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirDestructuringDeclarationReference.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirDestructuringDeclarationReference.kt @@ -20,10 +20,10 @@ class KtFirDestructuringDeclarationReference( ) : KtDestructuringDeclarationReference(element), KtFirReference { override fun canRename(): Boolean = false //todo - override fun resolveToSymbols(analysisSession: KtAnalysisSession): Collection { - check(analysisSession is KtFirAnalysisSession) - val fir = expression.getOrBuildFirSafe(analysisSession.firResolveState) ?: return emptyList() + override fun KtAnalysisSession.resolveToSymbols(): Collection { + check(this is KtFirAnalysisSession) + val fir = expression.getOrBuildFirSafe(firResolveState) ?: return emptyList() val componentFunctionSymbol = (fir.initializer as? FirComponentCall)?.getCalleeSymbol() ?: return emptyList() - return listOfNotNull(componentFunctionSymbol.fir.buildSymbol(analysisSession.firSymbolBuilder)) + return listOfNotNull(componentFunctionSymbol.fir.buildSymbol(firSymbolBuilder)) } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirForLoopInReference.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirForLoopInReference.kt index ee123c3179c..cebb507e898 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirForLoopInReference.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirForLoopInReference.kt @@ -18,20 +18,20 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol import org.jetbrains.kotlin.psi.KtForExpression open class KtFirForLoopInReference(expression: KtForExpression) : KtForLoopInReference(expression), KtFirReference { - override fun resolveToSymbols(analysisSession: KtAnalysisSession): Collection { - check(analysisSession is KtFirAnalysisSession) - val firLoop = expression.getOrBuildFirSafe(analysisSession.firResolveState) ?: return emptyList() + override fun KtAnalysisSession.resolveToSymbols(): Collection { + check(this is KtFirAnalysisSession) + val firLoop = expression.getOrBuildFirSafe(firResolveState) ?: return emptyList() val condition = firLoop.condition as? FirFunctionCall - val iterator = run { + val iterator = this@KtFirForLoopInReference.run { val callee = (condition?.explicitReceiver as? FirQualifiedAccessExpression)?.calleeReference (callee?.getResolvedSymbolOfNameReference()?.fir as? FirProperty)?.getInitializerFunctionCall() } val hasNext = condition?.calleeReference?.getResolvedSymbolOfNameReference() val next = (firLoop.block.statements.firstOrNull() as? FirProperty?)?.getInitializerFunctionCall() return listOfNotNull( - iterator?.fir?.buildSymbol(analysisSession.firSymbolBuilder), - hasNext?.fir?.buildSymbol(analysisSession.firSymbolBuilder), - next?.fir?.buildSymbol(analysisSession.firSymbolBuilder), + iterator?.fir?.buildSymbol(firSymbolBuilder), + hasNext?.fir?.buildSymbol(firSymbolBuilder), + next?.fir?.buildSymbol(firSymbolBuilder), ) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirInvokeFunctionReference.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirInvokeFunctionReference.kt index a1541a91abc..721f105c045 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirInvokeFunctionReference.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirInvokeFunctionReference.kt @@ -16,8 +16,8 @@ class KtFirInvokeFunctionReference(expression: KtCallExpression) : KtInvokeFunct TODO("Not yet implemented") } - override fun resolveToSymbols(analysisSession: KtAnalysisSession): Collection { - val call = analysisSession.resolveCall(expression) ?: return emptyList() + override fun KtAnalysisSession.resolveToSymbols(): Collection { + val call = expression.resolveCall() ?: return emptyList() if (call is VariableAsFunctionLikeCallInfo) { return listOf(call.invokeFunction) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirPropertyDelegationMethodsReference.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirPropertyDelegationMethodsReference.kt index 3efd51c34f0..c0ff9269997 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirPropertyDelegationMethodsReference.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirPropertyDelegationMethodsReference.kt @@ -21,15 +21,15 @@ import org.jetbrains.kotlin.psi.KtPropertyDelegate class KtFirPropertyDelegationMethodsReference( element: KtPropertyDelegate ) : KtPropertyDelegationMethodsReference(element), KtFirReference { - override fun resolveToSymbols(analysisSession: KtAnalysisSession): Collection { - check(analysisSession is KtFirAnalysisSession) - val property = (expression.parent as? KtElement)?.getOrBuildFirSafe(analysisSession.firResolveState) ?: return emptyList() + override fun KtAnalysisSession.resolveToSymbols(): Collection { + check(this is KtFirAnalysisSession) + val property = (expression.parent as? KtElement)?.getOrBuildFirSafe(firResolveState) ?: return emptyList() if (property.delegate == null) return emptyList() val getValueSymbol = (property.getter?.singleStatementOfType()?.result as? FirFunctionCall)?.getCalleeSymbol() val setValueSymbol = property.setter?.singleStatementOfType()?.getCalleeSymbol() return listOfNotNull( - getValueSymbol?.fir?.buildSymbol(analysisSession.firSymbolBuilder), - setValueSymbol?.fir?.buildSymbol(analysisSession.firSymbolBuilder) + getValueSymbol?.fir?.buildSymbol(firSymbolBuilder), + setValueSymbol?.fir?.buildSymbol(firSymbolBuilder) ) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirReference.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirReference.kt index 49477cba714..33ae2dd216c 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirReference.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirReference.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol interface KtFirReference : KtReference, KtSymbolBasedReference { fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection = - resolveToSymbols(analysisSession).mapNotNull(KtSymbol::psi) + analysisSession.resolveToSymbols().mapNotNull(KtSymbol::psi) override val resolver get() = KtFirReferenceResolver } \ No newline at end of file diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/AbstractSymbolByFqNameTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/AbstractSymbolByFqNameTest.kt index 9a761b80fa8..f86a3e0ae1c 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/AbstractSymbolByFqNameTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/AbstractSymbolByFqNameTest.kt @@ -23,7 +23,7 @@ abstract class AbstractSymbolByFqNameTest : KotlinLightCodeInsightFixtureTestCas val renderedSymbols = executeOnPooledThreadInReadAction { analyze(fakeKtFile) { - val symbols = createSymbols(symbolData, this) + val symbols = createSymbols(symbolData) symbols.map { DebugSymbolRenderer.render(it) } } } @@ -32,7 +32,7 @@ abstract class AbstractSymbolByFqNameTest : KotlinLightCodeInsightFixtureTestCas KotlinTestUtils.assertEqualsToFile(File(path), actual) } - protected abstract fun createSymbols(symbolData: SymbolData, analysisSession: KtAnalysisSession): List + protected abstract fun KtAnalysisSession.createSymbols(symbolData: SymbolData): List override fun getDefaultProjectDescriptor(): KotlinLightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/SymbolByFqName.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/SymbolByFqName.kt index 95fbf3e52e2..fe87d70ccfb 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/SymbolByFqName.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/SymbolByFqName.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.test.InTextDirectivesUtils import java.io.File object SymbolByFqName { @@ -36,25 +35,25 @@ object SymbolByFqName { } sealed class SymbolData { - abstract fun toSymbols(analysisSession: KtAnalysisSession): List + abstract fun KtAnalysisSession.toSymbols(): List data class ClassData(val classId: ClassId) : SymbolData() { - override fun toSymbols(analysisSession: KtAnalysisSession): List { - val symbol = analysisSession.symbolProvider.getClassOrObjectSymbolByClassId(classId) ?: error("Class $classId is not found") + override fun KtAnalysisSession.toSymbols(): List { + val symbol = classId.getCorrespondingToplevelClassOrObjectSymbol() ?: error("Class $classId is not found") return listOf(symbol) } } data class CallableData(val callableId: CallableId) : SymbolData() { - override fun toSymbols(analysisSession: KtAnalysisSession): List { + override fun KtAnalysisSession.toSymbols(): List { val classId = callableId.classId val symbols = if (classId == null) { - analysisSession.symbolProvider.getTopLevelCallableSymbols(callableId.packageName, callableId.callableName).toList() + callableId.packageName.getContainingCallableSymbolsWithName(callableId.callableName).toList() } else { val classSymbol = - analysisSession.symbolProvider.getClassOrObjectSymbolByClassId(classId) + classId.getCorrespondingToplevelClassOrObjectSymbol() ?: error("Class $classId is not found") - analysisSession.scopeProvider.getDeclaredMemberScope(classSymbol).getCallableSymbols() + classSymbol.getDeclaredMemberScope().getCallableSymbols() .filter { (it as? KtNamedSymbol)?.name == callableId.callableName } .toList() } diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt index e8ffcd50fd1..f1cc848b162 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt @@ -43,8 +43,8 @@ abstract class AbstractResolveCallTest : @Suppress("DEPRECATION") KotlinLightCod val callInfos = analyze(file as KtFile) { elements.map { element -> when (element) { - is KtCallExpression -> resolveCall(element) - is KtBinaryExpression -> resolveCall(element) + is KtCallExpression -> element.resolveCall() + is KtBinaryExpression -> element.resolveCall() else -> error("Selected should be either KtCallExpression or KtBinaryExpression but was $element") } } diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/scopes/AbstractMemberScopeTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/scopes/AbstractMemberScopeTest.kt index 506208b8e7e..8de8690fe0b 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/scopes/AbstractMemberScopeTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/scopes/AbstractMemberScopeTest.kt @@ -12,9 +12,9 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol abstract class AbstractMemberScopeByFqNameTest : AbstractSymbolsByFqNameBuildingTest() { - override fun createSymbols(symbolData: SymbolData, analysisSession: KtAnalysisSession): List { - val symbols = symbolData.toSymbols(analysisSession) + override fun KtAnalysisSession.createSymbols(symbolData: SymbolData): List { + val symbols = with(symbolData) { toSymbols() } val classSymbol = symbols.singleOrNull() as? KtClassOrObjectSymbol ?: error("Should be a single class symbol, but $symbols found") - return analysisSession.scopeProvider.getMemberScope(classSymbol).getAllSymbols().toList() + return classSymbol.getMemberScope().getAllSymbols().toList() } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolFromLibraryPointerRestoreTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolFromLibraryPointerRestoreTest.kt index b51161ec0e7..e37308593af 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolFromLibraryPointerRestoreTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolFromLibraryPointerRestoreTest.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols -import com.intellij.testFramework.LightProjectDescriptor import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.SymbolByFqName import org.jetbrains.kotlin.psi.KtFile @@ -13,6 +12,6 @@ import org.jetbrains.kotlin.psi.KtFile abstract class AbstractSymbolFromLibraryPointerRestoreTest : AbstractSymbolPointerRestoreTest() { override fun KtAnalysisSession.collectSymbols(filePath: String, ktFile: KtFile): List { val symbolData = SymbolByFqName.getSymbolDataFromFile(filePath) - return symbolData.toSymbols(this) + return with(symbolData) { toSymbols() } } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolFromSourcePointerRestoreTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolFromSourcePointerRestoreTest.kt index ec94ab6d1a6..c787524b279 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolFromSourcePointerRestoreTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolFromSourcePointerRestoreTest.kt @@ -13,6 +13,6 @@ import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType abstract class AbstractSymbolFromSourcePointerRestoreTest : AbstractSymbolPointerRestoreTest() { override fun KtAnalysisSession.collectSymbols(filePath: String, ktFile: KtFile): List = ktFile.collectDescendantsOfType().map { declaration -> - symbolProvider.getSymbol(declaration) + declaration.getSymbol() } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolPointerRestoreTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolPointerRestoreTest.kt index 49828e487ef..be9b931d685 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolPointerRestoreTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolPointerRestoreTest.kt @@ -64,7 +64,7 @@ abstract class AbstractSymbolPointerRestoreTest : KotlinLightCodeInsightFixtureT executeOnPooledThreadInReadAction { analyze(ktFile) { val restored = pointersWithRendered.map { (pointer, expectedRender) -> - val restored = pointer.restoreSymbol(this) ?: error("Symbol $expectedRender was not not restored correctly") + val restored = pointer.restoreSymbol() ?: error("Symbol $expectedRender was not not restored correctly") DebugSymbolRenderer.render(restored) } val actualRestored = SymbolByFqName.textWithRenderedSymbolData( diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByFqNameBuildingTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByFqNameBuildingTest.kt index b70a3e13323..cfca053bb9d 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByFqNameBuildingTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByFqNameBuildingTest.kt @@ -10,6 +10,6 @@ import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.SymbolData abstract class AbstractSymbolsByFqNameBuildingTest : AbstractSymbolByFqNameTest() { - override fun createSymbols(symbolData: SymbolData, analysisSession: KtAnalysisSession): List = - symbolData.toSymbols(analysisSession) + override fun KtAnalysisSession.createSymbols(symbolData: SymbolData): List = + with(symbolData) { toSymbols() } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByPsiBuildingTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByPsiBuildingTest.kt index 01fd0bac070..717e0f46ead 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByPsiBuildingTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByPsiBuildingTest.kt @@ -27,7 +27,7 @@ abstract class AbstractSymbolsByPsiBuildingTest : KotlinLightCodeInsightFixtureT val renderedSymbols = executeOnPooledThreadInReadAction { analyze(ktFile) { val declarationSymbols = ktFile.collectDescendantsOfType().map { declaration -> - symbolProvider.getSymbol(declaration) + declaration.getSymbol() } declarationSymbols.map(DebugSymbolRenderer::render) } diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/types/KtTypeRendererTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/types/KtTypeRendererTest.kt index 89ef0b39459..093779bc65f 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/types/KtTypeRendererTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/types/KtTypeRendererTest.kt @@ -30,8 +30,8 @@ class KtTypeRendererTest : KotlinLightCodeInsightFixtureTestCase() { val property = fakeKtFile.declarations.single() as KtFunction val renderedType = executeOnPooledThreadInReadAction { analyze(fakeKtFile) { - val ktType = getReturnTypeForKtDeclaration(property) - KtTypeRenderer.render(ktType, rendererOptions) + val ktType = property.getReturnKtType() + ktType.render(rendererOptions) } } assertEquals(expected, renderedType) @@ -46,8 +46,8 @@ class KtTypeRendererTest : KotlinLightCodeInsightFixtureTestCase() { val property = fakeKtFile.declarations.single() as KtProperty val renderedType = executeOnPooledThreadInReadAction { analyze(fakeKtFile) { - val ktType = getReturnTypeForKtDeclaration(property) - KtTypeRenderer.render(ktType, rendererOptions) + val ktType = property.getReturnKtType() + ktType.render(rendererOptions) } } assertEquals(expected, renderedType)