[FIR] Implement SPREAD_OF_NULLABLE
This commit is contained in:
committed by
TeamCityServer
parent
83c5c41dd4
commit
66e052b9b3
+3
-1
@@ -409,6 +409,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error<KtElement> {
|
||||
parameter<String>("name")
|
||||
}
|
||||
|
||||
val SPREAD_OF_NULLABLE by error<PsiElement>(PositioningStrategy.SPREAD_OPERATOR)
|
||||
}
|
||||
|
||||
val AMBIGUITY by object : DiagnosticGroup("Ambiguity") {
|
||||
@@ -570,7 +572,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val NOTHING_TO_OVERRIDE by error<KtModifierListOwner>(PositioningStrategy.OVERRIDE_MODIFIER) {
|
||||
parameter<FirMemberDeclaration>("declaration")
|
||||
}
|
||||
|
||||
|
||||
val CANNOT_OVERRIDE_INVISIBLE_MEMBER by error<KtNamedDeclaration>(PositioningStrategy.OVERRIDE_MODIFIER) {
|
||||
parameter<FirCallableDeclaration>("overridingMember")
|
||||
parameter<FirCallableDeclaration>("baseMember")
|
||||
|
||||
+1
@@ -75,6 +75,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
ASSIGNMENT_LHS,
|
||||
IMPORT_LAST_NAME,
|
||||
DATA_MODIFIER,
|
||||
SPREAD_OPERATOR,
|
||||
|
||||
;
|
||||
|
||||
|
||||
@@ -281,6 +281,7 @@ object FirErrors {
|
||||
val RESULT_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
|
||||
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error0<KtValueArgument>()
|
||||
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error1<KtElement, String>()
|
||||
val SPREAD_OF_NULLABLE by error0<PsiElement>(SourceElementPositioningStrategies.SPREAD_OPERATOR)
|
||||
|
||||
// Ambiguity
|
||||
val OVERLOAD_RESOLUTION_AMBIGUITY by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
+1
@@ -45,6 +45,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
||||
FirConventionFunctionCallChecker,
|
||||
FirDivisionByZeroChecker,
|
||||
FirConstructorCallChecker,
|
||||
FirSpreadOfNullableChecker
|
||||
)
|
||||
|
||||
override val tryExpressionCheckers: Set<FirTryExpressionChecker>
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression
|
||||
import org.jetbrains.kotlin.fir.types.ConeFlexibleType
|
||||
import org.jetbrains.kotlin.fir.types.canBeNull
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
|
||||
object FirSpreadOfNullableChecker : FirFunctionCallChecker() {
|
||||
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
fun checkAndReport(argument: FirExpression, source: FirSourceElement?) {
|
||||
val argumentTypeRef = argument.typeRef
|
||||
if (argument is FirSpreadArgumentExpression && argumentTypeRef.coneType !is ConeFlexibleType && argumentTypeRef.canBeNull) {
|
||||
reporter.reportOn(source, FirErrors.SPREAD_OF_NULLABLE, context)
|
||||
}
|
||||
}
|
||||
|
||||
for (argument in expression.argumentList.arguments) {
|
||||
if (argument is FirVarargArgumentsExpression) {
|
||||
for (subArgument in argument.arguments) {
|
||||
checkAndReport(subArgument, argument.source)
|
||||
}
|
||||
} else {
|
||||
checkAndReport(argument, argument.source)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -316,6 +316,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SETTER_PROJECTED_
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SINGLETON_IN_SUPERTYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SMARTCAST_IMPOSSIBLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SPREAD_OF_NULLABLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPES_FOR_ANNOTATION_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_APPEARS_TWICE
|
||||
@@ -672,6 +673,7 @@ class FirDefaultErrorMessages {
|
||||
map.put(NO_VALUE_FOR_PARAMETER, "No value passed for parameter ''{0}''", NAME)
|
||||
map.put(NAMED_PARAMETER_NOT_FOUND, "Cannot find a parameter with this name: {0}", TO_STRING)
|
||||
map.put(MANY_LAMBDA_EXPRESSION_ARGUMENTS, "Only one lambda expression is allowed outside a parenthesized argument list")
|
||||
map.put(SPREAD_OF_NULLABLE, "The spread operator (*foo) may not be applied to an argument of nullable type")
|
||||
|
||||
map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING)
|
||||
map.put(THROWABLE_TYPE_MISMATCH, "Throwable type mismatch: actual type is {0}", TO_STRING)
|
||||
|
||||
+13
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.lexer.KtTokens.VISIBILITY_MODIFIERS
|
||||
import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStringTemplateExpressionElementType
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtValueArgumentElementType
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtValueArgumentListElementType
|
||||
|
||||
object LightTreePositioningStrategies {
|
||||
val DEFAULT = object : LightTreePositioningStrategy() {
|
||||
@@ -780,6 +782,17 @@ object LightTreePositioningStrategies {
|
||||
return markElement(nodeToMark, startOffset, endOffset, tree, node)
|
||||
}
|
||||
}
|
||||
|
||||
val SPREAD_OPERATOR: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
): List<TextRange> {
|
||||
return super.mark(node, startOffset, startOffset + 1, tree)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun FirSourceElement.hasValOrVar(): Boolean =
|
||||
|
||||
+5
@@ -262,4 +262,9 @@ object SourceElementPositioningStrategies {
|
||||
LightTreePositioningStrategies.IMPORT_LAST_NAME,
|
||||
PositioningStrategies.IMPORT_LAST_NAME
|
||||
)
|
||||
|
||||
val SPREAD_OPERATOR = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SPREAD_OPERATOR,
|
||||
PositioningStrategies.SPREAD_OPERATOR
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user