FIR checker: Report VAL_OR_VAR_ON_*_PARAMETER.
This commit is contained in:
committed by
teamcityserver
parent
71c5c9f6c5
commit
af99ad0736
+1
-1
@@ -1,5 +1,5 @@
|
||||
fun test(
|
||||
val f: String.() -> Int = { length }
|
||||
f: String.() -> Int = { length }
|
||||
): Int {
|
||||
return "".f()
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,5 +3,5 @@ interface <!CONSTRUCTOR_IN_INTERFACE!>A(val s: String)<!>
|
||||
interface <!CONSTRUCTOR_IN_INTERFACE!>B constructor(val s: String)<!>
|
||||
|
||||
interface C {
|
||||
<!CONSTRUCTOR_IN_INTERFACE!>constructor(val s: String)<!> {}
|
||||
<!CONSTRUCTOR_IN_INTERFACE!>constructor(s: String)<!> {}
|
||||
}
|
||||
|
||||
+13
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -69,6 +70,18 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val FLOAT_LITERAL_OUT_OF_RANGE by error<PsiElement>()
|
||||
val WRONG_LONG_SUFFIX by error<KtElement>(PositioningStrategy.LONG_LITERAL_SUFFIX)
|
||||
val DIVISION_BY_ZERO by warning<KtExpression>()
|
||||
val VAL_OR_VAR_ON_LOOP_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
||||
parameter<KtKeywordToken>("valOrVar")
|
||||
}
|
||||
val VAL_OR_VAR_ON_FUN_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
||||
parameter<KtKeywordToken>("valOrVar")
|
||||
}
|
||||
val VAL_OR_VAR_ON_CATCH_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
||||
parameter<KtKeywordToken>("valOrVar")
|
||||
}
|
||||
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
||||
parameter<KtKeywordToken>("valOrVar")
|
||||
}
|
||||
}
|
||||
|
||||
val UNRESOLVED by object : DiagnosticGroup("Unresolved") {
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotation
|
||||
@@ -100,6 +101,10 @@ object FirErrors {
|
||||
val FLOAT_LITERAL_OUT_OF_RANGE by error0<PsiElement>()
|
||||
val WRONG_LONG_SUFFIX by error0<KtElement>(SourceElementPositioningStrategies.LONG_LITERAL_SUFFIX)
|
||||
val DIVISION_BY_ZERO by warning0<KtExpression>()
|
||||
val VAL_OR_VAR_ON_LOOP_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
val VAL_OR_VAR_ON_FUN_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
val VAL_OR_VAR_ON_CATCH_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
|
||||
// Unresolved
|
||||
val INVISIBLE_REFERENCE by error1<PsiElement, AbstractFirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
+10
@@ -11,10 +11,13 @@ import com.intellij.psi.tree.TokenSet
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.valOrVarKeyword
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtModifierList
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.psi.KtValVarKeywordOwner
|
||||
|
||||
// DO
|
||||
// - use this to retrieve modifiers on the source and confirm a certain modifier indeed appears
|
||||
@@ -96,3 +99,10 @@ operator fun FirModifierList?.contains(token: KtModifierKeywordToken): Boolean =
|
||||
fun FirElement.getModifier(token: KtModifierKeywordToken): FirModifier<*>? = source.getModifierList()?.get(token)
|
||||
|
||||
fun FirElement.hasModifier(token: KtModifierKeywordToken): Boolean = token in source.getModifierList()
|
||||
|
||||
internal val FirSourceElement?.valOrVarKeyword: KtKeywordToken?
|
||||
get() = when (this) {
|
||||
null -> null
|
||||
is FirPsiSourceElement<*> -> (psi as? KtValVarKeywordOwner)?.valOrVarKeyword?.let { it.node?.elementType as? KtKeywordToken }
|
||||
is FirLightSourceElement -> treeStructure.valOrVarKeyword(lighterASTNode)?.tokenType as? KtKeywordToken
|
||||
}
|
||||
+26
-5
@@ -6,12 +6,13 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirRealSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isInline
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOnWithSuppression
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.valOrVarKeyword
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
@@ -31,10 +32,11 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
|
||||
checkVarargParameters(declaration, context, reporter)
|
||||
checkParameterTypes(declaration, context, reporter)
|
||||
checkUninitializedParameter(declaration, context, reporter)
|
||||
checkValOrVarParameter(declaration, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkParameterTypes(declaration: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (valueParameter in declaration.valueParameters) {
|
||||
private fun checkParameterTypes(function: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (valueParameter in function.valueParameters) {
|
||||
val returnTypeRef = valueParameter.returnTypeRef
|
||||
if (returnTypeRef !is FirErrorTypeRef) continue
|
||||
// type problems on real source are already reported by ConeDiagnostic.toFirDiagnostics
|
||||
@@ -105,4 +107,23 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkValOrVarParameter(function: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (function is FirConstructor && function.isPrimary) {
|
||||
// `val/var` is valid for primary constructors, but not for secondary constructors
|
||||
return
|
||||
}
|
||||
|
||||
for (valueParameter in function.valueParameters) {
|
||||
val source = valueParameter.source
|
||||
if (source?.kind is FirFakeSourceElementKind) continue
|
||||
source.valOrVarKeyword?.let {
|
||||
if (function is FirConstructor) {
|
||||
reporter.reportOn(source, FirErrors.VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER, it, context)
|
||||
} else {
|
||||
reporter.reportOn(source, FirErrors.VAL_OR_VAR_ON_FUN_PARAMETER, it, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-4
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isSubtypeOfThrowable
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.valOrVarKeyword
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
@@ -18,9 +19,14 @@ object FirCatchParameterChecker : FirTryExpressionChecker() {
|
||||
override fun check(expression: FirTryExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (catchEntry in expression.catches) {
|
||||
val catchParameter = catchEntry.parameter
|
||||
val source = catchParameter.source ?: continue
|
||||
|
||||
if (catchParameter.defaultValue != null) {
|
||||
reporter.reportOn(catchParameter.source, FirErrors.CATCH_PARAMETER_WITH_DEFAULT_VALUE, context)
|
||||
reporter.reportOn(source, FirErrors.CATCH_PARAMETER_WITH_DEFAULT_VALUE, context)
|
||||
}
|
||||
|
||||
source.valOrVarKeyword?.let {
|
||||
reporter.reportOn(source, FirErrors.VAL_OR_VAR_ON_CATCH_PARAMETER, it, context)
|
||||
}
|
||||
|
||||
val coneType = catchParameter.returnTypeRef.coneType
|
||||
@@ -28,15 +34,15 @@ object FirCatchParameterChecker : FirTryExpressionChecker() {
|
||||
val isReified = coneType.lookupTag.typeParameterSymbol.fir.isReified
|
||||
|
||||
if (isReified) {
|
||||
reporter.reportOn(catchParameter.source, FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE, context)
|
||||
reporter.reportOn(source, FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE, context)
|
||||
} else {
|
||||
reporter.reportOn(catchParameter.source, FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE, context)
|
||||
reporter.reportOn(source, FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE, context)
|
||||
}
|
||||
}
|
||||
|
||||
val session = context.session
|
||||
if (!coneType.isSubtypeOfThrowable(session)) {
|
||||
reporter.reportOn(catchParameter.source, FirErrors.THROWABLE_TYPE_MISMATCH, coneType, context)
|
||||
reporter.reportOn(source, FirErrors.THROWABLE_TYPE_MISMATCH, coneType, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-3
@@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.valOrVarKeyword
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HAS_NEXT_FUNCTION_AMBIGUITY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HAS_NEXT_FUNCTION_NONE_APPLICABLE
|
||||
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
object FirForLoopChecker : FirBlockChecker() {
|
||||
override fun check(expression: FirBlock, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (expression.source?.kind != FirFakeSourceElementKind.DesugaredForLoop) return
|
||||
|
||||
val statements = expression.statements
|
||||
val iteratorDeclaration = statements[0] as? FirProperty ?: return
|
||||
val whileLoop = statements[1] as? FirWhileLoop ?: return
|
||||
@@ -57,6 +59,7 @@ object FirForLoopChecker : FirBlockChecker() {
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
val hasNextCall = whileLoop.condition as FirFunctionCall
|
||||
checkSpecialFunctionCall(
|
||||
hasNextCall,
|
||||
@@ -67,9 +70,10 @@ object FirForLoopChecker : FirBlockChecker() {
|
||||
HAS_NEXT_MISSING,
|
||||
noneApplicableFactory = HAS_NEXT_FUNCTION_NONE_APPLICABLE
|
||||
)
|
||||
val elementDeclaration = whileLoop.block.statements.firstOrNull() as? FirProperty ?: return
|
||||
if (elementDeclaration.initializer?.source?.kind != FirFakeSourceElementKind.DesugaredForLoop) return
|
||||
val nextCall = elementDeclaration.initializer as FirFunctionCall
|
||||
|
||||
val loopParameter = whileLoop.block.statements.firstOrNull() as? FirProperty ?: return
|
||||
if (loopParameter.initializer?.source?.kind != FirFakeSourceElementKind.DesugaredForLoop) return
|
||||
val nextCall = loopParameter.initializer as FirFunctionCall
|
||||
checkSpecialFunctionCall(
|
||||
nextCall,
|
||||
reporter,
|
||||
@@ -79,6 +83,11 @@ object FirForLoopChecker : FirBlockChecker() {
|
||||
NEXT_MISSING,
|
||||
noneApplicableFactory = NEXT_NONE_APPLICABLE
|
||||
)
|
||||
|
||||
val loopParameterSource = loopParameter.source
|
||||
loopParameterSource.valOrVarKeyword?.let {
|
||||
reporter.reportOn(loopParameterSource, FirErrors.VAL_OR_VAR_ON_LOOP_PARAMETER, it, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSpecialFunctionCall(
|
||||
|
||||
+8
@@ -328,6 +328,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_IS_CHECK
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_CATCH_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_FUN_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_LOOP_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR
|
||||
@@ -384,6 +388,10 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
map.put(VARIABLE_EXPECTED, "Variable expected")
|
||||
map.put(DELEGATION_IN_INTERFACE, "Interfaces cannot use delegation")
|
||||
map.put(NESTED_CLASS_NOT_ALLOWED, "{0} is not allowed here", TO_STRING)
|
||||
map.put(VAL_OR_VAR_ON_LOOP_PARAMETER, "''{0}'' on loop parameter is not allowed", TO_STRING);
|
||||
map.put(VAL_OR_VAR_ON_FUN_PARAMETER, "''{0}'' on function parameter is not allowed", TO_STRING);
|
||||
map.put(VAL_OR_VAR_ON_CATCH_PARAMETER, "''{0}'' on catch parameter is not allowed", TO_STRING);
|
||||
map.put(VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER, "''{0}'' on secondary constructor parameter is not allowed", TO_STRING);
|
||||
|
||||
// Unresolved
|
||||
map.put(INVISIBLE_REFERENCE, "Symbol {0} is invisible", SYMBOL)
|
||||
|
||||
+2
-2
@@ -865,7 +865,7 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.rightParenthesis(node:
|
||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.objectKeyword(node: LighterASTNode): LighterASTNode? =
|
||||
findChildByType(node, KtTokens.OBJECT_KEYWORD)
|
||||
|
||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.valOrVarKeyword(node: LighterASTNode): LighterASTNode? =
|
||||
internal fun FlyweightCapableTreeStructure<LighterASTNode>.valOrVarKeyword(node: LighterASTNode): LighterASTNode? =
|
||||
findChildByType(node, VAL_VAR_TOKEN_SET)
|
||||
|
||||
internal fun FlyweightCapableTreeStructure<LighterASTNode>.visibilityModifier(declaration: LighterASTNode): LighterASTNode? =
|
||||
@@ -1021,7 +1021,7 @@ fun FlyweightCapableTreeStructure<LighterASTNode>.collectDescendantsOfType(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.findChildByType(node: LighterASTNode, type: TokenSet): LighterASTNode? {
|
||||
fun FlyweightCapableTreeStructure<LighterASTNode>.findChildByType(node: LighterASTNode, type: TokenSet): LighterASTNode? {
|
||||
val childrenRef = Ref<Array<LighterASTNode?>>()
|
||||
getChildren(node, childrenRef)
|
||||
return childrenRef.get()?.firstOrNull { it?.tokenType in type }
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
fun f() {
|
||||
try {
|
||||
} catch (val e: Exception) {
|
||||
}
|
||||
|
||||
try {
|
||||
} catch (var e: Exception) {
|
||||
}
|
||||
|
||||
try {
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
fun f() {
|
||||
try {
|
||||
} catch (<!VAL_OR_VAR_ON_CATCH_PARAMETER!>val<!> e: Exception) {
|
||||
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
class Pair {
|
||||
operator fun component1(): Int = null!!
|
||||
operator fun component2(): Int = null!!
|
||||
}
|
||||
|
||||
class Coll {
|
||||
operator fun iterator(): It = It()
|
||||
}
|
||||
|
||||
class It {
|
||||
operator fun next() = Pair()
|
||||
operator fun hasNext() = false
|
||||
}
|
||||
|
||||
|
||||
fun f() {
|
||||
for (val i in 1..4) {
|
||||
|
||||
}
|
||||
|
||||
for (var i in 1..4) {
|
||||
|
||||
}
|
||||
|
||||
for (val (i,j) in Coll()) {
|
||||
|
||||
}
|
||||
|
||||
for (var (i,j) in Coll()) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class Pair {
|
||||
operator fun component1(): Int = null!!
|
||||
operator fun component2(): Int = null!!
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
// KT-2667 Support multi-declarations in for-loops in control flow analysis
|
||||
package d
|
||||
|
||||
class A {
|
||||
operator fun component1() = 1
|
||||
operator fun component2() = 2
|
||||
operator fun component3() = 3
|
||||
}
|
||||
|
||||
fun foo(list: List<A>) {
|
||||
for (var (c1, c2, c3) in list) {
|
||||
<!VAL_REASSIGNMENT!>c1<!> = 1
|
||||
c3 + 1
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// KT-2667 Support multi-declarations in for-loops in control flow analysis
|
||||
package d
|
||||
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
fun f(
|
||||
val a: Int,
|
||||
var b: Int,
|
||||
c: Int,
|
||||
<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> var d: Int,
|
||||
<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> val e: Int,
|
||||
<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> f: Int
|
||||
) {
|
||||
|
||||
|
||||
a + b + c + d[0] + e[0] + f[0] // to avoid 'unused parameter'
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
fun f(
|
||||
<!VAL_OR_VAR_ON_FUN_PARAMETER!>val<!> a: Int,
|
||||
<!VAL_OR_VAR_ON_FUN_PARAMETER!>var<!> b: Int,
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
class A {
|
||||
constructor(
|
||||
val x: Int, y: Int,
|
||||
var z: Int,
|
||||
<!VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER!>val<!> x: Int, y: Int,
|
||||
<!VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER!>var<!> z: Int,
|
||||
public a: Int)
|
||||
}
|
||||
|
||||
+2
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
@@ -235,6 +236,7 @@ private object FirToKtConversionCreator {
|
||||
Int::class,
|
||||
Name::class,
|
||||
EventOccurrencesRange::class,
|
||||
KtKeywordToken::class,
|
||||
KtModifierKeywordToken::class,
|
||||
Visibility::class,
|
||||
EffectiveVisibility::class,
|
||||
|
||||
+28
@@ -194,6 +194,34 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.VAL_OR_VAR_ON_LOOP_PARAMETER) { firDiagnostic ->
|
||||
ValOrVarOnLoopParameterImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.VAL_OR_VAR_ON_FUN_PARAMETER) { firDiagnostic ->
|
||||
ValOrVarOnFunParameterImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.VAL_OR_VAR_ON_CATCH_PARAMETER) { firDiagnostic ->
|
||||
ValOrVarOnCatchParameterImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER) { firDiagnostic ->
|
||||
ValOrVarOnSecondaryConstructorParameterImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.INVISIBLE_REFERENCE) { firDiagnostic ->
|
||||
InvisibleReferenceImpl(
|
||||
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration),
|
||||
|
||||
+21
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableLikeSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotation
|
||||
@@ -157,6 +158,26 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = DivisionByZero::class
|
||||
}
|
||||
|
||||
abstract class ValOrVarOnLoopParameter : KtFirDiagnostic<KtParameter>() {
|
||||
override val diagnosticClass get() = ValOrVarOnLoopParameter::class
|
||||
abstract val valOrVar: KtKeywordToken
|
||||
}
|
||||
|
||||
abstract class ValOrVarOnFunParameter : KtFirDiagnostic<KtParameter>() {
|
||||
override val diagnosticClass get() = ValOrVarOnFunParameter::class
|
||||
abstract val valOrVar: KtKeywordToken
|
||||
}
|
||||
|
||||
abstract class ValOrVarOnCatchParameter : KtFirDiagnostic<KtParameter>() {
|
||||
override val diagnosticClass get() = ValOrVarOnCatchParameter::class
|
||||
abstract val valOrVar: KtKeywordToken
|
||||
}
|
||||
|
||||
abstract class ValOrVarOnSecondaryConstructorParameter : KtFirDiagnostic<KtParameter>() {
|
||||
override val diagnosticClass get() = ValOrVarOnSecondaryConstructorParameter::class
|
||||
abstract val valOrVar: KtKeywordToken
|
||||
}
|
||||
|
||||
abstract class InvisibleReference : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = InvisibleReference::class
|
||||
abstract val reference: KtSymbol
|
||||
|
||||
+33
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableLikeSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotation
|
||||
@@ -224,6 +225,38 @@ internal class DivisionByZeroImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ValOrVarOnLoopParameterImpl(
|
||||
override val valOrVar: KtKeywordToken,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.ValOrVarOnLoopParameter(), KtAbstractFirDiagnostic<KtParameter> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ValOrVarOnFunParameterImpl(
|
||||
override val valOrVar: KtKeywordToken,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.ValOrVarOnFunParameter(), KtAbstractFirDiagnostic<KtParameter> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ValOrVarOnCatchParameterImpl(
|
||||
override val valOrVar: KtKeywordToken,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.ValOrVarOnCatchParameter(), KtAbstractFirDiagnostic<KtParameter> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ValOrVarOnSecondaryConstructorParameterImpl(
|
||||
override val valOrVar: KtKeywordToken,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.ValOrVarOnSecondaryConstructorParameter(), KtAbstractFirDiagnostic<KtParameter> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class InvisibleReferenceImpl(
|
||||
override val reference: KtSymbol,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
|
||||
Reference in New Issue
Block a user