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 688f75077a8..52284ebdf37 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 @@ -36,7 +36,6 @@ import org.jetbrains.kotlin.psi.* */ abstract class KtAnalysisSession(final override val token: ValidityToken) : ValidityTokenOwner { 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 @@ -45,7 +44,11 @@ abstract class KtAnalysisSession(final override val token: ValidityToken) : Vali protected abstract val completionCandidateChecker: KtCompletionCandidateChecker protected abstract val symbolDeclarationOverridesProvider: KtSymbolDeclarationOverridesProvider @Suppress("LeakingThis") + protected open val typeRenderer: KtTypeRenderer = KtDefaultTypeRenderer(this, token) + protected abstract val expressionTypeProvider: KtExpressionTypeProvider + protected abstract val typeProvider: KtTypeProvider + protected abstract val subtypingComponent: KtSubtypingComponent protected abstract val expressionHandlingComponent: KtExpressionHandlingComponent /// TODO: get rid of @@ -59,18 +62,20 @@ abstract class KtAnalysisSession(final override val token: ValidityToken) : Vali fun KtExpression.getImplicitReceiverSmartCasts(): Collection = smartCastProvider.getImplicitReceiverSmartCasts(this) - fun KtExpression.getKtType(): KtType = typeProvider.getKtExpressionType(this) + fun KtExpression.getKtType(): KtType = expressionTypeProvider.getKtExpressionType(this) - fun KtDeclaration.getReturnKtType(): KtType = typeProvider.getReturnTypeForKtDeclaration(this) + fun KtDeclaration.getReturnKtType(): KtType = expressionTypeProvider.getReturnTypeForKtDeclaration(this) - infix fun KtType.isEqualTo(other: KtType): Boolean = typeProvider.isEqualTo(this, other) + infix fun KtType.isEqualTo(other: KtType): Boolean = subtypingComponent.isEqualTo(this, other) - infix fun KtType.isSubTypeOf(superType: KtType): Boolean = typeProvider.isSubTypeOf(this, superType) + infix fun KtType.isSubTypeOf(superType: KtType): Boolean = subtypingComponent.isSubTypeOf(this, superType) - fun PsiElement.getExpectedType(): KtType? = typeProvider.getExpectedType(this) + fun PsiElement.getExpectedType(): KtType? = expressionTypeProvider.getExpectedType(this) fun KtType.isBuiltInFunctionalType(): Boolean = typeProvider.isBuiltinFunctionalType(this) + val builtinTypes: KtBuiltinTypes get() = typeProvider.builtinTypes + fun KtElement.getDiagnostics(): Collection = diagnosticProvider.getDiagnosticsForElement(this) fun KtFile.collectDiagnosticsForFile(): Collection = diagnosticProvider.collectDiagnosticsForFile(this) diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtExpressionTypeProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtExpressionTypeProvider.kt new file mode 100644 index 00000000000..5a4de47792b --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtExpressionTypeProvider.kt @@ -0,0 +1,19 @@ +/* + * 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 com.intellij.psi.PsiElement +import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner +import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtExpression + +abstract class KtExpressionTypeProvider : KtAnalysisSessionComponent() { + abstract fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType + abstract fun getKtExpressionType(expression: KtExpression): KtType + + abstract fun getExpectedType(expression: PsiElement): KtType? +} diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSubtypingComponent.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSubtypingComponent.kt new file mode 100644 index 00000000000..58c0e33ef24 --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSubtypingComponent.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.idea.frontend.api.types.KtType + +abstract class KtSubtypingComponent : KtAnalysisSessionComponent() { + abstract fun isEqualTo(first: KtType, second: KtType): Boolean + abstract fun isSubTypeOf(subType: KtType, superType: KtType): Boolean +} \ No newline at end of file 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 index e30578fb31e..4d01d8f7bad 100644 --- 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 @@ -5,27 +5,17 @@ package org.jetbrains.kotlin.idea.frontend.api.components -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner 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 - - abstract fun isEqualTo(first: KtType, second: KtType): Boolean - abstract fun isSubTypeOf(subType: KtType, superType: KtType): Boolean - - //TODO get rid of + //TODO get rid of it abstract fun isBuiltinFunctionalType(type: KtType): Boolean - abstract fun getExpectedType(expression: PsiElement): KtType? - abstract val builtinTypes: KtBuiltinTypes } + @Suppress("PropertyName") abstract class KtBuiltinTypes : ValidityTokenOwner { abstract val INT: KtType 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 e06928dd18f..7b4403293f6 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 @@ -34,7 +34,7 @@ private constructor( } override val smartCastProvider: KtSmartCastProvider = KtFirSmartcastProvider(this, token) - override val typeProvider: KtTypeProvider = KtFirTypeProvider(this, token) + override val expressionTypeProvider: KtExpressionTypeProvider = KtFirExpressionTypeProvider(this, token) override val diagnosticProvider: KtDiagnosticProvider = KtFirDiagnosticProvider(this, token) override val containingDeclarationProvider = KtFirSymbolContainingDeclarationProvider(this, token) override val callResolver: KtCallResolver = KtFirCallResolver(this, token) @@ -46,6 +46,8 @@ private constructor( KtFirSymbolDeclarationOverridesProvider(this, token) override val expressionHandlingComponent: KtExpressionHandlingComponent = KtFirExpressionHandlingComponent(this, token) + override val typeProvider: KtTypeProvider = KtFirTypeProvider(this, token) + override val subtypingComponent: KtSubtypingComponent = KtFirSubtypingComponent(this, token) override fun createContextDependentCopy(): KtAnalysisSession { check(!isContextSession) { "Cannot create context-dependent copy of KtAnalysis session from a context dependent one" } 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 index 8087abcbbdc..4690e370358 100644 --- 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 @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession internal interface KtFirAnalysisSessionComponent { @@ -14,4 +15,10 @@ internal interface KtFirAnalysisSessionComponent { val firSymbolBuilder get() = analysisSession.firSymbolBuilder val firResolveState get() = analysisSession.firResolveState fun ConeKotlinType.asKtType() = analysisSession.firSymbolBuilder.buildKtType(this) + + fun createTypeCheckerContext() = ConeTypeCheckerContext( + isErrorTypeEqualsToAnything = true, + isStubTypeEqualsToAnything = true, + analysisSession.firResolveState.rootModuleSession //TODO use correct session here + ) } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirExpressionTypeProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirExpressionTypeProvider.kt new file mode 100644 index 00000000000..bd608b9f2d3 --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirExpressionTypeProvider.kt @@ -0,0 +1,107 @@ +/* + * 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 com.intellij.psi.PsiElement +import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirFunctionCall +import org.jetbrains.kotlin.fir.expressions.argumentMapping +import org.jetbrains.kotlin.fir.psi +import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType +import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext +import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirOfType +import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirSafe +import org.jetbrains.kotlin.idea.frontend.api.ValidityToken +import org.jetbrains.kotlin.idea.frontend.api.assertIsValid +import org.jetbrains.kotlin.idea.frontend.api.components.KtBuiltinTypes +import org.jetbrains.kotlin.idea.frontend.api.components.KtExpressionTypeProvider +import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType +import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.types.AbstractTypeCheckerContext + +internal class KtFirExpressionTypeProvider( + override val analysisSession: KtFirAnalysisSession, + override val token: ValidityToken, +) : KtExpressionTypeProvider(), 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() + } + + override fun getExpectedType(expression: PsiElement): KtType? = + getExpectedTypeByReturnExpression(expression) + ?: getExpressionTypeByIfOrBooleanCondition(expression) + ?: getExpectedTypeOfFunctionParameter(expression) + + private fun getExpectedTypeOfFunctionParameter(expression: PsiElement): KtType? { + val (ktCallExpression, ktArgument) = expression.getFunctionCallAsWithThisAsParameter() ?: return null + val firCall = ktCallExpression.getOrBuildFirSafe(firResolveState) ?: return null + val arguments = firCall.argumentMapping ?: return null + val firParameterForExpression = arguments.entries.firstOrNull { (arg, _) -> arg.psi == ktArgument }?.value ?: return null + return firParameterForExpression.returnTypeRef.coneType.asKtType() + } + + private fun PsiElement.getFunctionCallAsWithThisAsParameter(): KtCallWithArgument? { + val valueArgument = unwrapQualified { valueArg, expr -> valueArg.getArgumentExpression() == expr } ?: return null + val argumentsList = valueArgument.parent as? KtValueArgumentList ?: return null + val callExpression = argumentsList.parent as? KtCallExpression ?: return null + val argumentExpression = valueArgument.getArgumentExpression() ?: return null + return KtCallWithArgument(callExpression, argumentExpression) + } + + private fun getExpectedTypeByReturnExpression(expression: PsiElement): KtType? { + val returnParent = expression.getReturnExpressionWithThisType() ?: return null + val targetSymbol = with(analysisSession) { returnParent.getReturnTargetSymbol() } ?: return null + return targetSymbol.type + } + + private fun PsiElement.getReturnExpressionWithThisType(): KtReturnExpression? = + unwrapQualified { returnExpr, target -> returnExpr.returnedExpression == target } + + private fun getExpressionTypeByIfOrBooleanCondition(expression: PsiElement): KtType? = when { + expression.isWhileLoopCondition() || expression.isIfCondition() -> with(analysisSession) { builtinTypes.BOOLEAN } + else -> null + } + + private fun PsiElement.isWhileLoopCondition() = + unwrapQualified { whileExpr, cond -> whileExpr.condition == cond } != null + + private fun PsiElement.isIfCondition() = + unwrapQualified { ifExpr, cond -> ifExpr.condition == cond } != null +} + +private data class KtCallWithArgument(val call: KtCallExpression, val argument: KtExpression) + +private inline fun PsiElement.unwrapQualified(check: (R, PsiElement) -> Boolean): R? { + val parent = nonContainerParent + return when { + parent is R && check(parent, this) -> parent + parent is KtQualifiedExpression && parent.selectorExpression == this -> { + val grandParent = parent.nonContainerParent + when { + grandParent is R && check(grandParent, parent) -> grandParent + else -> null + } + } + else -> null + } +} + +private val PsiElement.nonContainerParent: PsiElement? + get() = when (val parent = parent) { + is KtContainerNode -> parent.parent + else -> parent + } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSubtyppingComponent.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSubtyppingComponent.kt new file mode 100644 index 00000000000..f3ea0ceb07f --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSubtyppingComponent.kt @@ -0,0 +1,43 @@ +/* + * 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.idea.frontend.api.ValidityToken +import org.jetbrains.kotlin.idea.frontend.api.assertIsValid +import org.jetbrains.kotlin.idea.frontend.api.components.KtSubtypingComponent +import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType +import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion +import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.types.AbstractTypeCheckerContext + +internal class KtFirSubtypingComponent( + override val analysisSession: KtFirAnalysisSession, + override val token: ValidityToken, +) : KtSubtypingComponent(), KtFirAnalysisSessionComponent { + override fun isEqualTo(first: KtType, second: KtType): Boolean = withValidityAssertion { + second.assertIsValid() + check(first is KtFirType) + check(second is KtFirType) + return AbstractTypeChecker.equalTypes( + createTypeCheckerContext() as AbstractTypeCheckerContext, + first.coneType, + second.coneType + ) + } + + override fun isSubTypeOf(subType: KtType, superType: KtType): Boolean = withValidityAssertion { + superType.assertIsValid() + check(subType is KtFirType) + check(superType is KtFirType) + return AbstractTypeChecker.isSubtypeOf( + createTypeCheckerContext() as AbstractTypeCheckerContext, + subType.coneType, + superType.coneType + ) + } +} 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 index 780100b9a61..9752bf206ea 100644 --- 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 @@ -5,110 +5,19 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components -import com.intellij.psi.PsiElement -import com.jetbrains.rd.util.firstOrNull -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.expressions.FirCall -import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.expressions.FirFunctionCall -import org.jetbrains.kotlin.fir.expressions.argumentMapping -import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType -import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext -import org.jetbrains.kotlin.fir.types.coneType -import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFir -import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirOfType -import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirSafe import org.jetbrains.kotlin.idea.frontend.api.ValidityToken -import org.jetbrains.kotlin.idea.frontend.api.assertIsValid import org.jetbrains.kotlin.idea.frontend.api.components.KtBuiltinTypes 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.fir.types.KtFirType import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.types.AbstractTypeChecker -import org.jetbrains.kotlin.types.AbstractTypeCheckerContext -import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult -import kotlin.reflect.KClass internal class KtFirTypeProvider( override val analysisSession: KtFirAnalysisSession, override val token: ValidityToken, ) : 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() - } - - override fun getExpectedType(expression: PsiElement): KtType? = - getExpectedTypeByReturnExpression(expression) - ?: getExpressionTypeByIfOrBooleanCondition(expression) - ?: getExpectedTypeOfFunctionParameter(expression) - - private fun getExpectedTypeOfFunctionParameter(expression: PsiElement): KtType? { - val (ktCallExpression, ktArgument) = expression.getFunctionCallAsWithThisAsParameter() ?: return null - val firCall = ktCallExpression.getOrBuildFirSafe(firResolveState) ?: return null - val arguments = firCall.argumentMapping ?: return null - val firParameterForExpression = arguments.entries.firstOrNull { (arg, _) -> arg.psi == ktArgument }?.value ?: return null - return firParameterForExpression.returnTypeRef.coneType.asKtType() - } - - private fun PsiElement.getFunctionCallAsWithThisAsParameter(): KtCallWithArgument? { - val valueArgument = unwrapQualified { valueArg, expr -> valueArg.getArgumentExpression() == expr } ?: return null - val argumentsList = valueArgument.parent as? KtValueArgumentList ?: return null - val callExpression = argumentsList.parent as? KtCallExpression ?: return null - val argumentExpression = valueArgument.getArgumentExpression() ?: return null - return KtCallWithArgument(callExpression, argumentExpression) - } - - private fun getExpectedTypeByReturnExpression(expression: PsiElement): KtType? { - val returnParent = expression.getReturnExpressionWithThisType() ?: return null - val targetSymbol = with(analysisSession) { returnParent.getReturnTargetSymbol() } ?: return null - return targetSymbol.type - } - - private fun PsiElement.getReturnExpressionWithThisType(): KtReturnExpression? = - unwrapQualified { returnExpr, target -> returnExpr.returnedExpression == target } - - private fun getExpressionTypeByIfOrBooleanCondition(expression: PsiElement): KtType? = when { - expression.isWhileLoopCondition() || expression.isIfCondition() -> builtinTypes.BOOLEAN - else -> null - } - - private fun PsiElement.isWhileLoopCondition() = - unwrapQualified { whileExpr, cond -> whileExpr.condition == cond } != null - - private fun PsiElement.isIfCondition() = - unwrapQualified { ifExpr, cond -> ifExpr.condition == cond } != null - - override fun isEqualTo(first: KtType, second: KtType): Boolean = withValidityAssertion { - second.assertIsValid() - check(first is KtFirType) - check(second is KtFirType) - return AbstractTypeChecker.equalTypes( - this.createTypeCheckerContext() as AbstractTypeCheckerContext, - first.coneType, - second.coneType - ) - } - - override fun isSubTypeOf(subType: KtType, superType: KtType): Boolean = withValidityAssertion { - superType.assertIsValid() - check(subType is KtFirType) - check(superType is KtFirType) - return AbstractTypeChecker.isSubtypeOf( - this.createTypeCheckerContext() as AbstractTypeCheckerContext, - subType.coneType, - superType.coneType - ) - } - override fun isBuiltinFunctionalType(type: KtType): Boolean = withValidityAssertion { check(type is KtFirType) type.coneType.isBuiltinFunctionalType(analysisSession.firResolveState.rootModuleSession) //TODO use correct session here @@ -116,33 +25,4 @@ internal class KtFirTypeProvider( override val builtinTypes: KtBuiltinTypes = KtFirBuiltInTypes(analysisSession.firResolveState.rootModuleSession.builtinTypes, analysisSession.firSymbolBuilder, token) - - private fun createTypeCheckerContext() = ConeTypeCheckerContext( - isErrorTypeEqualsToAnything = true, - isStubTypeEqualsToAnything = true, - analysisSession.firResolveState.rootModuleSession //TODO use correct session here - ) } - -private data class KtCallWithArgument(val call: KtCallExpression, val argument: KtExpression) - -private inline fun PsiElement.unwrapQualified(check: (R, PsiElement) -> Boolean): R? { - val parent = nonContainerParent - return when { - parent is R && check(parent, this) -> parent - parent is KtQualifiedExpression && parent.selectorExpression == this -> { - val grandParent = parent.nonContainerParent - when { - grandParent is R && check(grandParent, parent) -> grandParent - else -> null - } - } - else -> null - } -} - -private val PsiElement.nonContainerParent: PsiElement? - get() = when (val parent = parent) { - is KtContainerNode -> parent.parent - else -> parent - } \ No newline at end of file