FIR: check NAMED_ARGUMENTS_NOT_ALLOWED
The check has already been partially implemented in org.jetbrains.kotlin.fir.resolve.calls.FirCallArgumentsProcessor. This change completes the missing piece that determines if a `FirFunction` has stable parameter names.
This commit is contained in:
committed by
Mikhail Glukhikh
parent
0d4e9ca0b9
commit
be0dd84a06
+6
@@ -10,6 +10,7 @@ import com.intellij.psi.PsiTypeElement
|
|||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
||||||
|
import org.jetbrains.kotlin.resolve.BadNamedArgumentsTarget
|
||||||
import org.jetbrains.kotlin.fir.FirEffectiveVisibility
|
import org.jetbrains.kotlin.fir.FirEffectiveVisibility
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
import org.jetbrains.kotlin.fir.PrivateForInline
|
||||||
@@ -197,6 +198,11 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val VARARG_OUTSIDE_PARENTHESES by error<FirSourceElement, KtExpression>()
|
val VARARG_OUTSIDE_PARENTHESES by error<FirSourceElement, KtExpression>()
|
||||||
|
|
||||||
|
// TODO: implement a position strategy that highlights the argument name instead of the whole named argument
|
||||||
|
val NAMED_ARGUMENTS_NOT_ALLOWED by error<FirSourceElement, PsiElement> {
|
||||||
|
parameter<BadNamedArgumentsTarget>("badNamedArgumentTarget")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val AMBIGUITY by object : DiagnosticGroup("Ambiguity") {
|
val AMBIGUITY by object : DiagnosticGroup("Ambiguity") {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.psi.KtTypeParameter
|
|||||||
import org.jetbrains.kotlin.psi.KtTypeParameterList
|
import org.jetbrains.kotlin.psi.KtTypeParameterList
|
||||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||||
import org.jetbrains.kotlin.psi.KtWhenExpression
|
import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.BadNamedArgumentsTarget
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file was generated automatically
|
* This file was generated automatically
|
||||||
@@ -167,6 +168,7 @@ object FirErrors {
|
|||||||
val INAPPLICABLE_CANDIDATE by error1<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val INAPPLICABLE_CANDIDATE by error1<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
val INAPPLICABLE_LATEINIT_MODIFIER by error1<FirSourceElement, KtModifierListOwner, String>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
val INAPPLICABLE_LATEINIT_MODIFIER by error1<FirSourceElement, KtModifierListOwner, String>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
||||||
val VARARG_OUTSIDE_PARENTHESES by error0<FirSourceElement, KtExpression>()
|
val VARARG_OUTSIDE_PARENTHESES by error0<FirSourceElement, KtExpression>()
|
||||||
|
val NAMED_ARGUMENTS_NOT_ALLOWED by error1<FirSourceElement, PsiElement, BadNamedArgumentsTarget>()
|
||||||
|
|
||||||
// Ambiguity
|
// Ambiguity
|
||||||
val AMBIGUITY by error1<FirSourceElement, PsiElement, Collection<AbstractFirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val AMBIGUITY by error1<FirSourceElement, PsiElement, Collection<AbstractFirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
|
|||||||
+2
@@ -119,6 +119,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NESTED_CLASS_NOT_
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_PARAMETERS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_PARAMETERS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAMED_ARGUMENTS_NOT_ALLOWED
|
||||||
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
|
||||||
@@ -353,6 +354,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
map.put(INAPPLICABLE_CANDIDATE, "Inapplicable candidate(s): {0}", SYMBOL)
|
map.put(INAPPLICABLE_CANDIDATE, "Inapplicable candidate(s): {0}", SYMBOL)
|
||||||
map.put(INAPPLICABLE_LATEINIT_MODIFIER, "''lateinit'' modifier {0}", TO_STRING)
|
map.put(INAPPLICABLE_LATEINIT_MODIFIER, "''lateinit'' modifier {0}", TO_STRING)
|
||||||
map.put(VARARG_OUTSIDE_PARENTHESES, "Passing value as a vararg is only allowed inside a parenthesized argument list")
|
map.put(VARARG_OUTSIDE_PARENTHESES, "Passing value as a vararg is only allowed inside a parenthesized argument list")
|
||||||
|
map.put(NAMED_ARGUMENTS_NOT_ALLOWED, "Named arguments are not allowed for {0}", TO_STRING)
|
||||||
|
|
||||||
// Ambiguity
|
// Ambiguity
|
||||||
map.put(AMBIGUITY, "Ambiguity between candidates: {0}", SYMBOLS)
|
map.put(AMBIGUITY, "Ambiguity between candidates: {0}", SYMBOLS)
|
||||||
|
|||||||
+5
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.isInfix
|
|||||||
import org.jetbrains.kotlin.fir.declarations.isOperator
|
import org.jetbrains.kotlin.fir.declarations.isOperator
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.*
|
import org.jetbrains.kotlin.fir.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.InapplicableWrongReceiver
|
import org.jetbrains.kotlin.fir.resolve.calls.InapplicableWrongReceiver
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.NamedArgumentNotAllowed
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionDiagnostic
|
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.VarargArgumentOutsideParentheses
|
import org.jetbrains.kotlin.fir.resolve.calls.VarargArgumentOutsideParentheses
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||||
@@ -115,6 +116,10 @@ private fun mapInapplicableCandidateError(
|
|||||||
|
|
||||||
when (rootCause) {
|
when (rootCause) {
|
||||||
is VarargArgumentOutsideParentheses -> FirErrors.VARARG_OUTSIDE_PARENTHESES.on(rootCause.argument.source ?: source)
|
is VarargArgumentOutsideParentheses -> FirErrors.VARARG_OUTSIDE_PARENTHESES.on(rootCause.argument.source ?: source)
|
||||||
|
is NamedArgumentNotAllowed -> FirErrors.NAMED_ARGUMENTS_NOT_ALLOWED.on(
|
||||||
|
rootCause.argument.source ?: source,
|
||||||
|
rootCause.badNamedArgumentsTarget
|
||||||
|
)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}.ifEmpty { listOf(FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)) }
|
}.ifEmpty { listOf(FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)) }
|
||||||
|
|||||||
@@ -22,9 +22,12 @@ import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.*
|
import org.jetbrains.kotlin.fir.resolve.providers.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
|
||||||
import org.jetbrains.kotlin.fir.symbols.*
|
import org.jetbrains.kotlin.fir.symbols.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
@@ -35,6 +38,7 @@ import org.jetbrains.kotlin.name.CallableId
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.BadNamedArgumentsTarget
|
||||||
|
|
||||||
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
|
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
|
||||||
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
|
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
|
||||||
@@ -349,3 +353,51 @@ fun BodyResolveComponents.initialTypeOfCandidate(candidate: Candidate): ConeKotl
|
|||||||
private fun initialTypeOfCandidate(candidate: Candidate, typeRef: FirResolvedTypeRef): ConeKotlinType {
|
private fun initialTypeOfCandidate(candidate: Candidate, typeRef: FirResolvedTypeRef): ConeKotlinType {
|
||||||
return candidate.substitutor.substituteOrSelf(typeRef.type)
|
return candidate.substitutor.substituteOrSelf(typeRef.type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline val FirCallableDeclaration<*>.containingClass: FirRegularClass?
|
||||||
|
get() = this.containingClassAttr?.let { lookupTag ->
|
||||||
|
session.symbolProvider.getSymbolByLookupTag(lookupTag)?.fir as? FirRegularClass
|
||||||
|
}
|
||||||
|
|
||||||
|
val FirFunction<*>.asBadForNamedArgumentTarget: BadNamedArgumentsTarget?
|
||||||
|
get() {
|
||||||
|
if (this is FirConstructor && this.isPrimary) {
|
||||||
|
this.containingClass?.let { containingClass ->
|
||||||
|
if (containingClass.classKind == ClassKind.ANNOTATION_CLASS) {
|
||||||
|
// Java annotation classes allow (actually require) named parameters.
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this is FirMemberDeclaration && status.isExpect) {
|
||||||
|
return BadNamedArgumentsTarget.EXPECTED_CLASS_MEMBER
|
||||||
|
}
|
||||||
|
return when (origin) {
|
||||||
|
FirDeclarationOrigin.Source, FirDeclarationOrigin.Library, FirDeclarationOrigin.BuiltIns -> null
|
||||||
|
FirDeclarationOrigin.Delegated -> delegatedWrapperData?.wrapped?.asBadForNamedArgumentTarget
|
||||||
|
FirDeclarationOrigin.ImportedFromObject -> importedFromObjectData?.original?.asBadForNamedArgumentTarget
|
||||||
|
// For intersection overrides, the logic in
|
||||||
|
// org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope#selectMostSpecificMember picks the most specific one and store
|
||||||
|
// it in originalForIntersectionOverrideAttr. This follows from FE1.0 behavior which selects the most specific function
|
||||||
|
// (org.jetbrains.kotlin.resolve.OverridingUtil#selectMostSpecificMember), from which the `hasStableParameterNames` status is
|
||||||
|
// copied.
|
||||||
|
FirDeclarationOrigin.IntersectionOverride -> originalForIntersectionOverrideAttr?.asBadForNamedArgumentTarget
|
||||||
|
FirDeclarationOrigin.Java, FirDeclarationOrigin.Enhancement -> BadNamedArgumentsTarget.NON_KOTLIN_FUNCTION
|
||||||
|
FirDeclarationOrigin.SamConstructor -> null
|
||||||
|
FirDeclarationOrigin.SubstitutionOverride -> originalForSubstitutionOverrideAttr?.asBadForNamedArgumentTarget
|
||||||
|
// referenced function of a Kotlin function type is synthetic
|
||||||
|
FirDeclarationOrigin.Synthetic -> {
|
||||||
|
if (dispatchReceiverClassOrNull()?.isBuiltinFunctionalType() == true) {
|
||||||
|
BadNamedArgumentsTarget.INVOKE_ON_FUNCTION_TYPE
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is FirDeclarationOrigin.Plugin -> null // TODO: figure out what to do with plugin generated functions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle functions with non-stable parameter names, see also
|
||||||
|
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.functionProto
|
||||||
|
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto
|
||||||
|
inline val FirFunction<*>.hasStableParameterNames: Boolean get() = asBadForNamedArgumentTarget == null
|
||||||
|
|||||||
+8
-10
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.resolve.BadNamedArgumentsTarget
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
@@ -15,11 +16,10 @@ import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression
|
import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.asBadForNamedArgumentTarget
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultParameterResolver
|
import org.jetbrains.kotlin.fir.resolve.defaultParameterResolver
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
import kotlin.collections.LinkedHashMap
|
|
||||||
import kotlin.collections.component1
|
import kotlin.collections.component1
|
||||||
import kotlin.collections.component2
|
import kotlin.collections.component2
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
@@ -108,6 +108,10 @@ private class FirCallArgumentsProcessor(
|
|||||||
private set
|
private set
|
||||||
val result: LinkedHashMap<FirValueParameter, ResolvedCallArgument> = LinkedHashMap(function.valueParameters.size)
|
val result: LinkedHashMap<FirValueParameter, ResolvedCallArgument> = LinkedHashMap(function.valueParameters.size)
|
||||||
|
|
||||||
|
val badForNamedArgumentTarget: BadNamedArgumentsTarget? by lazy {
|
||||||
|
function.asBadForNamedArgumentTarget
|
||||||
|
}
|
||||||
|
|
||||||
private enum class State {
|
private enum class State {
|
||||||
POSITION_ARGUMENTS,
|
POSITION_ARGUMENTS,
|
||||||
VARARG_POSITION,
|
VARARG_POSITION,
|
||||||
@@ -165,8 +169,8 @@ private class FirCallArgumentsProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processNamedArgument(argument: FirExpression, name: Name) {
|
private fun processNamedArgument(argument: FirExpression, name: Name) {
|
||||||
if (!function.hasStableParameterNames) {
|
badForNamedArgumentTarget?.let {
|
||||||
addDiagnostic(NamedArgumentNotAllowed(argument, function))
|
addDiagnostic(NamedArgumentNotAllowed(argument, function, it))
|
||||||
}
|
}
|
||||||
|
|
||||||
val stateAllowsMixedNamedAndPositionArguments = state != State.NAMED_ONLY_ARGUMENTS
|
val stateAllowsMixedNamedAndPositionArguments = state != State.NAMED_ONLY_ARGUMENTS
|
||||||
@@ -296,10 +300,4 @@ private class FirCallArgumentsProcessor(
|
|||||||
|
|
||||||
private val FirExpression.argumentName: Name?
|
private val FirExpression.argumentName: Name?
|
||||||
get() = (this as? FirNamedArgumentExpression)?.name
|
get() = (this as? FirNamedArgumentExpression)?.name
|
||||||
|
|
||||||
// TODO: handle functions with non-stable parameter names, see also
|
|
||||||
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.functionProto
|
|
||||||
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto
|
|
||||||
private val FirFunction<*>.hasStableParameterNames: Boolean
|
|
||||||
get() = true
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.resolve.BadNamedArgumentsTarget
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
@@ -26,7 +27,8 @@ class TooManyArguments(
|
|||||||
|
|
||||||
class NamedArgumentNotAllowed(
|
class NamedArgumentNotAllowed(
|
||||||
override val argument: FirExpression,
|
override val argument: FirExpression,
|
||||||
val function: FirFunction<*>
|
val function: FirFunction<*>,
|
||||||
|
val badNamedArgumentsTarget: BadNamedArgumentsTarget
|
||||||
) : InapplicableArgumentDiagnostic()
|
) : InapplicableArgumentDiagnostic()
|
||||||
|
|
||||||
class ArgumentPassedTwice(
|
class ArgumentPassedTwice(
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* 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.resolve
|
||||||
|
|
||||||
|
enum class BadNamedArgumentsTarget(private val description:String) {
|
||||||
|
NON_KOTLIN_FUNCTION("non-Kotlin functions"), // a function provided by non-Kotlin artifact, ex: Java function
|
||||||
|
INVOKE_ON_FUNCTION_TYPE("function types"),
|
||||||
|
EXPECTED_CLASS_MEMBER("members of expected classes"),
|
||||||
|
// TODO: add the following when MPP support is available
|
||||||
|
// INTEROP_FUNCTION("interop functions with ambiguous parameter names"), // deserialized Kotlin function that serves as a bridge to a function written in another language, ex: Obj-C
|
||||||
|
;
|
||||||
|
|
||||||
|
override fun toString(): String = description
|
||||||
|
}
|
||||||
@@ -7,5 +7,5 @@ class A(foo: Int.() -> Unit) {
|
|||||||
fun test(foo: Int.(String) -> Unit) {
|
fun test(foo: Int.(String) -> Unit) {
|
||||||
4.foo("")
|
4.foo("")
|
||||||
4.<!INAPPLICABLE_CANDIDATE!>foo<!>(p1 = "")
|
4.<!INAPPLICABLE_CANDIDATE!>foo<!>(p1 = "")
|
||||||
4.foo(p2 = "")
|
4.foo(<!NAMED_ARGUMENTS_NOT_ALLOWED!>p2 = ""<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ expect class Foo(zzz: Int) {
|
|||||||
expect fun f2(xxx: Int)
|
expect fun f2(xxx: Int)
|
||||||
|
|
||||||
fun testCommon() {
|
fun testCommon() {
|
||||||
Foo(zzz = 0)
|
Foo(<!NAMED_ARGUMENTS_NOT_ALLOWED!>zzz = 0<!>)
|
||||||
val f = Foo(aaa = true)
|
val f = Foo(<!NAMED_ARGUMENTS_NOT_ALLOWED!>aaa = true<!>)
|
||||||
f.f1(xxx = "")
|
f.f1(<!NAMED_ARGUMENTS_NOT_ALLOWED!>xxx = ""<!>)
|
||||||
f2(xxx = 42)
|
f2(<!NAMED_ARGUMENTS_NOT_ALLOWED!>xxx = 42<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MODULE: m2-jvm(m1-common)
|
// MODULE: m2-jvm(m1-common)
|
||||||
|
|||||||
+1
-1
@@ -6,4 +6,4 @@ public class A {
|
|||||||
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
val test = A(x = 1, y = "2")
|
val test = A(<!NAMED_ARGUMENTS_NOT_ALLOWED!>x = 1<!>, <!NAMED_ARGUMENTS_NOT_ALLOWED!>y = "2"<!>)
|
||||||
|
|||||||
+3
-3
@@ -8,11 +8,11 @@ public class JavaSuperClass {
|
|||||||
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
fun directInvocation() = JavaSuperClass().foo(javaName = 1)
|
fun directInvocation() = JavaSuperClass().foo(<!NAMED_ARGUMENTS_NOT_ALLOWED!>javaName = 1<!>)
|
||||||
|
|
||||||
open class KotlinSubClass : JavaSuperClass()
|
open class KotlinSubClass : JavaSuperClass()
|
||||||
|
|
||||||
fun viaFakeOverride() = KotlinSubClass().foo(javaName = 2)
|
fun viaFakeOverride() = KotlinSubClass().foo(<!NAMED_ARGUMENTS_NOT_ALLOWED!>javaName = 2<!>)
|
||||||
|
|
||||||
class KotlinSubSubClass : KotlinSubClass() {
|
class KotlinSubSubClass : KotlinSubClass() {
|
||||||
override fun foo(kotlinName: Int) {}
|
override fun foo(kotlinName: Int) {}
|
||||||
@@ -24,4 +24,4 @@ fun viaRealOverride() = KotlinSubSubClass().foo(kotlinName = 3)
|
|||||||
fun unresolvedParameter() = JavaSuperClass().<!INAPPLICABLE_CANDIDATE!>foo<!>(nonexistentName = 4)
|
fun unresolvedParameter() = JavaSuperClass().<!INAPPLICABLE_CANDIDATE!>foo<!>(nonexistentName = 4)
|
||||||
|
|
||||||
|
|
||||||
fun multipleParameters() = JavaSuperClass().multipleParameters(first = 1, second = 2L, third = "3")
|
fun multipleParameters() = JavaSuperClass().multipleParameters(<!NAMED_ARGUMENTS_NOT_ALLOWED!>first = 1<!>, <!NAMED_ARGUMENTS_NOT_ALLOWED!>second = 2L<!>, <!NAMED_ARGUMENTS_NOT_ALLOWED!>third = "3"<!>)
|
||||||
|
|||||||
+1
-1
@@ -13,5 +13,5 @@ public class J {
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
J("", r = { }, z = false)
|
J("", <!NAMED_ARGUMENTS_NOT_ALLOWED!>r = { }<!>, <!NAMED_ARGUMENTS_NOT_ALLOWED!>z = false<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -13,5 +13,5 @@ public class J {
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
J.foo("", r = { }, z = false)
|
J.foo("", <!NAMED_ARGUMENTS_NOT_ALLOWED!>r = { }<!>, <!NAMED_ARGUMENTS_NOT_ALLOWED!>z = false<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
// !WITH_NEW_INFERENCE
|
// !WITH_NEW_INFERENCE
|
||||||
// FILE: KotlinFile.kt
|
// FILE: KotlinFile.kt
|
||||||
fun foo(javaClass: JavaClass) {
|
fun foo(javaClass: JavaClass) {
|
||||||
javaClass.doSomething(p = 1) {
|
javaClass.doSomething(<!NAMED_ARGUMENTS_NOT_ALLOWED!>p = 1<!>) {
|
||||||
bar()
|
bar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,4 +11,4 @@ fun bar(){}
|
|||||||
// FILE: JavaClass.java
|
// FILE: JavaClass.java
|
||||||
public class JavaClass {
|
public class JavaClass {
|
||||||
public void doSomething(int p, Runnable runnable) { runnable.run(); }
|
public void doSomething(int p, Runnable runnable) { runnable.run(); }
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement
|
|||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
||||||
|
import org.jetbrains.kotlin.resolve.BadNamedArgumentsTarget
|
||||||
import org.jetbrains.kotlin.fir.FirEffectiveVisibility
|
import org.jetbrains.kotlin.fir.FirEffectiveVisibility
|
||||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.DiagnosticData
|
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.DiagnosticData
|
||||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.DiagnosticList
|
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.DiagnosticList
|
||||||
@@ -173,6 +174,7 @@ private object FirToKtConversionCreator {
|
|||||||
KtModifierKeywordToken::class,
|
KtModifierKeywordToken::class,
|
||||||
Visibility::class,
|
Visibility::class,
|
||||||
WhenMissingCase::class,
|
WhenMissingCase::class,
|
||||||
|
BadNamedArgumentsTarget::class,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val KType.kClass: KClass<*>
|
private val KType.kClass: KClass<*>
|
||||||
|
|||||||
+7
@@ -657,6 +657,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.NAMED_ARGUMENTS_NOT_ALLOWED) { firDiagnostic ->
|
||||||
|
NamedArgumentsNotAllowedImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.AMBIGUITY) { firDiagnostic ->
|
add(FirErrors.AMBIGUITY) { firDiagnostic ->
|
||||||
AmbiguityImpl(
|
AmbiguityImpl(
|
||||||
firDiagnostic.a.map { abstractFirBasedSymbol ->
|
firDiagnostic.a.map { abstractFirBasedSymbol ->
|
||||||
|
|||||||
+6
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.psi.KtTypeParameter
|
|||||||
import org.jetbrains.kotlin.psi.KtTypeParameterList
|
import org.jetbrains.kotlin.psi.KtTypeParameterList
|
||||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||||
import org.jetbrains.kotlin.psi.KtWhenExpression
|
import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.BadNamedArgumentsTarget
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file was generated automatically
|
* This file was generated automatically
|
||||||
@@ -469,6 +470,11 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = VarargOutsideParentheses::class
|
override val diagnosticClass get() = VarargOutsideParentheses::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class NamedArgumentsNotAllowed : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = NamedArgumentsNotAllowed::class
|
||||||
|
abstract val badNamedArgumentTarget: BadNamedArgumentsTarget
|
||||||
|
}
|
||||||
|
|
||||||
abstract class Ambiguity : KtFirDiagnostic<PsiElement>() {
|
abstract class Ambiguity : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = Ambiguity::class
|
override val diagnosticClass get() = Ambiguity::class
|
||||||
abstract val candidates: List<KtSymbol>
|
abstract val candidates: List<KtSymbol>
|
||||||
|
|||||||
+9
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.psi.KtTypeParameter
|
|||||||
import org.jetbrains.kotlin.psi.KtTypeParameterList
|
import org.jetbrains.kotlin.psi.KtTypeParameterList
|
||||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||||
import org.jetbrains.kotlin.psi.KtWhenExpression
|
import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.BadNamedArgumentsTarget
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file was generated automatically
|
* This file was generated automatically
|
||||||
@@ -755,6 +756,14 @@ internal class VarargOutsideParenthesesImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class NamedArgumentsNotAllowedImpl(
|
||||||
|
override val badNamedArgumentTarget: BadNamedArgumentsTarget,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.NamedArgumentsNotAllowed(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class AmbiguityImpl(
|
internal class AmbiguityImpl(
|
||||||
override val candidates: List<KtSymbol>,
|
override val candidates: List<KtSymbol>,
|
||||||
firDiagnostic: FirPsiDiagnostic<*>,
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
|||||||
Reference in New Issue
Block a user