FIR: check multiple vararg param and forbidden vararg type
This commit is contained in:
committed by
Mikhail Glukhikh
parent
0e9474342d
commit
bdeecfc188
+4
@@ -292,6 +292,10 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
|||||||
// TODO: val ANONYMOUS_FUNCTION_WITH_NAME by error1<FirSourceElement, PsiElement, Name>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
// TODO: val ANONYMOUS_FUNCTION_WITH_NAME by error1<FirSourceElement, PsiElement, Name>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
val ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE by error<FirSourceElement, KtParameter>(PositioningStrategy.PARAMETER_DEFAULT_VALUE)
|
val ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE by error<FirSourceElement, KtParameter>(PositioningStrategy.PARAMETER_DEFAULT_VALUE)
|
||||||
val USELESS_VARARG_ON_PARAMETER by warning<FirSourceElement, KtParameter>()
|
val USELESS_VARARG_ON_PARAMETER by warning<FirSourceElement, KtParameter>()
|
||||||
|
val MULTIPLE_VARARG_PARAMETERS by error<FirSourceElement, KtParameter>(PositioningStrategy.PARAMETER_VARARG_MODIFIER)
|
||||||
|
val FORBIDDEN_VARARG_PARAMETER_TYPE by error<FirSourceElement, KtParameter>(PositioningStrategy.PARAMETER_VARARG_MODIFIER) {
|
||||||
|
parameter<ConeKotlinType>("varargParameterType")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val PROPERTIES_AND_ACCESSORS by object : DiagnosticGroup("Properties & accessors") {
|
val PROPERTIES_AND_ACCESSORS by object : DiagnosticGroup("Properties & accessors") {
|
||||||
|
|||||||
@@ -198,6 +198,8 @@ object FirErrors {
|
|||||||
val FUNCTION_DECLARATION_WITH_NO_NAME by error0<FirSourceElement, KtFunction>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
val FUNCTION_DECLARATION_WITH_NO_NAME by error0<FirSourceElement, KtFunction>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
val ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE by error0<FirSourceElement, KtParameter>(SourceElementPositioningStrategies.PARAMETER_DEFAULT_VALUE)
|
val ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE by error0<FirSourceElement, KtParameter>(SourceElementPositioningStrategies.PARAMETER_DEFAULT_VALUE)
|
||||||
val USELESS_VARARG_ON_PARAMETER by warning0<FirSourceElement, KtParameter>()
|
val USELESS_VARARG_ON_PARAMETER by warning0<FirSourceElement, KtParameter>()
|
||||||
|
val MULTIPLE_VARARG_PARAMETERS by error0<FirSourceElement, KtParameter>(SourceElementPositioningStrategies.PARAMETER_VARARG_MODIFIER)
|
||||||
|
val FORBIDDEN_VARARG_PARAMETER_TYPE by error1<FirSourceElement, KtParameter, ConeKotlinType>(SourceElementPositioningStrategies.PARAMETER_VARARG_MODIFIER)
|
||||||
|
|
||||||
// Properties & accessors
|
// Properties & accessors
|
||||||
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<FirSourceElement, KtModifierListOwner, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
|
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<FirSourceElement, KtModifierListOwner, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
|
||||||
|
|||||||
@@ -121,9 +121,11 @@ fun ConeClassLikeType.toRegularClass(session: FirSession): FirRegularClass? {
|
|||||||
* or null of something goes wrong.
|
* or null of something goes wrong.
|
||||||
*/
|
*/
|
||||||
fun ConeKotlinType.toRegularClass(session: FirSession): FirRegularClass? {
|
fun ConeKotlinType.toRegularClass(session: FirSession): FirRegularClass? {
|
||||||
return safeAs<ConeClassLikeType>()?.toRegularClass(session)
|
return safeAs<ConeClassLikeType>()?.fullyExpandedType(session)?.toRegularClass(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ConeKotlinType.isInline(session: FirSession) : Boolean = toRegularClass(session)?.isInline == true
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the FirRegularClass associated with this
|
* Returns the FirRegularClass associated with this
|
||||||
* or null of something goes wrong.
|
* or null of something goes wrong.
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.declaration
|
||||||
|
|
||||||
|
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.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
|
import org.jetbrains.kotlin.fir.types.arrayElementType
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
import org.jetbrains.kotlin.fir.types.isUnsignedTypeOrNullableUnsignedType
|
||||||
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
|
|
||||||
|
object FirFunctionParameterChecker : FirFunctionChecker() {
|
||||||
|
override fun check(declaration: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
checkVarargParameters(declaration, context, reporter)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkVarargParameters(function: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
val varargParameters = function.valueParameters.filter { it.isVararg }
|
||||||
|
if (varargParameters.size > 1) {
|
||||||
|
for (parameter in varargParameters) {
|
||||||
|
reporter.reportOn(parameter.source ?: continue, FirErrors.MULTIPLE_VARARG_PARAMETERS, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val nullableNothingType = context.session.builtinTypes.nullableNothingType.coneType
|
||||||
|
for (varargParameter in varargParameters) {
|
||||||
|
val varargParameterType = varargParameter.returnTypeRef.coneType.arrayElementType() ?: continue
|
||||||
|
if (AbstractTypeChecker.isSubtypeOf(context.session.typeContext, varargParameterType, nullableNothingType) ||
|
||||||
|
(varargParameterType.isInline(context.session) && !varargParameterType.isUnsignedTypeOrNullableUnsignedType)
|
||||||
|
// Note: comparing with FE1.0, we skip checking if the type is not primitive because primitive types are not inline. That
|
||||||
|
// is any primitive values are already allowed by the inline check.
|
||||||
|
) {
|
||||||
|
reporter.reportOn(
|
||||||
|
varargParameter.source ?: continue,
|
||||||
|
FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE,
|
||||||
|
varargParameterType,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -75,6 +75,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_INT
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.GENERIC_THROWABLE_SUBCLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.GENERIC_THROWABLE_SUBCLASS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN
|
||||||
@@ -97,6 +98,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_INTERFACE_N
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_OBJECT_NOT_ALLOWED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_OBJECT_NOT_ALLOWED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_COMPANION_OBJECTS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_COMPANION_OBJECTS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_PARAMETERS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NONE_APPLICABLE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NONE_APPLICABLE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_IN_FINAL_CLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_IN_FINAL_CLASS
|
||||||
@@ -444,6 +446,8 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
"An anonymous function is not allowed to specify default values for its parameters"
|
"An anonymous function is not allowed to specify default values for its parameters"
|
||||||
)
|
)
|
||||||
map.put(USELESS_VARARG_ON_PARAMETER, "Vararg on this parameter is useless")
|
map.put(USELESS_VARARG_ON_PARAMETER, "Vararg on this parameter is useless")
|
||||||
|
map.put(MULTIPLE_VARARG_PARAMETERS, "Multiple vararg-parameters are prohibited")
|
||||||
|
map.put(FORBIDDEN_VARARG_PARAMETER_TYPE, "Forbidden vararg parameter type: {0}", RENDER_TYPE)
|
||||||
|
|
||||||
// Properties & accessors
|
// Properties & accessors
|
||||||
map.put(
|
map.put(
|
||||||
|
|||||||
@@ -69,9 +69,15 @@ val ConeKotlinType.isArrayType: Boolean
|
|||||||
return isBuiltinType(StandardClassIds.Array, false) ||
|
return isBuiltinType(StandardClassIds.Array, false) ||
|
||||||
StandardClassIds.primitiveArrayTypeByElementType.values.any { isBuiltinType(it, false) }
|
StandardClassIds.primitiveArrayTypeByElementType.values.any { isBuiltinType(it, false) }
|
||||||
}
|
}
|
||||||
|
private val builtinUnsignedTypes = setOf(StandardClassIds.UInt, StandardClassIds.UByte, StandardClassIds.ULong, StandardClassIds.UShort)
|
||||||
|
val ConeKotlinType.isUnsignedTypeOrNullableUnsignedType: Boolean get() = isAnyOfBuiltinType(builtinUnsignedTypes)
|
||||||
|
|
||||||
private fun ConeKotlinType.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean {
|
private fun ConeKotlinType.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean {
|
||||||
|
|
||||||
if (this !is ConeClassLikeType) return false
|
if (this !is ConeClassLikeType) return false
|
||||||
return lookupTag.classId == classId && type.isNullable == isNullable
|
return lookupTag.classId == classId && type.isNullable == isNullable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ConeKotlinType.isAnyOfBuiltinType(classIds: Set<ClassId>): Boolean {
|
||||||
|
if (this !is ConeClassLikeType) return false
|
||||||
|
return lookupTag.classId in classIds
|
||||||
|
}
|
||||||
|
|||||||
+1
@@ -29,6 +29,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
override val functionCheckers: Set<FirFunctionChecker> = setOf(
|
override val functionCheckers: Set<FirFunctionChecker> = setOf(
|
||||||
FirContractChecker,
|
FirContractChecker,
|
||||||
FirFunctionNameChecker,
|
FirFunctionNameChecker,
|
||||||
|
FirFunctionParameterChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val propertyCheckers: Set<FirPropertyChecker> = setOf(
|
override val propertyCheckers: Set<FirPropertyChecker> = setOf(
|
||||||
|
|||||||
+5
-5
@@ -63,11 +63,11 @@ annotation class InAnn10(val p1: <!NULLABLE_TYPE_OF_ANNOTATION_MEMBER!>String?<!
|
|||||||
annotation class InAnn11(val p1: <!NULLABLE_TYPE_OF_ANNOTATION_MEMBER!>Ann1?<!>)
|
annotation class InAnn11(val p1: <!NULLABLE_TYPE_OF_ANNOTATION_MEMBER!>Ann1?<!>)
|
||||||
annotation class InAnn12(val p1: <!NULLABLE_TYPE_OF_ANNOTATION_MEMBER!>MyEnum?<!>)
|
annotation class InAnn12(val p1: <!NULLABLE_TYPE_OF_ANNOTATION_MEMBER!>MyEnum?<!>)
|
||||||
|
|
||||||
annotation class InAnn13(vararg val p1: String,
|
annotation class InAnn13(<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> val p1: String,
|
||||||
vararg val p2: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>Class<*><!>,
|
<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> val p2: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>Class<*><!>,
|
||||||
vararg val p3: MyEnum,
|
<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> val p3: MyEnum,
|
||||||
vararg val p4: Ann1,
|
<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> val p4: Ann1,
|
||||||
vararg val p5: Int)
|
<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> val p5: Int)
|
||||||
|
|
||||||
enum class MyEnum {
|
enum class MyEnum {
|
||||||
A
|
A
|
||||||
|
|||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED
|
|
||||||
fun test(vararg x1: Int, vararg x2: Int) {
|
|
||||||
fun test2(vararg x1: Int, vararg x2: Int) {
|
|
||||||
class LocalClass(vararg x1: Int, vararg x2: Int) {
|
|
||||||
constructor(vararg x1: Int, vararg x2: Int, xx: Int) {}
|
|
||||||
}
|
|
||||||
fun test3(vararg x1: Int, vararg x2: Int) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Any.test(vararg x1: Int, vararg x2: Int, vararg x3: Int) {}
|
|
||||||
|
|
||||||
interface I {
|
|
||||||
fun test(vararg x1: Int, vararg x2: Int)
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class C(vararg x1: Int, vararg x2: Int, b: Boolean) {
|
|
||||||
fun test(vararg x1: Int, vararg x2: Int) {}
|
|
||||||
|
|
||||||
abstract fun test2(vararg x1: Int, vararg x2: Int)
|
|
||||||
|
|
||||||
class CC(vararg x1: Int, vararg x2: Int, b: Boolean) {
|
|
||||||
constructor(vararg x1: Int, vararg x2: Int) {}
|
|
||||||
fun test(vararg x1: Int, vararg x2: Int) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object O {
|
|
||||||
fun test(vararg x1: Int, vararg x2: Int) {}
|
|
||||||
|
|
||||||
class CC(vararg x1: Int, vararg x2: Int, b: Boolean) {
|
|
||||||
constructor(vararg x1: Int, vararg x2: Int) {}
|
|
||||||
fun test(vararg x1: Int, vararg x2: Int) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED
|
||||||
fun test(<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> x1: Int, <!MULTIPLE_VARARG_PARAMETERS!>vararg<!> x2: Int) {
|
fun test(<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> x1: Int, <!MULTIPLE_VARARG_PARAMETERS!>vararg<!> x2: Int) {
|
||||||
fun test2(<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> x1: Int, <!MULTIPLE_VARARG_PARAMETERS!>vararg<!> x2: Int) {
|
fun test2(<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> x1: Int, <!MULTIPLE_VARARG_PARAMETERS!>vararg<!> x2: Int) {
|
||||||
|
|||||||
+4
-4
@@ -2,11 +2,11 @@ fun f(
|
|||||||
val a: Int,
|
val a: Int,
|
||||||
var b: Int,
|
var b: Int,
|
||||||
c: Int,
|
c: Int,
|
||||||
vararg var d: Int,
|
<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> var d: Int,
|
||||||
vararg val e: Int,
|
<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> val e: Int,
|
||||||
vararg f: Int
|
<!MULTIPLE_VARARG_PARAMETERS!>vararg<!> f: Int
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
a + b + c + d[0] + e[0] + f[0] // to avoid 'unused parameter'
|
a + b + c + d[0] + e[0] + f[0] // to avoid 'unused parameter'
|
||||||
}
|
}
|
||||||
|
|||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
|
||||||
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
inline class MyInt(val x: Int)
|
|
||||||
inline class MyString(val x: String)
|
|
||||||
|
|
||||||
annotation class Ann1(val a: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>MyInt<!>)
|
|
||||||
annotation class Ann2(val a: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>Array<MyString><!>)
|
|
||||||
annotation class Ann3(vararg val a: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>MyInt<!>)
|
|
||||||
|
|
||||||
annotation class Ann4(val a: KClass<MyInt>)
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|||||||
Vendored
+7
-7
@@ -3,19 +3,19 @@
|
|||||||
|
|
||||||
inline class Foo(val x: Int)
|
inline class Foo(val x: Int)
|
||||||
|
|
||||||
fun f1(vararg a: Foo) {}
|
fun f1(<!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> a: Foo) {}
|
||||||
fun f2(vararg a: Foo?) {}
|
fun f2(<!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> a: Foo?) {}
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
fun f3(a0: Int, vararg a1: Foo) {
|
fun f3(a0: Int, <!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> a1: Foo) {
|
||||||
fun f4(vararg a: Foo) {}
|
fun f4(<!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> a: Foo) {}
|
||||||
|
|
||||||
val g = fun (<!USELESS_VARARG_ON_PARAMETER!>vararg v: Foo<!>) {}
|
val g = fun (<!USELESS_VARARG_ON_PARAMETER!>vararg v: Foo<!>) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class B(vararg val s: Foo) {
|
class B(<!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> val s: Foo) {
|
||||||
constructor(a: Int, vararg s: Foo) : this(*s)
|
constructor(a: Int, <!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> s: Foo) : this(*s)
|
||||||
}
|
}
|
||||||
|
|
||||||
annotation class Ann(vararg val f: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>Foo<!>)
|
annotation class Ann(<!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> val f: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>Foo<!>)
|
||||||
|
|||||||
+1
-1
@@ -9,4 +9,4 @@ class ValueParam(vararg val a: ULong)
|
|||||||
|
|
||||||
annotation class Ann(vararg val a: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>UInt<!>)
|
annotation class Ann(vararg val a: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>UInt<!>)
|
||||||
|
|
||||||
fun array(vararg a: UIntArray) {}
|
fun array(<!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> a: UIntArray) {}
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
|
||||||
|
|
||||||
fun testVarargOfNothing(vararg v: Nothing) {}
|
|
||||||
|
|
||||||
fun testVarargOfNNothing(vararg v: Nothing?) {}
|
|
||||||
|
|
||||||
fun <T : Nothing?> testVarargOfT(vararg v: T) {}
|
|
||||||
|
|
||||||
fun outer() {
|
|
||||||
fun testVarargOfNothing(vararg v: Nothing) {}
|
|
||||||
|
|
||||||
fun testVarargOfNNothing(vararg v: Nothing?) {}
|
|
||||||
|
|
||||||
fun <T : Nothing?> testVarargOfT(vararg v: T) {}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
fun testVarargOfNothing(<!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> v: Nothing) {}
|
fun testVarargOfNothing(<!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> v: Nothing) {}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -11,7 +11,7 @@ fun params(
|
|||||||
r3: ResultAlias<String>,
|
r3: ResultAlias<String>,
|
||||||
r4: List<Result<Int>>,
|
r4: List<Result<Int>>,
|
||||||
r5: InlineResult<Int>,
|
r5: InlineResult<Int>,
|
||||||
vararg r6: Result<Int>
|
<!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> r6: Result<Int>
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
class CtorParams(r1: Result<Int>)
|
class CtorParams(r1: Result<Int>)
|
||||||
|
|||||||
Vendored
+1
-1
@@ -11,7 +11,7 @@ fun params(
|
|||||||
r3: ResultAlias<String>,
|
r3: ResultAlias<String>,
|
||||||
r4: List<Result<Int>>,
|
r4: List<Result<Int>>,
|
||||||
r5: InlineResult<Int>,
|
r5: InlineResult<Int>,
|
||||||
vararg r6: Result<Int>
|
<!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> r6: Result<Int>
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
class CtorParams(r1: Result<Int>)
|
class CtorParams(r1: Result<Int>)
|
||||||
|
|||||||
+13
@@ -840,6 +840,19 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.MULTIPLE_VARARG_PARAMETERS) { firDiagnostic ->
|
||||||
|
MultipleVarargParametersImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE) { firDiagnostic ->
|
||||||
|
ForbiddenVarargParameterTypeImpl(
|
||||||
|
firSymbolBuilder.buildKtType(firDiagnostic.a),
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS) { firDiagnostic ->
|
add(FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS) { firDiagnostic ->
|
||||||
AbstractPropertyInNonAbstractClassImpl(
|
AbstractPropertyInNonAbstractClassImpl(
|
||||||
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration),
|
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration),
|
||||||
|
|||||||
+9
@@ -594,6 +594,15 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = UselessVarargOnParameter::class
|
override val diagnosticClass get() = UselessVarargOnParameter::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class MultipleVarargParameters : KtFirDiagnostic<KtParameter>() {
|
||||||
|
override val diagnosticClass get() = MultipleVarargParameters::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ForbiddenVarargParameterType : KtFirDiagnostic<KtParameter>() {
|
||||||
|
override val diagnosticClass get() = ForbiddenVarargParameterType::class
|
||||||
|
abstract val varargParameterType: KtType
|
||||||
|
}
|
||||||
|
|
||||||
abstract class AbstractPropertyInNonAbstractClass : KtFirDiagnostic<KtModifierListOwner>() {
|
abstract class AbstractPropertyInNonAbstractClass : KtFirDiagnostic<KtModifierListOwner>() {
|
||||||
override val diagnosticClass get() = AbstractPropertyInNonAbstractClass::class
|
override val diagnosticClass get() = AbstractPropertyInNonAbstractClass::class
|
||||||
abstract val property: KtSymbol
|
abstract val property: KtSymbol
|
||||||
|
|||||||
+15
@@ -952,6 +952,21 @@ internal class UselessVarargOnParameterImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class MultipleVarargParametersImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.MultipleVarargParameters(), KtAbstractFirDiagnostic<KtParameter> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ForbiddenVarargParameterTypeImpl(
|
||||||
|
override val varargParameterType: KtType,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ForbiddenVarargParameterType(), KtAbstractFirDiagnostic<KtParameter> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class AbstractPropertyInNonAbstractClassImpl(
|
internal class AbstractPropertyInNonAbstractClassImpl(
|
||||||
override val property: KtSymbol,
|
override val property: KtSymbol,
|
||||||
override val containingClass: KtSymbol,
|
override val containingClass: KtSymbol,
|
||||||
|
|||||||
Reference in New Issue
Block a user