[Analysis API] Handle missed cases in PsiElement.getExpectedType()
^KTIJ-24256
This commit is contained in:
committed by
teamcity
parent
7dd438cb9e
commit
3d0bca5ca1
+79
-33
@@ -7,11 +7,14 @@ package org.jetbrains.kotlin.analysis.api.descriptors.components
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtExpressionTypeProvider
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.components.base.Fe10KtAnalysisSessionComponent
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtType
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtErrorType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
@@ -28,6 +31,7 @@ import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.util.getType
|
||||
import org.jetbrains.kotlin.resolve.sam.SamConstructorDescriptor
|
||||
import org.jetbrains.kotlin.resolve.sam.getFunctionTypeForAbstractMethod
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.checker.intersectWrappedTypes
|
||||
import org.jetbrains.kotlin.types.error.ErrorTypeKind
|
||||
@@ -181,44 +185,83 @@ class KtFe10ExpressionTypeProvider(
|
||||
}
|
||||
}
|
||||
|
||||
if (parentExpression is KtCallableDeclaration) {
|
||||
if (expression is KtBlockExpression) {
|
||||
return null
|
||||
when (parentExpression) {
|
||||
is KtCallableDeclaration -> {
|
||||
if (expression is KtBlockExpression) {
|
||||
return null
|
||||
}
|
||||
|
||||
val bindingContext = analysisContext.analyze(parentExpression)
|
||||
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, parentExpression]
|
||||
if (descriptor is CallableDescriptor) {
|
||||
return descriptor.returnType?.toKtNonErrorType(analysisContext)
|
||||
}
|
||||
}
|
||||
|
||||
val bindingContext = analysisContext.analyze(parentExpression)
|
||||
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, parentExpression]
|
||||
if (descriptor is CallableDescriptor) {
|
||||
return descriptor.returnType?.toKtType(analysisContext)
|
||||
}
|
||||
} else if (parentExpression is KtBinaryExpressionWithTypeRHS && KtPsiUtil.isCast(parentExpression)) {
|
||||
val typeReference = parentExpression.right
|
||||
if (typeReference != null) {
|
||||
val bindingContext = analysisContext.analyze(typeReference)
|
||||
var kotlinType = bindingContext[BindingContext.TYPE, typeReference]
|
||||
if (kotlinType != null && KtPsiUtil.isSafeCast(parentExpression)) {
|
||||
kotlinType = kotlinType.makeNullable()
|
||||
is KtBinaryExpressionWithTypeRHS -> {
|
||||
val typeReference = parentExpression.right
|
||||
if (KtPsiUtil.isCast(parentExpression) && typeReference != null) {
|
||||
val bindingContext = analysisContext.analyze(typeReference)
|
||||
var kotlinType = bindingContext[BindingContext.TYPE, typeReference]
|
||||
if (kotlinType != null && KtPsiUtil.isSafeCast(parentExpression)) {
|
||||
kotlinType = kotlinType.makeNullable()
|
||||
}
|
||||
return kotlinType?.toKtNonErrorType(analysisContext)
|
||||
}
|
||||
return kotlinType?.toKtType(analysisContext)
|
||||
}
|
||||
} else if (parentExpression is KtValueArgument) {
|
||||
val callExpression = getContainingCallExpression(parentExpression)
|
||||
if (callExpression != null) {
|
||||
val bindingContext = analysisContext.analyze(callExpression)
|
||||
val resolvedCall = callExpression.getResolvedCall(bindingContext)
|
||||
if (resolvedCall != null) {
|
||||
val parameterDescriptor = resolvedCall.getParameterForArgument(parentExpression)?.original
|
||||
if (parameterDescriptor != null) {
|
||||
val kotlinType = when (val originalCallableDescriptor = parameterDescriptor.containingDeclaration) {
|
||||
is SamConstructorDescriptor -> originalCallableDescriptor.returnTypeOrNothing
|
||||
else -> {
|
||||
if (parameterDescriptor.isVararg)
|
||||
parameterDescriptor.varargElementType
|
||||
else
|
||||
parameterDescriptor.type
|
||||
|
||||
is KtValueArgument -> {
|
||||
val callExpression = getContainingCallExpression(parentExpression)
|
||||
if (callExpression != null) {
|
||||
val bindingContext = analysisContext.analyze(callExpression)
|
||||
val resolvedCall = callExpression.getResolvedCall(bindingContext)
|
||||
if (resolvedCall != null) {
|
||||
val parameterDescriptor = resolvedCall.getParameterForArgument(parentExpression)?.original
|
||||
if (parameterDescriptor != null) {
|
||||
val kotlinType = when (val originalCallableDescriptor = parameterDescriptor.containingDeclaration) {
|
||||
is SamConstructorDescriptor -> originalCallableDescriptor.returnTypeOrNothing
|
||||
else -> {
|
||||
if (parameterDescriptor.isVararg)
|
||||
parameterDescriptor.varargElementType
|
||||
else
|
||||
parameterDescriptor.type
|
||||
}
|
||||
}
|
||||
return kotlinType?.toKtNonErrorType(analysisContext)
|
||||
}
|
||||
return kotlinType?.toKtType(analysisContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is KtWhenConditionWithExpression -> {
|
||||
val whenExpression = (parentExpression.parent as? KtWhenEntry)?.parent as? KtWhenExpression
|
||||
if (whenExpression != null) {
|
||||
val subject = whenExpression.subjectExpression ?: return with(analysisSession) { builtinTypes.BOOLEAN }
|
||||
val kotlinType = analysisContext.analyze(subject).getType(subject)
|
||||
return kotlinType?.toKtNonErrorType(analysisContext)
|
||||
}
|
||||
}
|
||||
|
||||
is KtBlockExpression -> {
|
||||
if (expression == parentExpression.statements.lastOrNull()) {
|
||||
val functionLiteral = parentExpression.parent as? KtFunctionLiteral
|
||||
if (functionLiteral != null) {
|
||||
val functionalType = getExpectedType(functionLiteral) as? KtFunctionalType
|
||||
functionalType?.returnType?.let { return it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is KtWhenEntry -> {
|
||||
if (expression == parentExpression.expression) {
|
||||
val whenExpression = parentExpression.parent as? KtWhenExpression
|
||||
if (whenExpression != null) {
|
||||
getExpectedType(whenExpression)?.let { return it }
|
||||
|
||||
val entries = whenExpression.entries
|
||||
val entryExpressions = entries.mapNotNull { entry -> entry.expression?.takeUnless { expression == it } }
|
||||
val kotlinTypes = entryExpressions.mapNotNull { analysisContext.analyze(it).getType(it) }
|
||||
return intersectWrappedTypes(kotlinTypes).toKtNonErrorType(analysisContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,7 +269,7 @@ class KtFe10ExpressionTypeProvider(
|
||||
|
||||
val bindingContext = analysisContext.analyze(ktExpression)
|
||||
val kotlinType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, ktExpression]
|
||||
return kotlinType?.toKtType(analysisContext)
|
||||
return kotlinType?.toKtNonErrorType(analysisContext)
|
||||
}
|
||||
|
||||
private fun getContainingCallExpression(argument: KtValueArgument): KtCallExpression? {
|
||||
@@ -274,4 +317,7 @@ class KtFe10ExpressionTypeProvider(
|
||||
val expressionType = expression.getType(bindingContext) ?: return false
|
||||
return !TypeUtils.isNullableType(expressionType)
|
||||
}
|
||||
|
||||
private fun KotlinType.toKtNonErrorType(analysisContext: Fe10AnalysisContext): KtType? =
|
||||
this.toKtType(analysisContext).takeUnless { it is KtErrorType }
|
||||
}
|
||||
+144
@@ -41,11 +41,77 @@ public class Fe10IdeNormalAnalysisSourceModuleExpectedExpressionTypeTestGenerate
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("afterExclOperand.kt")
|
||||
public void testAfterExclOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/afterExclOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFilesPresentInExpectedExpressionType() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionGet.kt")
|
||||
public void testArrayAccessExpressionGet() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionGet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionGetWithTypeParameters.kt")
|
||||
public void testArrayAccessExpressionGetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionGetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionSet.kt")
|
||||
public void testArrayAccessExpressionSet() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionSet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionSetWithTypeParameters.kt")
|
||||
public void testArrayAccessExpressionSetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionSetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionInWhenWithSubject.kt")
|
||||
public void testConditionInWhenWithSubject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/conditionInWhenWithSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionInWhenWithoutSubject.kt")
|
||||
public void testConditionInWhenWithoutSubject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/conditionInWhenWithoutSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionLeftOperand.kt")
|
||||
public void testElvisExpressionLeftOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionLeftOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionLeftOperandWithoutExplicitType.kt")
|
||||
public void testElvisExpressionLeftOperandWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionLeftOperandWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionRightOperand.kt")
|
||||
public void testElvisExpressionRightOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionRightOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionRightOperandWithoutExplicitType.kt")
|
||||
public void testElvisExpressionRightOperandWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionRightOperandWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("functionExpressionBody.kt")
|
||||
public void testFunctionExpressionBody() throws Exception {
|
||||
@@ -136,6 +202,12 @@ public class Fe10IdeNormalAnalysisSourceModuleExpectedExpressionTypeTestGenerate
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/infixFunctionParamQualified.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("infixFunctionTypeParameter.kt")
|
||||
public void testInfixFunctionTypeParameter() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/infixFunctionTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaWithExplicitTypeFromVariable.kt")
|
||||
public void testLambdaWithExplicitTypeFromVariable() throws Exception {
|
||||
@@ -148,6 +220,42 @@ public class Fe10IdeNormalAnalysisSourceModuleExpectedExpressionTypeTestGenerate
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lambdaWithoutReturnNorExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInFunctionBlockBody.kt")
|
||||
public void testLastStatementInFunctionBlockBody() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInFunctionBlockBody.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambda.kt")
|
||||
public void testLastStatementInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambdaWithTypeMismatch.kt")
|
||||
public void testLastStatementInLambdaWithTypeMismatch() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambdaWithTypeMismatch.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambdaWithoutExplicitType.kt")
|
||||
public void testLastStatementInLambdaWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambdaWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInTry.kt")
|
||||
public void testLastStatementInTry() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInTryWithoutExplicitType.kt")
|
||||
public void testLastStatementInTryWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInTryWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("propertyDeclaration.kt")
|
||||
public void testPropertyDeclaration() throws Exception {
|
||||
@@ -274,6 +382,42 @@ public class Fe10IdeNormalAnalysisSourceModuleExpectedExpressionTypeTestGenerate
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/samWithTypeCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIf.kt")
|
||||
public void testStatementInIf() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIf.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIfBlockExpression.kt")
|
||||
public void testStatementInIfBlockExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIfBlockExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIfWithoutExplicitType.kt")
|
||||
public void testStatementInIfWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIfWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhen.kt")
|
||||
public void testStatementInWhen() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhen.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhenBlockExpression.kt")
|
||||
public void testStatementInWhenBlockExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhenBlockExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhenWithoutExplicitType.kt")
|
||||
public void testStatementInWhenWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhenWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("variableAssignment.kt")
|
||||
public void testVariableAssignment() throws Exception {
|
||||
|
||||
+6
@@ -277,6 +277,12 @@ public class Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated exte
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/assignment/arrayAssignmentTargetUnresovledSet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAssignmentTargetWithTypeParameters.kt")
|
||||
public void testArrayAssignmentTargetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/assignment/arrayAssignmentTargetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayCompoundAssignementTarget.kt")
|
||||
public void testArrayCompoundAssignementTarget() throws Exception {
|
||||
|
||||
+17
-7
@@ -79,26 +79,36 @@ internal interface KtFirAnalysisSessionComponent {
|
||||
)
|
||||
}
|
||||
|
||||
fun FirQualifiedAccessExpression.createSubstitutorFromTypeArguments(): KtSubstitutor? {
|
||||
return createConeSubstitutorFromTypeArguments()?.toKtSubstitutor()
|
||||
fun FirQualifiedAccessExpression.createSubstitutorFromTypeArguments(discardErrorTypes: Boolean = false): KtSubstitutor? {
|
||||
return createConeSubstitutorFromTypeArguments(discardErrorTypes)?.toKtSubstitutor()
|
||||
}
|
||||
|
||||
fun FirQualifiedAccessExpression.createSubstitutorFromTypeArguments(callableSymbol: FirCallableSymbol<*>): KtSubstitutor {
|
||||
return createConeSubstitutorFromTypeArguments(callableSymbol).toKtSubstitutor()
|
||||
fun FirQualifiedAccessExpression.createSubstitutorFromTypeArguments(
|
||||
callableSymbol: FirCallableSymbol<*>,
|
||||
discardErrorTypes: Boolean = false
|
||||
): KtSubstitutor {
|
||||
return createConeSubstitutorFromTypeArguments(callableSymbol, discardErrorTypes).toKtSubstitutor()
|
||||
}
|
||||
|
||||
fun FirQualifiedAccessExpression.createConeSubstitutorFromTypeArguments(): ConeSubstitutor? {
|
||||
fun FirQualifiedAccessExpression.createConeSubstitutorFromTypeArguments(discardErrorTypes: Boolean = false): ConeSubstitutor? {
|
||||
val symbol = calleeReference.toResolvedCallableSymbol() ?: return null
|
||||
return createConeSubstitutorFromTypeArguments(symbol)
|
||||
return createConeSubstitutorFromTypeArguments(symbol, discardErrorTypes)
|
||||
}
|
||||
|
||||
fun FirQualifiedAccessExpression.createConeSubstitutorFromTypeArguments(callableSymbol: FirCallableSymbol<*>): ConeSubstitutor {
|
||||
/**
|
||||
* @param discardErrorTypes if true, then type arguments with error types are not added in substitution map
|
||||
*/
|
||||
fun FirQualifiedAccessExpression.createConeSubstitutorFromTypeArguments(
|
||||
callableSymbol: FirCallableSymbol<*>,
|
||||
discardErrorTypes: Boolean = false
|
||||
): ConeSubstitutor {
|
||||
val typeArgumentMap = buildMap {
|
||||
// Type arguments are ignored defensively if `callableSymbol` can't provide enough type parameters (and vice versa). For
|
||||
// example, when call candidates are collected, the candidate's `callableSymbol` might have fewer type parameters than the
|
||||
// inferred call's type arguments.
|
||||
typeArguments.zip(callableSymbol.typeParameterSymbols).forEach { (typeArgument, typeParameterSymbol) ->
|
||||
val type = typeArgument.safeAs<FirTypeProjectionWithVariance>()?.typeRef?.coneType ?: return@forEach
|
||||
if (type is ConeErrorType && discardErrorTypes) return@forEach
|
||||
put(typeParameterSymbol, type)
|
||||
}
|
||||
}
|
||||
|
||||
+135
-14
@@ -11,6 +11,8 @@ import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.getReferencedElementType
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.unwrap
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtErrorType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirOfType
|
||||
@@ -23,11 +25,13 @@ import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.resolve.constructFunctionType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
@@ -92,8 +96,19 @@ internal class KtFirExpressionTypeProvider(
|
||||
val assignment = expression.parent as? KtBinaryExpression ?: return null
|
||||
if (assignment.operationToken !in KtTokens.ALL_ASSIGNMENTS) return null
|
||||
if (assignment.left != expression) return null
|
||||
val setTargetArgumentParameter = fir.resolvedArgumentMapping?.entries?.last()?.value ?: return null
|
||||
return setTargetArgumentParameter.returnTypeRef.coneType.asKtType()
|
||||
val setTargetParameterType = fir.argumentsToSubstitutedValueParameters()?.values?.last()?.substitutedType ?: return null
|
||||
return setTargetParameterType.asKtType()
|
||||
}
|
||||
|
||||
private data class SubstitutedValueParameter(val parameter: FirValueParameter, val substitutedType: ConeKotlinType)
|
||||
|
||||
private fun FirFunctionCall.argumentsToSubstitutedValueParameters(
|
||||
substituteWithErrorTypes: Boolean = true
|
||||
): LinkedHashMap<FirExpression, SubstitutedValueParameter>? {
|
||||
val substitutor = createConeSubstitutorFromTypeArguments(discardErrorTypes = !substituteWithErrorTypes) ?: ConeSubstitutor.Empty
|
||||
return resolvedArgumentMapping?.mapValuesTo(LinkedHashMap()) { (_, parameter) ->
|
||||
SubstitutedValueParameter(parameter, substitutor.substituteOrSelf(parameter.returnTypeRef.coneType))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType {
|
||||
@@ -134,10 +149,17 @@ internal class KtFirExpressionTypeProvider(
|
||||
?: getExpressionTypeByIfOrBooleanCondition(unwrapped)
|
||||
?: getExpectedTypeByTypeCast(unwrapped)
|
||||
?: getExpectedTypeOfFunctionParameter(unwrapped)
|
||||
?: getExpectedTypeOfIndexingParameter(unwrapped)
|
||||
?: getExpectedTypeOfInfixFunctionParameter(unwrapped)
|
||||
?: getExpectedTypeByVariableAssignment(unwrapped)
|
||||
?: getExpectedTypeByPropertyDeclaration(unwrapped)
|
||||
?: getExpectedTypeByFunctionExpressionBody(unwrapped)
|
||||
?: getExpectedTypeOfLastStatementInBlock(unwrapped)
|
||||
?: getExpectedTypeByIfExpression(unwrapped)
|
||||
?: getExpectedTypeOfWhenEntryExpression(unwrapped)
|
||||
?: getExpectedTypeByTryExpression(unwrapped)
|
||||
?: getExpectedTypeOfElvisOperand(unwrapped)
|
||||
?: getExpectedTypeByWhenEntryValue(unwrapped)
|
||||
return expectedType
|
||||
}
|
||||
|
||||
@@ -158,9 +180,9 @@ internal class KtFirExpressionTypeProvider(
|
||||
return (callee.fir as FirSimpleFunction).returnTypeRef.coneType.asKtType()
|
||||
}
|
||||
|
||||
val arguments = firCall.resolvedArgumentMapping ?: return null
|
||||
val firParameterForExpression =
|
||||
arguments.entries.firstOrNull { (arg, _) ->
|
||||
val argumentsToParameters = firCall.argumentsToSubstitutedValueParameters(substituteWithErrorTypes = false) ?: return null
|
||||
val (firParameterForExpression, substitutedType) =
|
||||
argumentsToParameters.entries.firstOrNull { (arg, _) ->
|
||||
when (arg) {
|
||||
// TODO: better to utilize. See `createArgumentMapping` in [KtFirCallResolver]
|
||||
is FirLambdaArgumentExpression, is FirNamedArgumentExpression, is FirSpreadArgumentExpression ->
|
||||
@@ -169,11 +191,29 @@ internal class KtFirExpressionTypeProvider(
|
||||
arg.psi == argumentExpression
|
||||
}
|
||||
}?.value ?: return null
|
||||
val coneType = firParameterForExpression.returnTypeRef.coneType
|
||||
return if (firParameterForExpression.isVararg)
|
||||
coneType.varargElementType().asKtType()
|
||||
substitutedType.varargElementType().asKtType()
|
||||
else
|
||||
coneType.asKtType()
|
||||
substitutedType.asKtType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Expected type of the indexing parameter in array access, for example, in the following code:
|
||||
* ```
|
||||
* val map = mapOf<Int, String>()
|
||||
* map[k] = v
|
||||
* ```
|
||||
* `k` is indexing parameter and its expected type is `Int`.
|
||||
*/
|
||||
private fun getExpectedTypeOfIndexingParameter(expression: PsiElement): KtType? {
|
||||
val arrayAccessExpression = expression.unwrapQualified<KtArrayAccessExpression> { arrayAccessExpression, currentExpression ->
|
||||
currentExpression in arrayAccessExpression.indexExpressions
|
||||
} ?: return null
|
||||
val firCall = arrayAccessExpression.getOrBuildFirSafe<FirFunctionCall>(firResolveSession) ?: return null
|
||||
val firArgument = firCall.argumentList.arguments.firstOrNull { it.psi == expression } ?: return null
|
||||
|
||||
val argumentsToParameters = firCall.argumentsToSubstitutedValueParameters(substituteWithErrorTypes = false) ?: return null
|
||||
return argumentsToParameters[firArgument]?.substitutedType?.asKtType()
|
||||
}
|
||||
|
||||
private fun PsiElement.getFunctionCallAsWithThisAsParameter(): KtCallWithArgument? {
|
||||
@@ -196,9 +236,8 @@ internal class KtFirExpressionTypeProvider(
|
||||
val firCall = infixCallExpression.getOrBuildFirSafe<FirFunctionCall>(firResolveSession) ?: return null
|
||||
|
||||
// There is only one parameter for infix functions; get its type
|
||||
val arguments = firCall.resolvedArgumentMapping ?: return null
|
||||
val firParameterForExpression = arguments.values.singleOrNull() ?: return null
|
||||
return firParameterForExpression.returnTypeRef.coneType.asKtType()
|
||||
val argumentsToParameters = firCall.argumentsToSubstitutedValueParameters(substituteWithErrorTypes = false) ?: return null
|
||||
return argumentsToParameters.values.singleOrNull()?.substitutedType?.asKtType() ?: return null
|
||||
}
|
||||
|
||||
private fun getExpectedTypeByReturnExpression(expression: PsiElement): KtType? {
|
||||
@@ -222,14 +261,14 @@ internal class KtFirExpressionTypeProvider(
|
||||
expression.unwrapQualified<KtBinaryExpression> { binaryExpr, expr -> binaryExpr.right == expr && binaryExpr.operationToken == KtTokens.EQ }
|
||||
?: return null
|
||||
val variableExpression = assignmentExpression.left as? KtNameReferenceExpression ?: return null
|
||||
return getKtExpressionType(variableExpression)
|
||||
return getKtExpressionNonErrorType(variableExpression)
|
||||
}
|
||||
|
||||
private fun getExpectedTypeByPropertyDeclaration(expression: PsiElement): KtType? {
|
||||
// Given: `val x: T = expression`
|
||||
// Expected type of `expression` is `T`
|
||||
val property = expression.unwrapQualified<KtProperty> { property, expr -> property.initializer == expr } ?: return null
|
||||
return getReturnTypeForKtDeclaration(property)
|
||||
return getReturnTypeForKtDeclaration(property).nonErrorTypeOrNull()
|
||||
}
|
||||
|
||||
private fun getExpectedTypeByFunctionExpressionBody(expression: PsiElement): KtType? {
|
||||
@@ -241,9 +280,91 @@ internal class KtFirExpressionTypeProvider(
|
||||
// which may raise an exception if we attempt to retrieve, e.g., callable declaration from it.
|
||||
return null
|
||||
}
|
||||
return getReturnTypeForKtDeclaration(function)
|
||||
return getReturnTypeForKtDeclaration(function).nonErrorTypeOrNull()
|
||||
}
|
||||
|
||||
private fun getExpectedTypeOfLastStatementInBlock(expression: PsiElement): KtType? {
|
||||
val blockExpression = expression.unwrapQualified<KtBlockExpression> { blockExpression, currentExpression ->
|
||||
currentExpression == blockExpression.statements.lastOrNull()
|
||||
} ?: return null
|
||||
|
||||
val functionLiteral = blockExpression.parent as? KtFunctionLiteral
|
||||
return if (functionLiteral != null) {
|
||||
val functionalType = getExpectedType(functionLiteral) as? KtFunctionalType
|
||||
functionalType?.returnType
|
||||
} else {
|
||||
getExpectedType(blockExpression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getExpectedTypeByIfExpression(expression: PsiElement): KtType? {
|
||||
val ifExpression = expression.unwrapQualified<KtIfExpression> { ifExpression, currentExpression ->
|
||||
currentExpression == ifExpression.then || currentExpression == ifExpression.`else`
|
||||
} ?: return null
|
||||
getExpectedType(ifExpression)?.let { return it }
|
||||
|
||||
// if `KtIfExpression` doesn't have an expected type, get the expected type of the current branch from the other branch
|
||||
val otherBranch = (if (expression == ifExpression.then) ifExpression.`else` else ifExpression.then) ?: return null
|
||||
return getKtExpressionNonErrorType(otherBranch)
|
||||
}
|
||||
|
||||
private fun getExpectedTypeOfWhenEntryExpression(expression: PsiElement): KtType? {
|
||||
val whenEntry = expression.unwrapQualified<KtWhenEntry> { whenEntry, currentExpression ->
|
||||
currentExpression == whenEntry.expression
|
||||
} ?: return null
|
||||
val whenExpression = whenEntry.parent as? KtWhenExpression ?: return null
|
||||
getExpectedType(whenExpression)?.let { return it }
|
||||
|
||||
// if `KtWhenExpression` doesn't have an expected type, get the expected type of the current entry from the other entries
|
||||
val entryExpressions = whenExpression.entries
|
||||
.mapNotNull { it.expression }
|
||||
.filter { entryExpression -> entryExpression != expression }
|
||||
val types = entryExpressions.mapNotNull { getKtExpressionNonErrorType(it) }
|
||||
return analysisSession.useSiteSession.typeContext.intersectTypesOrNull(types.map { it.coneType })?.asKtType()
|
||||
}
|
||||
|
||||
private fun getExpectedTypeByTryExpression(expression: PsiElement): KtType? {
|
||||
val tryExpression = expression.unwrapQualified<KtTryExpression> { tryExpression, currentExpression ->
|
||||
currentExpression == tryExpression.tryBlock
|
||||
} ?: return null
|
||||
return getExpectedType(tryExpression)
|
||||
}
|
||||
|
||||
private fun getExpectedTypeOfElvisOperand(expression: PsiElement): KtType? {
|
||||
val binaryExpression = expression.unwrapQualified<KtBinaryExpression> { binaryExpression, operand ->
|
||||
binaryExpression.operationToken == KtTokens.ELVIS && (operand == binaryExpression.left || operand == binaryExpression.right)
|
||||
} ?: return null
|
||||
if (expression !is KtExpression) return null
|
||||
val type = getExpectedType(binaryExpression) ?: getElvisOperandExpectedTypeByOtherOperand(expression, binaryExpression)
|
||||
|
||||
return type?.applyIf(expression == binaryExpression.left) { withNullability(ConeNullability.NULLABLE) }
|
||||
}
|
||||
|
||||
private fun getElvisOperandExpectedTypeByOtherOperand(operand: KtExpression, elvisExpression: KtBinaryExpression): KtType? {
|
||||
val leftOperand = elvisExpression.left ?: return null
|
||||
val rightOperand = elvisExpression.right ?: return null
|
||||
return if (operand == leftOperand) {
|
||||
getKtExpressionNonErrorType(rightOperand)
|
||||
} else {
|
||||
getKtExpressionNonErrorType(leftOperand)?.withNullability(ConeNullability.NOT_NULL)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtType.withNullability(nullability: ConeNullability): KtType =
|
||||
coneType.withNullability(nullability, analysisSession.useSiteSession.typeContext).asKtType()
|
||||
|
||||
private fun getExpectedTypeByWhenEntryValue(expression: PsiElement): KtType? {
|
||||
val condition = expression.parent as? KtWhenConditionWithExpression ?: return null
|
||||
val whenExpression = (condition.parent as? KtWhenEntry)?.parent as? KtWhenExpression ?: return null
|
||||
val subject = whenExpression.subjectExpression ?: return with(analysisSession) { builtinTypes.BOOLEAN }
|
||||
return getKtExpressionNonErrorType(subject)
|
||||
}
|
||||
|
||||
private fun getKtExpressionNonErrorType(expression: KtExpression): KtType? =
|
||||
getKtExpressionType(expression)?.nonErrorTypeOrNull()
|
||||
|
||||
private fun KtType.nonErrorTypeOrNull(): KtType? = takeUnless { it is KtErrorType }
|
||||
|
||||
private fun PsiElement.isWhileLoopCondition() =
|
||||
unwrapQualified<KtWhileExpressionBase> { whileExpr, cond -> whileExpr.condition == cond } != null
|
||||
|
||||
|
||||
+144
@@ -41,11 +41,77 @@ public class FirIdeDependentAnalysisSourceModuleExpectedExpressionTypeTestGenera
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("afterExclOperand.kt")
|
||||
public void testAfterExclOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/afterExclOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFilesPresentInExpectedExpressionType() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionGet.kt")
|
||||
public void testArrayAccessExpressionGet() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionGet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionGetWithTypeParameters.kt")
|
||||
public void testArrayAccessExpressionGetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionGetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionSet.kt")
|
||||
public void testArrayAccessExpressionSet() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionSet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionSetWithTypeParameters.kt")
|
||||
public void testArrayAccessExpressionSetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionSetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionInWhenWithSubject.kt")
|
||||
public void testConditionInWhenWithSubject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/conditionInWhenWithSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionInWhenWithoutSubject.kt")
|
||||
public void testConditionInWhenWithoutSubject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/conditionInWhenWithoutSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionLeftOperand.kt")
|
||||
public void testElvisExpressionLeftOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionLeftOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionLeftOperandWithoutExplicitType.kt")
|
||||
public void testElvisExpressionLeftOperandWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionLeftOperandWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionRightOperand.kt")
|
||||
public void testElvisExpressionRightOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionRightOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionRightOperandWithoutExplicitType.kt")
|
||||
public void testElvisExpressionRightOperandWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionRightOperandWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("functionExpressionBody.kt")
|
||||
public void testFunctionExpressionBody() throws Exception {
|
||||
@@ -136,6 +202,12 @@ public class FirIdeDependentAnalysisSourceModuleExpectedExpressionTypeTestGenera
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/infixFunctionParamQualified.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("infixFunctionTypeParameter.kt")
|
||||
public void testInfixFunctionTypeParameter() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/infixFunctionTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaWithExplicitTypeFromVariable.kt")
|
||||
public void testLambdaWithExplicitTypeFromVariable() throws Exception {
|
||||
@@ -148,6 +220,42 @@ public class FirIdeDependentAnalysisSourceModuleExpectedExpressionTypeTestGenera
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lambdaWithoutReturnNorExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInFunctionBlockBody.kt")
|
||||
public void testLastStatementInFunctionBlockBody() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInFunctionBlockBody.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambda.kt")
|
||||
public void testLastStatementInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambdaWithTypeMismatch.kt")
|
||||
public void testLastStatementInLambdaWithTypeMismatch() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambdaWithTypeMismatch.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambdaWithoutExplicitType.kt")
|
||||
public void testLastStatementInLambdaWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambdaWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInTry.kt")
|
||||
public void testLastStatementInTry() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInTryWithoutExplicitType.kt")
|
||||
public void testLastStatementInTryWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInTryWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("propertyDeclaration.kt")
|
||||
public void testPropertyDeclaration() throws Exception {
|
||||
@@ -274,6 +382,42 @@ public class FirIdeDependentAnalysisSourceModuleExpectedExpressionTypeTestGenera
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/samWithTypeCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIf.kt")
|
||||
public void testStatementInIf() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIf.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIfBlockExpression.kt")
|
||||
public void testStatementInIfBlockExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIfBlockExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIfWithoutExplicitType.kt")
|
||||
public void testStatementInIfWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIfWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhen.kt")
|
||||
public void testStatementInWhen() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhen.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhenBlockExpression.kt")
|
||||
public void testStatementInWhenBlockExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhenBlockExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhenWithoutExplicitType.kt")
|
||||
public void testStatementInWhenWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhenWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("variableAssignment.kt")
|
||||
public void testVariableAssignment() throws Exception {
|
||||
|
||||
+6
@@ -277,6 +277,12 @@ public class FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated ex
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/assignment/arrayAssignmentTargetUnresovledSet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAssignmentTargetWithTypeParameters.kt")
|
||||
public void testArrayAssignmentTargetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/assignment/arrayAssignmentTargetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayCompoundAssignementTarget.kt")
|
||||
public void testArrayCompoundAssignementTarget() throws Exception {
|
||||
|
||||
+144
@@ -41,11 +41,77 @@ public class FirIdeNormalAnalysisSourceModuleExpectedExpressionTypeTestGenerated
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("afterExclOperand.kt")
|
||||
public void testAfterExclOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/afterExclOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFilesPresentInExpectedExpressionType() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionGet.kt")
|
||||
public void testArrayAccessExpressionGet() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionGet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionGetWithTypeParameters.kt")
|
||||
public void testArrayAccessExpressionGetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionGetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionSet.kt")
|
||||
public void testArrayAccessExpressionSet() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionSet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionSetWithTypeParameters.kt")
|
||||
public void testArrayAccessExpressionSetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionSetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionInWhenWithSubject.kt")
|
||||
public void testConditionInWhenWithSubject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/conditionInWhenWithSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionInWhenWithoutSubject.kt")
|
||||
public void testConditionInWhenWithoutSubject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/conditionInWhenWithoutSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionLeftOperand.kt")
|
||||
public void testElvisExpressionLeftOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionLeftOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionLeftOperandWithoutExplicitType.kt")
|
||||
public void testElvisExpressionLeftOperandWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionLeftOperandWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionRightOperand.kt")
|
||||
public void testElvisExpressionRightOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionRightOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionRightOperandWithoutExplicitType.kt")
|
||||
public void testElvisExpressionRightOperandWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionRightOperandWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("functionExpressionBody.kt")
|
||||
public void testFunctionExpressionBody() throws Exception {
|
||||
@@ -136,6 +202,12 @@ public class FirIdeNormalAnalysisSourceModuleExpectedExpressionTypeTestGenerated
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/infixFunctionParamQualified.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("infixFunctionTypeParameter.kt")
|
||||
public void testInfixFunctionTypeParameter() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/infixFunctionTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaWithExplicitTypeFromVariable.kt")
|
||||
public void testLambdaWithExplicitTypeFromVariable() throws Exception {
|
||||
@@ -148,6 +220,42 @@ public class FirIdeNormalAnalysisSourceModuleExpectedExpressionTypeTestGenerated
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lambdaWithoutReturnNorExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInFunctionBlockBody.kt")
|
||||
public void testLastStatementInFunctionBlockBody() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInFunctionBlockBody.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambda.kt")
|
||||
public void testLastStatementInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambdaWithTypeMismatch.kt")
|
||||
public void testLastStatementInLambdaWithTypeMismatch() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambdaWithTypeMismatch.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambdaWithoutExplicitType.kt")
|
||||
public void testLastStatementInLambdaWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambdaWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInTry.kt")
|
||||
public void testLastStatementInTry() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInTryWithoutExplicitType.kt")
|
||||
public void testLastStatementInTryWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInTryWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("propertyDeclaration.kt")
|
||||
public void testPropertyDeclaration() throws Exception {
|
||||
@@ -274,6 +382,42 @@ public class FirIdeNormalAnalysisSourceModuleExpectedExpressionTypeTestGenerated
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/samWithTypeCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIf.kt")
|
||||
public void testStatementInIf() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIf.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIfBlockExpression.kt")
|
||||
public void testStatementInIfBlockExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIfBlockExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIfWithoutExplicitType.kt")
|
||||
public void testStatementInIfWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIfWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhen.kt")
|
||||
public void testStatementInWhen() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhen.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhenBlockExpression.kt")
|
||||
public void testStatementInWhenBlockExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhenBlockExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhenWithoutExplicitType.kt")
|
||||
public void testStatementInWhenWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhenWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("variableAssignment.kt")
|
||||
public void testVariableAssignment() throws Exception {
|
||||
|
||||
+6
@@ -277,6 +277,12 @@ public class FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated exten
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/assignment/arrayAssignmentTargetUnresovledSet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAssignmentTargetWithTypeParameters.kt")
|
||||
public void testArrayAssignmentTargetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/assignment/arrayAssignmentTargetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayCompoundAssignementTarget.kt")
|
||||
public void testArrayCompoundAssignementTarget() throws Exception {
|
||||
|
||||
+3
-1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
@@ -20,10 +21,11 @@ import org.jetbrains.kotlin.types.Variance
|
||||
abstract class AbstractAnalysisApiGetSuperTypesTest : AbstractAnalysisApiSingleFileTest(){
|
||||
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
|
||||
val expression = testServices.expressionMarkerProvider.getSelectedElement(ktFile)
|
||||
expression as? KtExpression ?: error("unexpected expression kind ${expression::class}")
|
||||
|
||||
val actual = executeOnPooledThreadInReadAction {
|
||||
analyze(expression) {
|
||||
val expectedType = expression.getExpectedType() ?: error("expect to get type of expression '${expression.text}'")
|
||||
val expectedType = expression.getKtType() ?: error("expect to get type of expression '${expression.text}'")
|
||||
val directSuperTypes = expectedType.getDirectSuperTypes()
|
||||
val approximatedDirectSuperTypes = expectedType.getDirectSuperTypes(shouldApproximate = true)
|
||||
val allSuperTypes = expectedType.getAllSuperTypes()
|
||||
|
||||
+144
@@ -41,11 +41,77 @@ public class FirStandaloneNormalAnalysisSourceModuleExpectedExpressionTypeTestGe
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("afterExclOperand.kt")
|
||||
public void testAfterExclOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/afterExclOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFilesPresentInExpectedExpressionType() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionGet.kt")
|
||||
public void testArrayAccessExpressionGet() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionGet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionGetWithTypeParameters.kt")
|
||||
public void testArrayAccessExpressionGetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionGetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionSet.kt")
|
||||
public void testArrayAccessExpressionSet() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionSet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAccessExpressionSetWithTypeParameters.kt")
|
||||
public void testArrayAccessExpressionSetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/arrayAccessExpressionSetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionInWhenWithSubject.kt")
|
||||
public void testConditionInWhenWithSubject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/conditionInWhenWithSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionInWhenWithoutSubject.kt")
|
||||
public void testConditionInWhenWithoutSubject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/conditionInWhenWithoutSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionLeftOperand.kt")
|
||||
public void testElvisExpressionLeftOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionLeftOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionLeftOperandWithoutExplicitType.kt")
|
||||
public void testElvisExpressionLeftOperandWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionLeftOperandWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionRightOperand.kt")
|
||||
public void testElvisExpressionRightOperand() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionRightOperand.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("elvisExpressionRightOperandWithoutExplicitType.kt")
|
||||
public void testElvisExpressionRightOperandWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/elvisExpressionRightOperandWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("functionExpressionBody.kt")
|
||||
public void testFunctionExpressionBody() throws Exception {
|
||||
@@ -136,6 +202,12 @@ public class FirStandaloneNormalAnalysisSourceModuleExpectedExpressionTypeTestGe
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/infixFunctionParamQualified.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("infixFunctionTypeParameter.kt")
|
||||
public void testInfixFunctionTypeParameter() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/infixFunctionTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaWithExplicitTypeFromVariable.kt")
|
||||
public void testLambdaWithExplicitTypeFromVariable() throws Exception {
|
||||
@@ -148,6 +220,42 @@ public class FirStandaloneNormalAnalysisSourceModuleExpectedExpressionTypeTestGe
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lambdaWithoutReturnNorExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInFunctionBlockBody.kt")
|
||||
public void testLastStatementInFunctionBlockBody() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInFunctionBlockBody.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambda.kt")
|
||||
public void testLastStatementInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambdaWithTypeMismatch.kt")
|
||||
public void testLastStatementInLambdaWithTypeMismatch() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambdaWithTypeMismatch.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInLambdaWithoutExplicitType.kt")
|
||||
public void testLastStatementInLambdaWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInLambdaWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInTry.kt")
|
||||
public void testLastStatementInTry() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lastStatementInTryWithoutExplicitType.kt")
|
||||
public void testLastStatementInTryWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/lastStatementInTryWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("propertyDeclaration.kt")
|
||||
public void testPropertyDeclaration() throws Exception {
|
||||
@@ -274,6 +382,42 @@ public class FirStandaloneNormalAnalysisSourceModuleExpectedExpressionTypeTestGe
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/samWithTypeCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIf.kt")
|
||||
public void testStatementInIf() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIf.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIfBlockExpression.kt")
|
||||
public void testStatementInIfBlockExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIfBlockExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInIfWithoutExplicitType.kt")
|
||||
public void testStatementInIfWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInIfWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhen.kt")
|
||||
public void testStatementInWhen() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhen.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhenBlockExpression.kt")
|
||||
public void testStatementInWhenBlockExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhenBlockExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("statementInWhenWithoutExplicitType.kt")
|
||||
public void testStatementInWhenWithoutExplicitType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expectedExpressionType/statementInWhenWithoutExplicitType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("variableAssignment.kt")
|
||||
public void testVariableAssignment() throws Exception {
|
||||
|
||||
+6
@@ -277,6 +277,12 @@ public class FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerate
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/assignment/arrayAssignmentTargetUnresovledSet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayAssignmentTargetWithTypeParameters.kt")
|
||||
public void testArrayAssignmentTargetWithTypeParameters() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/assignment/arrayAssignmentTargetWithTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayCompoundAssignementTarget.kt")
|
||||
public void testArrayCompoundAssignementTarget() throws Exception {
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun test() {
|
||||
if (!a<caret>v)
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
expression: av
|
||||
expected type: null
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
operator fun get(p1: Int) {}
|
||||
operator fun set(p1: String, p2: Int, value: Int) {}
|
||||
|
||||
fun d() = this[a<caret>v]
|
||||
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// IGNORE_FE10
|
||||
class A {
|
||||
operator fun <T> get(key: T) {}
|
||||
}
|
||||
|
||||
fun test(a: A) {
|
||||
a[a<caret>v]
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
expression: av
|
||||
expected type: KtTypeParameterType:
|
||||
annotationsList: []
|
||||
type: T
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
operator fun get(p1: Int) {}
|
||||
operator fun set(p1: String, p2: Int, value: Int) {}
|
||||
|
||||
fun d() {
|
||||
this[a<caret>v, 2] = 1
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/String
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
operator fun <T> set(key: T, value: T) {}
|
||||
}
|
||||
|
||||
fun test(a: A) {
|
||||
a[a<caret>v] = 1
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
enum class E {
|
||||
A
|
||||
B
|
||||
}
|
||||
|
||||
fun foo(e: E) {
|
||||
when(e) {
|
||||
a<caret>v -> null
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: E
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
fun foo() {
|
||||
when() {
|
||||
a<caret>v -> null
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Boolean
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo() {
|
||||
val result: Int = a<caret>v ?: 1
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int?
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo() {
|
||||
a<caret>v ?: 1
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int?
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo(i: Int?) {
|
||||
val result: Int = i ?: a<caret>v
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo(i: Int?) {
|
||||
i ?: a<caret>v
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
expression: av
|
||||
expected type: KtTypeErrorType:
|
||||
annotationsList: []
|
||||
type: ERROR_TYPE
|
||||
+1
-3
@@ -1,4 +1,2 @@
|
||||
expression: av
|
||||
expected type: KtClassErrorType:
|
||||
annotationsList: []
|
||||
type: ERROR_TYPE
|
||||
expected type: null
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
expression: ab
|
||||
expected type: KtTypeParameterType:
|
||||
annotationsList: []
|
||||
type: T
|
||||
+3
-2
@@ -1,4 +1,5 @@
|
||||
expression: ab
|
||||
expected type: KtTypeParameterType:
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
type: T
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
fun x() {
|
||||
1 toCall a<caret>v
|
||||
}
|
||||
|
||||
infix fun <T> T.toCall(y: T) {}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo(): Int {
|
||||
a<caret>v
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
expression: av
|
||||
expected type: null
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// WITH_STDLIB
|
||||
// IGNORE_FE10
|
||||
fun foo(list: List<Int>) {
|
||||
val result: List<String> = list.map { a<caret>v }
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/String
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// WITH_STDLIB
|
||||
fun foo(list: List<Int>) {
|
||||
val result: List<Int> = list.map { mapOf(a<caret>v) }
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: [
|
||||
KtTypeParameterType:
|
||||
annotationsList: []
|
||||
type: K
|
||||
KtTypeParameterType:
|
||||
annotationsList: []
|
||||
type: V
|
||||
]
|
||||
type: kotlin/Pair<K, V>
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// WITH_STDLIB
|
||||
fun foo(list: List<Int>) {
|
||||
val result = list.map { a<caret>v }
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
expression: av
|
||||
expected type: KtTypeParameterType:
|
||||
annotationsList: []
|
||||
type: R
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
fun foo() {
|
||||
val result: Int = try {
|
||||
a<caret>v
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
fun foo() {
|
||||
try {
|
||||
a<caret>v
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
expression: av
|
||||
expected type: null
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
expression: av
|
||||
expected type: KtTypeErrorType:
|
||||
annotationsList: []
|
||||
type: ERROR_TYPE
|
||||
+1
-3
@@ -1,4 +1,2 @@
|
||||
expression: av
|
||||
expected type: KtClassErrorType:
|
||||
annotationsList: []
|
||||
type: ERROR_TYPE
|
||||
expected type: null
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo() {
|
||||
val result = if (true) 1 else a<caret>v
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fun foo() {
|
||||
val result = if (true) {
|
||||
1
|
||||
} else {
|
||||
a<caret>v
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo() {
|
||||
if (true) a<caret>v else 1
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
enum class E {
|
||||
A
|
||||
B
|
||||
}
|
||||
|
||||
fun foo(e: E) {
|
||||
val result = when(e) {
|
||||
E.A -> 1
|
||||
E.B -> a<caret>v
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
enum class E {
|
||||
A
|
||||
B
|
||||
}
|
||||
|
||||
fun foo(e: E) {
|
||||
val result = when(e) {
|
||||
E.A -> { 1 }
|
||||
E.B -> { a<caret>v }
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
enum class E {
|
||||
A
|
||||
B
|
||||
C
|
||||
D
|
||||
}
|
||||
|
||||
fun foo(e: E) = when (e) {
|
||||
E.A -> 1
|
||||
E.B -> ""
|
||||
E.C -> a<caret>v
|
||||
E.D -> unresolved
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
expression: av
|
||||
expected type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Any
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// IGNORE_FE10
|
||||
class A {
|
||||
operator fun <T> set(key: Int, value: T) {}
|
||||
}
|
||||
|
||||
fun test(a: A) {
|
||||
<expr>a[1]</expr> = ""
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
expression: a[1]
|
||||
type: kotlin.String
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
expression: xy
|
||||
expected type: (T) -> R
|
||||
functionClassKind: kotlin.FunctionN
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
expression: xy
|
||||
expected type: (T) -> R
|
||||
expected type: (kotlin.Int) -> R
|
||||
functionClassKind: kotlin.FunctionN
|
||||
|
||||
Reference in New Issue
Block a user