[FIR] Implement FUNCTION_EXPECTED
This commit is contained in:
+1
-1
@@ -32,7 +32,7 @@ FILE: threeReceivers.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun R|FooBar|.chk(buz: R|Buz|): R|kotlin/Unit| {
|
public final fun R|FooBar|.chk(buz: R|Buz|): R|kotlin/Unit| {
|
||||||
R|<local>/buz|.<Unresolved name: foobar>#()
|
R|<local>/buz|.<Expression 'foobar' of type 'Bar' cannot be invoked as a function>#()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -17,6 +17,6 @@ class Foo {
|
|||||||
// this@Foo is dispatch receiver of foobar
|
// this@Foo is dispatch receiver of foobar
|
||||||
// Foo/foobar is dispatch receiver of invoke
|
// Foo/foobar is dispatch receiver of invoke
|
||||||
// this@chk is extension receiver of invoke
|
// this@chk is extension receiver of invoke
|
||||||
buz.<!UNRESOLVED_REFERENCE!>foobar<!>()
|
buz.<!FUNCTION_EXPECTED!>foobar<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -28,5 +28,5 @@ FILE: test.kt
|
|||||||
lval res1: R|kotlin/String| = R|<local>/descriptor|.R|/WrappedPropertyDescriptor.setter|
|
lval res1: R|kotlin/String| = R|<local>/descriptor|.R|/WrappedPropertyDescriptor.setter|
|
||||||
lval res2: <ERROR TYPE REF: Unresolved name: getSetter> = R|<local>/descriptor|.<Unresolved name: getSetter>#()
|
lval res2: <ERROR TYPE REF: Unresolved name: getSetter> = R|<local>/descriptor|.<Unresolved name: getSetter>#()
|
||||||
lval res3: R|kotlin/Boolean| = R|<local>/descriptor|.R|/WrappedPropertyDescriptor.isDelegated|
|
lval res3: R|kotlin/Boolean| = R|<local>/descriptor|.R|/WrappedPropertyDescriptor.isDelegated|
|
||||||
lval res4: <ERROR TYPE REF: Unresolved name: isDelegated> = R|<local>/descriptor|.<Unresolved name: isDelegated>#()
|
lval res4: <ERROR TYPE REF: Expression 'isDelegated' of type 'kotlin/Boolean' cannot be invoked as a function> = R|<local>/descriptor|.<Expression 'isDelegated' of type 'kotlin/Boolean' cannot be invoked as a function>#()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -22,5 +22,5 @@ fun test() {
|
|||||||
val res1 = descriptor.setter
|
val res1 = descriptor.setter
|
||||||
val res2 = descriptor.<!UNRESOLVED_REFERENCE!>getSetter<!>() // Should be error
|
val res2 = descriptor.<!UNRESOLVED_REFERENCE!>getSetter<!>() // Should be error
|
||||||
val res3 = descriptor.isDelegated
|
val res3 = descriptor.isDelegated
|
||||||
val res4 = descriptor.<!UNRESOLVED_REFERENCE!>isDelegated<!>() // Should be error
|
val res4 = descriptor.<!FUNCTION_EXPECTED!>isDelegated<!>() // Should be error
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
FILE: main.kt
|
FILE: main.kt
|
||||||
public final fun test(ann: R|Ann|): R|kotlin/Unit| {
|
public final fun test(ann: R|Ann|): R|kotlin/Unit| {
|
||||||
R|<local>/ann|.R|/Ann.value|
|
R|<local>/ann|.R|/Ann.value|
|
||||||
R|<local>/ann|.<Unresolved name: value>#()
|
R|<local>/ann|.<Expression 'value' of type 'kotlin/String' cannot be invoked as a function>#()
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -3,12 +3,12 @@
|
|||||||
// FILE: Ann.java
|
// FILE: Ann.java
|
||||||
|
|
||||||
public @interface Ann {
|
public @interface Ann {
|
||||||
String value()
|
String value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
|
|
||||||
fun test(ann: Ann) {
|
fun test(ann: Ann) {
|
||||||
ann.value
|
ann.value
|
||||||
ann.<!UNRESOLVED_REFERENCE!>value<!>() // should be an error
|
ann.<!FUNCTION_EXPECTED!>value<!>() // should be an error
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -120,6 +120,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
}
|
}
|
||||||
val ILLEGAL_SELECTOR by error<PsiElement>()
|
val ILLEGAL_SELECTOR by error<PsiElement>()
|
||||||
val NO_RECEIVER_ALLOWED by error<PsiElement>()
|
val NO_RECEIVER_ALLOWED by error<PsiElement>()
|
||||||
|
val FUNCTION_EXPECTED by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
|
||||||
|
parameter<String>("expression")
|
||||||
|
parameter<ConeKotlinType>("type")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val SUPER by object : DiagnosticGroup("Super") {
|
val SUPER by object : DiagnosticGroup("Super") {
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ object FirErrors {
|
|||||||
val FUNCTION_CALL_EXPECTED by error2<PsiElement, String, Boolean>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val FUNCTION_CALL_EXPECTED by error2<PsiElement, String, Boolean>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val ILLEGAL_SELECTOR by error0<PsiElement>()
|
val ILLEGAL_SELECTOR by error0<PsiElement>()
|
||||||
val NO_RECEIVER_ALLOWED by error0<PsiElement>()
|
val NO_RECEIVER_ALLOWED by error0<PsiElement>()
|
||||||
|
val FUNCTION_EXPECTED by error2<PsiElement, String, ConeKotlinType>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
|
||||||
// Super
|
// Super
|
||||||
val SUPER_IS_NOT_AN_EXPRESSION by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val SUPER_IS_NOT_AN_EXPRESSION by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
|||||||
+6
@@ -177,6 +177,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FINAL_UPPER_BOUND
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_CALL_EXPECTED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_CALL_EXPECTED
|
||||||
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.FUNCTION_EXPECTED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_CANNOT_HAVE_ABSTRACT_PROPERTIES
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_CANNOT_HAVE_ABSTRACT_PROPERTIES
|
||||||
@@ -434,6 +435,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_TA
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_PARAMETER_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_PARAMETER_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_RETURN_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_RETURN_TYPE
|
||||||
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
class FirDefaultErrorMessages {
|
class FirDefaultErrorMessages {
|
||||||
@@ -496,6 +498,10 @@ class FirDefaultErrorMessages {
|
|||||||
)
|
)
|
||||||
map.put(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, "Cannot create an instance of an abstract class")
|
map.put(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, "Cannot create an instance of an abstract class")
|
||||||
map.put(FUNCTION_CALL_EXPECTED, "Function invocation ''{0}({1})'' expected", TO_STRING, FUNCTION_PARAMETERS)
|
map.put(FUNCTION_CALL_EXPECTED, "Function invocation ''{0}({1})'' expected", TO_STRING, FUNCTION_PARAMETERS)
|
||||||
|
map.put(
|
||||||
|
FUNCTION_EXPECTED,
|
||||||
|
"Expression ''{0}'' of type {1} cannot be invoked as a function. The function 'invoke()' is not found", TO_STRING, RENDER_TYPE
|
||||||
|
)
|
||||||
map.put(ILLEGAL_SELECTOR, "The expression cannot be a selector (occur after a dot)")
|
map.put(ILLEGAL_SELECTOR, "The expression cannot be a selector (occur after a dot)")
|
||||||
map.put(NO_RECEIVER_ALLOWED, "No receiver can be passed to this function or property")
|
map.put(NO_RECEIVER_ALLOWED, "No receiver can be passed to this function or property")
|
||||||
|
|
||||||
|
|||||||
+1
@@ -41,6 +41,7 @@ private fun ConeDiagnostic.toFirDiagnostic(
|
|||||||
is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.name.asString())
|
is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.name.asString())
|
||||||
is ConeUnresolvedQualifierError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.qualifier)
|
is ConeUnresolvedQualifierError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.qualifier)
|
||||||
is ConeFunctionCallExpectedError -> FirErrors.FUNCTION_CALL_EXPECTED.createOn(source, this.name.asString(), this.hasValueParameters)
|
is ConeFunctionCallExpectedError -> FirErrors.FUNCTION_CALL_EXPECTED.createOn(source, this.name.asString(), this.hasValueParameters)
|
||||||
|
is ConeFunctionExpectedError -> FirErrors.FUNCTION_EXPECTED.createOn(source, this.expression, this.type)
|
||||||
is ConeHiddenCandidateError -> FirErrors.INVISIBLE_REFERENCE.createOn(source, this.candidateSymbol)
|
is ConeHiddenCandidateError -> FirErrors.INVISIBLE_REFERENCE.createOn(source, this.candidateSymbol)
|
||||||
is ConeAmbiguityError -> when {
|
is ConeAmbiguityError -> when {
|
||||||
applicability.isSuccess -> FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.createOn(source, this.candidates.map { it.symbol })
|
applicability.isSuccess -> FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.createOn(source, this.candidates.map { it.symbol })
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.*
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver
|
import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerResolveManager
|
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerResolveManager
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.dfa.symbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.ResolvedCallableReferenceAtom
|
import org.jetbrains.kotlin.fir.resolve.inference.ResolvedCallableReferenceAtom
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
@@ -84,6 +85,14 @@ class FirCallResolver(
|
|||||||
val name = functionCall.calleeReference.name
|
val name = functionCall.calleeReference.name
|
||||||
val result = collectCandidates(functionCall, name)
|
val result = collectCandidates(functionCall, name)
|
||||||
|
|
||||||
|
var forceCandidates: Collection<Candidate>? = null
|
||||||
|
if (result.candidates.isEmpty()) {
|
||||||
|
val newResult = collectCandidates(functionCall, name, CallKind.VariableAccess)
|
||||||
|
if (newResult.candidates.isNotEmpty()) {
|
||||||
|
forceCandidates = newResult.candidates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val nameReference = createResolvedNamedReference(
|
val nameReference = createResolvedNamedReference(
|
||||||
functionCall.calleeReference,
|
functionCall.calleeReference,
|
||||||
name,
|
name,
|
||||||
@@ -91,6 +100,8 @@ class FirCallResolver(
|
|||||||
result.candidates,
|
result.candidates,
|
||||||
result.applicability,
|
result.applicability,
|
||||||
functionCall.explicitReceiver,
|
functionCall.explicitReceiver,
|
||||||
|
expectedCallKind = if (forceCandidates != null) CallKind.VariableAccess else null,
|
||||||
|
expectedCandidates = forceCandidates
|
||||||
)
|
)
|
||||||
|
|
||||||
val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference)
|
val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference)
|
||||||
@@ -147,7 +158,7 @@ class FirCallResolver(
|
|||||||
|
|
||||||
val info = CallInfo(
|
val info = CallInfo(
|
||||||
qualifiedAccess,
|
qualifiedAccess,
|
||||||
if (qualifiedAccess is FirFunctionCall || forceCallKind == CallKind.Function) CallKind.Function else CallKind.VariableAccess,
|
forceCallKind ?: if (qualifiedAccess is FirFunctionCall) CallKind.Function else CallKind.VariableAccess,
|
||||||
name,
|
name,
|
||||||
explicitReceiver,
|
explicitReceiver,
|
||||||
argumentList,
|
argumentList,
|
||||||
@@ -229,7 +240,7 @@ class FirCallResolver(
|
|||||||
reducedCandidates,
|
reducedCandidates,
|
||||||
result.applicability,
|
result.applicability,
|
||||||
qualifiedAccess.explicitReceiver,
|
qualifiedAccess.explicitReceiver,
|
||||||
functionCallExpected = functionCallExpected
|
expectedCallKind = if (functionCallExpected) CallKind.Function else null
|
||||||
)
|
)
|
||||||
|
|
||||||
val referencedSymbol = when (nameReference) {
|
val referencedSymbol = when (nameReference) {
|
||||||
@@ -576,38 +587,66 @@ class FirCallResolver(
|
|||||||
applicability: CandidateApplicability,
|
applicability: CandidateApplicability,
|
||||||
explicitReceiver: FirExpression? = null,
|
explicitReceiver: FirExpression? = null,
|
||||||
createResolvedReferenceWithoutCandidateForLocalVariables: Boolean = true,
|
createResolvedReferenceWithoutCandidateForLocalVariables: Boolean = true,
|
||||||
functionCallExpected: Boolean = false
|
expectedCallKind: CallKind? = null,
|
||||||
|
expectedCandidates: Collection<Candidate>? = null
|
||||||
): FirNamedReference {
|
): FirNamedReference {
|
||||||
val source = reference.source
|
val source = reference.source
|
||||||
return when {
|
return when {
|
||||||
functionCallExpected -> {
|
expectedCallKind != null -> {
|
||||||
fun isValueParametersNotEmpty(candidate: Candidate): Boolean {
|
fun isValueParametersNotEmpty(candidate: Candidate): Boolean {
|
||||||
return (candidate.symbol.fir as? FirFunction)?.valueParameters?.size?.let { it > 0 } ?: false
|
return (candidate.symbol.fir as? FirFunction)?.valueParameters?.size?.let { it > 0 } ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
val candidate = candidates.singleOrNull()
|
val candidate = candidates.singleOrNull()
|
||||||
|
|
||||||
|
val diagnostic = if (expectedCallKind == CallKind.Function) {
|
||||||
|
ConeFunctionCallExpectedError(
|
||||||
|
name,
|
||||||
|
candidate?.let { isValueParametersNotEmpty(it) } ?: candidates.any { isValueParametersNotEmpty(it) })
|
||||||
|
} else {
|
||||||
|
val singleExpectedCandidate = expectedCandidates?.singleOrNull()
|
||||||
|
if (singleExpectedCandidate?.symbol?.fir is FirRegularClass) {
|
||||||
|
ConeUnresolvedNameError(name)
|
||||||
|
// TODO: ConeResolutionToClassifierError()
|
||||||
|
} else {
|
||||||
|
val coneType = explicitReceiver?.typeRef?.coneType
|
||||||
|
if (coneType != null && !coneType.isUnit) {
|
||||||
|
ConeFunctionExpectedError(
|
||||||
|
name.asString(),
|
||||||
|
(singleExpectedCandidate?.symbol?.fir as? FirTypedDeclaration)?.returnTypeRef?.coneType ?: coneType
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ConeUnresolvedNameError(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (candidate != null) {
|
if (candidate != null) {
|
||||||
createErrorReferenceWithExistingCandidate(
|
createErrorReferenceWithExistingCandidate(
|
||||||
candidate,
|
candidate,
|
||||||
ConeFunctionCallExpectedError(name, isValueParametersNotEmpty(candidate)),
|
diagnostic,
|
||||||
source,
|
source,
|
||||||
transformer.resolutionContext,
|
transformer.resolutionContext,
|
||||||
components.resolutionStageRunner
|
components.resolutionStageRunner
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
buildErrorReference(
|
buildErrorReference(callInfo, diagnostic, source)
|
||||||
callInfo,
|
|
||||||
ConeFunctionCallExpectedError(name, candidates.any { isValueParametersNotEmpty(it) }),
|
|
||||||
source
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
candidates.isEmpty() -> buildErrorReference(
|
candidates.isEmpty() -> {
|
||||||
callInfo,
|
val diagnostic = if (name.asString() == "invoke" && explicitReceiver is FirConstExpression<*>) {
|
||||||
ConeUnresolvedNameError(name),
|
ConeFunctionExpectedError(explicitReceiver.value?.toString() ?: "", explicitReceiver.typeRef.coneType)
|
||||||
source
|
} else {
|
||||||
)
|
ConeUnresolvedNameError(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
buildErrorReference(
|
||||||
|
callInfo,
|
||||||
|
diagnostic,
|
||||||
|
source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
candidates.size > 1 -> buildErrorReference(
|
candidates.size > 1 -> buildErrorReference(
|
||||||
callInfo,
|
callInfo,
|
||||||
|
|||||||
+5
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
@@ -49,6 +50,10 @@ class ConeFunctionCallExpectedError(val name: Name, val hasValueParameters: Bool
|
|||||||
override val reason: String get() = "Function call expected: $name(${if (hasValueParameters) "..." else ""})"
|
override val reason: String get() = "Function call expected: $name(${if (hasValueParameters) "..." else ""})"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ConeFunctionExpectedError(val expression: String, val type: ConeKotlinType) : ConeDiagnostic() {
|
||||||
|
override val reason: String get() = "Expression '$expression' of type '$type' cannot be invoked as a function"
|
||||||
|
}
|
||||||
|
|
||||||
class ConeHiddenCandidateError(
|
class ConeHiddenCandidateError(
|
||||||
val candidateSymbol: FirBasedSymbol<*>
|
val candidateSymbol: FirBasedSymbol<*>
|
||||||
) : ConeDiagnostic() {
|
) : ConeDiagnostic() {
|
||||||
|
|||||||
@@ -50,25 +50,25 @@ fun main(args : Array<String>) {
|
|||||||
checkSubtype<Int>(b)
|
checkSubtype<Int>(b)
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>fooT2<!>()(1) // : Any?
|
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>fooT2<!>()(1) // : Any?
|
||||||
|
|
||||||
<!UNRESOLVED_REFERENCE!>1<!>()
|
<!FUNCTION_EXPECTED!>1<!>()
|
||||||
<!UNRESOLVED_REFERENCE!>1<!>{}
|
<!FUNCTION_EXPECTED!>1<!>{}
|
||||||
<!UNRESOLVED_REFERENCE!>1<!>(){}
|
<!FUNCTION_EXPECTED!>1<!>(){}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun f() : Int.() -> Unit = {}
|
fun f() : Int.() -> Unit = {}
|
||||||
|
|
||||||
fun main1() {
|
fun main1() {
|
||||||
1.(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)();
|
1.(<!FUNCTION_EXPECTED!>fun Int.() = 1<!>)();
|
||||||
{1}();
|
{1}();
|
||||||
(fun (x : Int) = x)(1)
|
(fun (x : Int) = x)(1)
|
||||||
1.(<!UNRESOLVED_REFERENCE!>fun Int.(x : Int) = x<!>)(1);
|
1.(<!FUNCTION_EXPECTED!>fun Int.(x : Int) = x<!>)(1);
|
||||||
l@{1}()
|
l@{1}()
|
||||||
1.((<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>))()
|
1.((<!FUNCTION_EXPECTED!>fun Int.() = 1<!>))()
|
||||||
1.(<!UNRESOLVED_REFERENCE!>f()<!>)()
|
1.(<!FUNCTION_EXPECTED!>f()<!>)()
|
||||||
1.<!UNRESOLVED_REFERENCE!>if(true){f()}else{f()}<!>()
|
1.<!FUNCTION_EXPECTED!>if(true){f()}else{f()}<!>()
|
||||||
1.<!UNRESOLVED_REFERENCE!>if(true)(fun Int.() {})else{f()}<!>()
|
1.<!FUNCTION_EXPECTED!>if(true)(fun Int.() {})else{f()}<!>()
|
||||||
|
|
||||||
1.<!UNRESOLVED_REFERENCE!>"sdf"<!>()
|
1.<!FUNCTION_EXPECTED!>"sdf"<!>()
|
||||||
|
|
||||||
1.<!ILLEGAL_SELECTOR!>"sdf"<!>
|
1.<!ILLEGAL_SELECTOR!>"sdf"<!>
|
||||||
1.<!ILLEGAL_SELECTOR!>{}<!>
|
1.<!ILLEGAL_SELECTOR!>{}<!>
|
||||||
@@ -78,7 +78,7 @@ fun main1() {
|
|||||||
fun test() {
|
fun test() {
|
||||||
{x : Int -> 1}(<!NO_VALUE_FOR_PARAMETER!>)<!>;
|
{x : Int -> 1}(<!NO_VALUE_FOR_PARAMETER!>)<!>;
|
||||||
(fun Int.() = 1)(<!NO_VALUE_FOR_PARAMETER!>)<!>
|
(fun Int.() = 1)(<!NO_VALUE_FOR_PARAMETER!>)<!>
|
||||||
"sd".(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)()
|
"sd".(<!FUNCTION_EXPECTED!>fun Int.() = 1<!>)()
|
||||||
val i : Int? = null
|
val i : Int? = null
|
||||||
i.(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)();
|
i.(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)();
|
||||||
<!INAPPLICABLE_CANDIDATE!>{}<!><Int>()
|
<!INAPPLICABLE_CANDIDATE!>{}<!><Int>()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ fun test(t: T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test1(t: T?) {
|
fun test1(t: T?) {
|
||||||
t.<!UNRESOLVED_REFERENCE!>f<!>(1) // todo resolve f as value and report UNSAFE_CALL
|
t.<!FUNCTION_EXPECTED!>f<!>(1) // todo resolve f as value and report UNSAFE_CALL
|
||||||
t?.<!UNSAFE_IMPLICIT_INVOKE_CALL!>f<!>(1)
|
t?.<!UNSAFE_IMPLICIT_INVOKE_CALL!>f<!>(1)
|
||||||
t<!UNSAFE_CALL!>.<!>f?.invoke(1)
|
t<!UNSAFE_CALL!>.<!>f?.invoke(1)
|
||||||
t?.f?.invoke(1)
|
t?.f?.invoke(1)
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ fun test4() {
|
|||||||
// should be an error on receiver, shouldn't be thrown away
|
// should be an error on receiver, shouldn't be thrown away
|
||||||
|
|
||||||
fun test5() {
|
fun test5() {
|
||||||
1.(<!UNRESOLVED_REFERENCE!>fun String.()=1<!>)()
|
1.(<!FUNCTION_EXPECTED!>fun String.()=1<!>)()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <R: Any> R?.sure() : R = this!!
|
fun <R: Any> R?.sure() : R = this!!
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ fun x(f : Foo) {
|
|||||||
f.<!FUNCTION_CALL_EXPECTED!>prop<!>
|
f.<!FUNCTION_CALL_EXPECTED!>prop<!>
|
||||||
f.<!FUNCTION_CALL_EXPECTED!>bar<!>
|
f.<!FUNCTION_CALL_EXPECTED!>bar<!>
|
||||||
|
|
||||||
f.<!UNRESOLVED_REFERENCE!>a<!>()
|
f.<!FUNCTION_EXPECTED!>a<!>()
|
||||||
<!UNRESOLVED_REFERENCE!>c<!>()
|
<!UNRESOLVED_REFERENCE!>c<!>()
|
||||||
<!INVISIBLE_REFERENCE!>R<!>()
|
<!INVISIBLE_REFERENCE!>R<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -33,4 +33,4 @@ fun bar() {
|
|||||||
Inner()
|
Inner()
|
||||||
Inner(1)
|
Inner(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
fun f(c: LongRange): Int {
|
|
||||||
return c.<!UNRESOLVED_REFERENCE!>start<!>()
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
|
||||||
fun f(c: LongRange): Int {
|
fun f(c: LongRange): Int {
|
||||||
return c.<!FUNCTION_EXPECTED!>start<!>()
|
return c.<!FUNCTION_EXPECTED!>start<!>()
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
fun foo(i: Int) {
|
fun foo(i: Int) {
|
||||||
<!UNRESOLVED_REFERENCE!>i<!>()
|
<!UNRESOLVED_REFERENCE!>i<!>()
|
||||||
<!UNRESOLVED_REFERENCE!>1<!>()
|
<!FUNCTION_EXPECTED!>1<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
fun test1() {
|
fun test1() {
|
||||||
1. (<!UNRESOLVED_REFERENCE!>fun String.(i: Int) = i<!> )(1)
|
1. (<!FUNCTION_EXPECTED!>fun String.(i: Int) = i<!> )(1)
|
||||||
1.(<!UNRESOLVED_REFERENCE!>label@ fun String.(i: Int) = i<!> )(1)
|
1.(<!FUNCTION_EXPECTED!>label@ fun String.(i: Int) = i<!> )(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test2(f: String.(Int) -> Unit) {
|
fun test2(f: String.(Int) -> Unit) {
|
||||||
@@ -12,5 +12,5 @@ fun test2(f: String.(Int) -> Unit) {
|
|||||||
fun test3() {
|
fun test3() {
|
||||||
fun foo(): String.(Int) -> Unit = {}
|
fun foo(): String.(Int) -> Unit = {}
|
||||||
|
|
||||||
1.(<!UNRESOLVED_REFERENCE!>foo()<!>)(1)
|
1.(<!FUNCTION_EXPECTED!>foo()<!>)(1)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -2,11 +2,11 @@ class A(val x: (String.() -> Unit)?)
|
|||||||
|
|
||||||
fun test(a: A) {
|
fun test(a: A) {
|
||||||
if (a.x != null) {
|
if (a.x != null) {
|
||||||
"".(<!UNRESOLVED_REFERENCE!>a.x<!>)()
|
"".(<!FUNCTION_EXPECTED!>a.x<!>)()
|
||||||
a.x("") // todo
|
a.x("") // todo
|
||||||
(a.x)("")
|
(a.x)("")
|
||||||
}
|
}
|
||||||
"".(<!UNRESOLVED_REFERENCE!>a.x<!>)()
|
"".(<!FUNCTION_EXPECTED!>a.x<!>)()
|
||||||
a.<!UNSAFE_IMPLICIT_INVOKE_CALL!>x<!>("")
|
a.<!UNSAFE_IMPLICIT_INVOKE_CALL!>x<!>("")
|
||||||
<!UNSAFE_IMPLICIT_INVOKE_CALL!>(a.x)<!>("")
|
<!UNSAFE_IMPLICIT_INVOKE_CALL!>(a.x)<!>("")
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ val Cls.extensionProperty: MemberInvokeOwner
|
|||||||
|
|
||||||
fun testNullableReceiver(nullable: Cls?) {
|
fun testNullableReceiver(nullable: Cls?) {
|
||||||
nullable?.extensionProperty()
|
nullable?.extensionProperty()
|
||||||
nullable.<!UNRESOLVED_REFERENCE!>extensionProperty<!>()
|
nullable.<!FUNCTION_EXPECTED!>extensionProperty<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testNotNullableReceiver(notNullable: Cls) {
|
fun testNotNullableReceiver(notNullable: Cls) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ class D : C {
|
|||||||
{
|
{
|
||||||
val s = ""
|
val s = ""
|
||||||
<!UNRESOLVED_REFERENCE!>s<!>()
|
<!UNRESOLVED_REFERENCE!>s<!>()
|
||||||
<!UNRESOLVED_REFERENCE!>""<!>()
|
<!FUNCTION_EXPECTED!>""<!>()
|
||||||
42
|
42
|
||||||
}())
|
}())
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-2
@@ -12,5 +12,5 @@ public fun foo(xx: Any): Int {
|
|||||||
y.length
|
y.length
|
||||||
} while (true)
|
} while (true)
|
||||||
// We could have smart cast here but with break it's hard to detect
|
// We could have smart cast here but with break it's hard to detect
|
||||||
return x.<!UNRESOLVED_REFERENCE!>length<!>()
|
return x.<!FUNCTION_EXPECTED!>length<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
fun x(): Boolean { return true }
|
||||||
|
|
||||||
|
public fun foo(pp: Any): Int {
|
||||||
|
var p = pp
|
||||||
|
while(true) {
|
||||||
|
(p as String).length
|
||||||
|
if (x()) break
|
||||||
|
p = 42
|
||||||
|
}
|
||||||
|
// Smart cast is NOT possible here
|
||||||
|
// (we could provide it but p = 42 makes it difficult to understand)
|
||||||
|
return p.<!FUNCTION_EXPECTED!>length<!>()
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
fun x(): Boolean { return true }
|
fun x(): Boolean { return true }
|
||||||
|
|
||||||
public fun foo(pp: Any): Int {
|
public fun foo(pp: Any): Int {
|
||||||
@@ -11,4 +10,4 @@ public fun foo(pp: Any): Int {
|
|||||||
// Smart cast is NOT possible here
|
// Smart cast is NOT possible here
|
||||||
// (we could provide it but p = 42 makes it difficult to understand)
|
// (we could provide it but p = 42 makes it difficult to understand)
|
||||||
return p.<!UNRESOLVED_REFERENCE!>length<!>()
|
return p.<!UNRESOLVED_REFERENCE!>length<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -8,9 +8,9 @@ class C() {
|
|||||||
// TESTCASE NUMBER: 1
|
// TESTCASE NUMBER: 1
|
||||||
fun case1() {
|
fun case1() {
|
||||||
val b: B = B(C())
|
val b: B = B(C())
|
||||||
b <!UNRESOLVED_REFERENCE!>memberVal<!> 1 //nok UNRESOLVED_REFERENCE
|
b <!FUNCTION_EXPECTED!>memberVal<!> 1 //nok UNRESOLVED_REFERENCE
|
||||||
b.memberVal.<!UNRESOLVED_REFERENCE!>invoke<!>(2) //nok UNRESOLVED_REFERENCE
|
b.memberVal.<!UNRESOLVED_REFERENCE!>invoke<!>(2) //nok UNRESOLVED_REFERENCE
|
||||||
b.<!UNRESOLVED_REFERENCE!>memberVal<!>(1) //nok FUNCTION_EXPECTED
|
b.<!FUNCTION_EXPECTED!>memberVal<!>(1) //nok FUNCTION_EXPECTED
|
||||||
|
|
||||||
if (b.memberVal is C) {
|
if (b.memberVal is C) {
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -9,9 +9,9 @@ class C() {
|
|||||||
// TESTCASE NUMBER: 1
|
// TESTCASE NUMBER: 1
|
||||||
fun case1() {
|
fun case1() {
|
||||||
val b: B = B(C())
|
val b: B = B(C())
|
||||||
b <!UNRESOLVED_REFERENCE!>memberVal<!> 1 //nok UNRESOLVED_REFERENCE
|
b <!FUNCTION_EXPECTED!>memberVal<!> 1 //nok UNRESOLVED_REFERENCE
|
||||||
b.memberVal.<!UNRESOLVED_REFERENCE!>invoke<!>(2) //nok UNRESOLVED_REFERENCE
|
b.memberVal.<!UNRESOLVED_REFERENCE!>invoke<!>(2) //nok UNRESOLVED_REFERENCE
|
||||||
b.<!UNRESOLVED_REFERENCE!>memberVal<!>(1) //nok FUNCTION_EXPECTED
|
b.<!FUNCTION_EXPECTED!>memberVal<!>(1) //nok FUNCTION_EXPECTED
|
||||||
|
|
||||||
b.memberVal as C
|
b.memberVal as C
|
||||||
|
|
||||||
|
|||||||
+8
@@ -327,6 +327,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.FUNCTION_EXPECTED) { firDiagnostic ->
|
||||||
|
FunctionExpectedImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||||
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.SUPER_IS_NOT_AN_EXPRESSION) { firDiagnostic ->
|
add(FirErrors.SUPER_IS_NOT_AN_EXPRESSION) { firDiagnostic ->
|
||||||
SuperIsNotAnExpressionImpl(
|
SuperIsNotAnExpressionImpl(
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
|
|||||||
+6
@@ -257,6 +257,12 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = NoReceiverAllowed::class
|
override val diagnosticClass get() = NoReceiverAllowed::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class FunctionExpected : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = FunctionExpected::class
|
||||||
|
abstract val expression: String
|
||||||
|
abstract val type: KtType
|
||||||
|
}
|
||||||
|
|
||||||
abstract class SuperIsNotAnExpression : KtFirDiagnostic<PsiElement>() {
|
abstract class SuperIsNotAnExpression : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = SuperIsNotAnExpression::class
|
override val diagnosticClass get() = SuperIsNotAnExpression::class
|
||||||
}
|
}
|
||||||
|
|||||||
+9
@@ -381,6 +381,15 @@ internal class NoReceiverAllowedImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class FunctionExpectedImpl(
|
||||||
|
override val expression: String,
|
||||||
|
override val type: KtType,
|
||||||
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.FunctionExpected(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class SuperIsNotAnExpressionImpl(
|
internal class SuperIsNotAnExpressionImpl(
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
Reference in New Issue
Block a user