FIR checker: add diagnostics for missing/ambiguous component calls
This commit is contained in:
committed by
Mikhail Glukhikh
parent
83b9c29495
commit
fa0b933bc8
+122
@@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* 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.KtNodeTypes
|
||||||
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.extended.report
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
|
|
||||||
|
object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
||||||
|
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
val source = declaration.source ?: return
|
||||||
|
// val (...) = `destructuring_declaration`
|
||||||
|
if (source.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION) {
|
||||||
|
assert(declaration.name.isSpecial && declaration.name.asString() == "<destruct>") {
|
||||||
|
"Unexpected name: ${declaration.name.asString()} for destructuring declaration"
|
||||||
|
}
|
||||||
|
checkInitializer(source, declaration.initializer, reporter)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// val (`destructuring_declaration_entry`, ...) = ...
|
||||||
|
if (source.elementType != KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY) return
|
||||||
|
|
||||||
|
val componentCall = declaration.initializer as? FirComponentCall ?: return
|
||||||
|
val reference = componentCall.calleeReference as? FirErrorNamedReference ?: return
|
||||||
|
|
||||||
|
val originalExpression = componentCall.explicitReceiverOfQualifiedAccess ?: return
|
||||||
|
val originalDestructuringDeclaration = originalExpression.resolvedVariable ?: return
|
||||||
|
val originalDestructuringDeclarationOrInitializer =
|
||||||
|
when (originalDestructuringDeclaration) {
|
||||||
|
is FirProperty -> {
|
||||||
|
if (originalDestructuringDeclaration.initializer?.source?.elementType == KtNodeTypes.FOR) {
|
||||||
|
// for ((entry, ...) = `destructuring_declaration`) { ... }
|
||||||
|
// It will be wrapped as `next()` call whose explicit receiver is `iterator()` on the actual source.
|
||||||
|
val iterator = originalDestructuringDeclaration.initializer?.explicitReceiverOfQualifiedAccess
|
||||||
|
(iterator?.resolvedVariable as? FirProperty)?.initializer?.explicitReceiverOfQualifiedAccess
|
||||||
|
} else {
|
||||||
|
// val (entry, ...) = `destructuring_declaration`
|
||||||
|
originalDestructuringDeclaration.initializer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is FirValueParameter -> {
|
||||||
|
// ... = { `(entry, ...)` -> ... } // value parameter itself is a destructuring declaration
|
||||||
|
originalDestructuringDeclaration
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
} ?: return
|
||||||
|
val originalDestructuringDeclarationOrInitializerSource = originalDestructuringDeclarationOrInitializer.source ?: return
|
||||||
|
val originalDestructuringDeclarationType =
|
||||||
|
when (originalDestructuringDeclarationOrInitializer) {
|
||||||
|
is FirVariable<*> -> originalDestructuringDeclarationOrInitializer.returnTypeRef
|
||||||
|
is FirExpression -> originalDestructuringDeclarationOrInitializer.typeRef
|
||||||
|
else -> null
|
||||||
|
} ?: return
|
||||||
|
|
||||||
|
when (val diagnostic = reference.diagnostic) {
|
||||||
|
is ConeUnresolvedNameError -> {
|
||||||
|
reporter.report(
|
||||||
|
FirErrors.COMPONENT_FUNCTION_MISSING.on(
|
||||||
|
originalDestructuringDeclarationOrInitializerSource,
|
||||||
|
diagnostic.name,
|
||||||
|
originalDestructuringDeclarationType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is ConeAmbiguityError -> {
|
||||||
|
reporter.report(
|
||||||
|
FirErrors.COMPONENT_FUNCTION_AMBIGUITY.on(
|
||||||
|
originalDestructuringDeclarationOrInitializerSource,
|
||||||
|
diagnostic.name,
|
||||||
|
diagnostic.candidates
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// TODO: COMPONENT_FUNCTION_ON_NULLABLE
|
||||||
|
// TODO: COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkInitializer(source: FirSourceElement, initializer: FirExpression?, reporter: DiagnosticReporter) {
|
||||||
|
val needToReport =
|
||||||
|
when (initializer) {
|
||||||
|
null -> true
|
||||||
|
is FirErrorExpression -> (initializer.diagnostic as? ConeSimpleDiagnostic)?.kind == DiagnosticKind.Syntax
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
if (needToReport) {
|
||||||
|
reporter.report(source, FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val FirExpression.explicitReceiverOfQualifiedAccess: FirQualifiedAccessExpression?
|
||||||
|
get() = (this as? FirQualifiedAccess)?.explicitReceiver?.unwrapped as? FirQualifiedAccessExpression
|
||||||
|
|
||||||
|
private val FirExpression.unwrapped: FirExpression
|
||||||
|
get() =
|
||||||
|
when (this) {
|
||||||
|
is FirExpressionWithSmartcast -> this.originalExpression
|
||||||
|
is FirWrappedExpression -> this.expression
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
|
|
||||||
|
private val FirQualifiedAccessExpression.resolvedVariable: FirVariable<*>?
|
||||||
|
get() = ((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirVariableSymbol)?.fir as? FirVariable<*>
|
||||||
|
}
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.KtNodeTypes
|
|
||||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.extended.report
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
|
||||||
|
|
||||||
object FirDestructuringDeclarationInitializerChecker : FirPropertyChecker() {
|
|
||||||
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
|
||||||
if (!declaration.name.isSpecial || declaration.name.asString() != "<destruct>") return
|
|
||||||
val source = declaration.source
|
|
||||||
if (source == null || source.kind is FirFakeSourceElementKind) return
|
|
||||||
if (source.elementType != KtNodeTypes.DESTRUCTURING_DECLARATION) return
|
|
||||||
val needToReport =
|
|
||||||
when (val initializer = declaration.initializer) {
|
|
||||||
null -> true
|
|
||||||
is FirErrorExpression -> (initializer.diagnostic as? ConeSimpleDiagnostic)?.kind == DiagnosticKind.Syntax
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
if (needToReport) {
|
|
||||||
reporter.report(source, FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+8
@@ -59,6 +59,14 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun reportFirDiagnostic(diagnostic: ConeDiagnostic, source: FirSourceElement, reporter: DiagnosticReporter) {
|
private fun reportFirDiagnostic(diagnostic: ConeDiagnostic, source: FirSourceElement, reporter: DiagnosticReporter) {
|
||||||
|
// Will be handled by [FirDestructuringDeclarationChecker]
|
||||||
|
if (source.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY) {
|
||||||
|
// TODO: if all diagnostics are supported, we don't need the following check, and will bail out based on element type.
|
||||||
|
if (diagnostic is ConeUnresolvedNameError || diagnostic is ConeAmbiguityError) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val coneDiagnostic = when (diagnostic) {
|
val coneDiagnostic = when (diagnostic) {
|
||||||
is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.name?.asString() ?: "<No name>")
|
is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.name?.asString() ?: "<No name>")
|
||||||
is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.classId.asString())
|
is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.classId.asString())
|
||||||
|
|||||||
+16
@@ -7,9 +7,11 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBIGUOUS_CALLS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.PROPERTY_NAME
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.PROPERTY_NAME
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.TO_STRING
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.TO_STRING
|
||||||
@@ -32,6 +34,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_VAL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_VAL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_IN_SUPERTYPE_FOR_ENUM
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_IN_SUPERTYPE_FOR_ENUM
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_AMBIGUITY
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_MISSING
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_OVERLOADS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_OVERLOADS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_PROJECTION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_PROJECTION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_INTERFACE
|
||||||
@@ -382,6 +386,18 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
|
|
||||||
// Destructuring declaration
|
// Destructuring declaration
|
||||||
map.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration")
|
map.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration")
|
||||||
|
map.put(
|
||||||
|
COMPONENT_FUNCTION_MISSING,
|
||||||
|
"Destructuring declaration initializer of type {1} must have a ''{0}()'' function",
|
||||||
|
TO_STRING,
|
||||||
|
RENDER_TYPE
|
||||||
|
)
|
||||||
|
map.put(
|
||||||
|
COMPONENT_FUNCTION_AMBIGUITY,
|
||||||
|
"Function ''{0}''() is ambiguous for this expression: {1}",
|
||||||
|
TO_STRING,
|
||||||
|
AMBIGUOUS_CALLS
|
||||||
|
)
|
||||||
|
|
||||||
// Control flow diagnostics
|
// Control flow diagnostics
|
||||||
map.put(UNINITIALIZED_VARIABLE, "{0} must be initialized before access", PROPERTY_NAME)
|
map.put(UNINITIALIZED_VARIABLE, "{0} must be initialized before access", PROPERTY_NAME)
|
||||||
|
|||||||
+12
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
|
||||||
object FirDiagnosticRenderers {
|
object FirDiagnosticRenderers {
|
||||||
val NULLABLE_STRING = Renderer<String?> { it ?: "null" }
|
val NULLABLE_STRING = Renderer<String?> { it ?: "null" }
|
||||||
@@ -56,4 +57,15 @@ object FirDiagnosticRenderers {
|
|||||||
}
|
}
|
||||||
name.asString()
|
name.asString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val RENDER_TYPE = Renderer { typeRef: FirTypeRef ->
|
||||||
|
// TODO: need a way to tune granuality, e.g., without parameter names in functional types.
|
||||||
|
typeRef.render()
|
||||||
|
}
|
||||||
|
|
||||||
|
val AMBIGUOUS_CALLS = Renderer { candidates: Collection<AbstractFirBasedSymbol<*>> ->
|
||||||
|
candidates.joinToString(separator = "\n", prefix = "\n") { symbol ->
|
||||||
|
SYMBOL.render(symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,15 @@ import org.jetbrains.kotlin.fir.FirSourceElement
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
object FirErrors {
|
object FirErrors {
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
@@ -174,6 +177,10 @@ object FirErrors {
|
|||||||
|
|
||||||
// Destructuring declaration
|
// Destructuring declaration
|
||||||
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<FirSourceElement, KtDestructuringDeclaration>()
|
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<FirSourceElement, KtDestructuringDeclaration>()
|
||||||
|
val COMPONENT_FUNCTION_MISSING by error2<FirSourceElement, PsiElement, Name, FirTypeRef>()
|
||||||
|
val COMPONENT_FUNCTION_AMBIGUITY by error2<FirSourceElement, PsiElement, Name, Collection<AbstractFirBasedSymbol<*>>>()
|
||||||
|
// TODO: val COMPONENT_FUNCTION_ON_NULLABLE by ...
|
||||||
|
// TODO: val COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH by ...
|
||||||
|
|
||||||
// Control flow diagnostics
|
// Control flow diagnostics
|
||||||
val UNINITIALIZED_VARIABLE by error1<FirSourceElement, PsiElement, FirPropertySymbol>()
|
val UNINITIALIZED_VARIABLE by error1<FirSourceElement, PsiElement, FirPropertySymbol>()
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
|
|
||||||
override val propertyCheckers: Set<FirPropertyChecker> = setOf(
|
override val propertyCheckers: Set<FirPropertyChecker> = setOf(
|
||||||
FirInapplicableLateinitChecker,
|
FirInapplicableLateinitChecker,
|
||||||
FirDestructuringDeclarationInitializerChecker,
|
FirDestructuringDeclarationChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val regularClassCheckers: Set<FirRegularClassChecker> = setOf(
|
override val regularClassCheckers: Set<FirRegularClassChecker> = setOf(
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ class MyClass2 {}
|
|||||||
<!CONFLICTING_OVERLOADS!>fun MyClass2.component1()<!> = 1.3
|
<!CONFLICTING_OVERLOADS!>fun MyClass2.component1()<!> = 1.3
|
||||||
|
|
||||||
fun test(mc1: MyClass, mc2: MyClass2) {
|
fun test(mc1: MyClass, mc2: MyClass2) {
|
||||||
val (<!INAPPLICABLE_CANDIDATE!>a<!>, <!UNRESOLVED_REFERENCE!>b<!>) = mc1
|
val (<!INAPPLICABLE_CANDIDATE!>a<!>, b) = <!COMPONENT_FUNCTION_MISSING!>mc1<!>
|
||||||
val (c) = mc2
|
val (c) = mc2
|
||||||
|
|
||||||
//a,b,c are error types
|
//a,b,c are error types
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ class C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
for ((<!AMBIGUITY!>x<!>, y) in C()) {
|
for ((x, y) in <!COMPONENT_FUNCTION_AMBIGUITY!>C()<!>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ class C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
for ((x, <!UNRESOLVED_REFERENCE!>y<!>) in C()) {
|
for ((x, y) in <!COMPONENT_FUNCTION_MISSING!>C()<!>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,13 +1,13 @@
|
|||||||
// !WITH_NEW_INFERENCE
|
// !WITH_NEW_INFERENCE
|
||||||
fun useDeclaredVariables() {
|
fun useDeclaredVariables() {
|
||||||
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for ((<!UNRESOLVED_REFERENCE!>a<!>, <!UNRESOLVED_REFERENCE!>b<!>)<!SYNTAX!><!>) {
|
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for ((a, b)<!SYNTAX!><!>) {
|
||||||
a
|
a
|
||||||
b
|
b
|
||||||
}<!>
|
}<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkersShouldRun() {
|
fun checkersShouldRun() {
|
||||||
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for ((<!UNRESOLVED_REFERENCE!>@A a<!>, _)<!SYNTAX!><!>) {
|
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for ((@A a, _)<!SYNTAX!><!>) {
|
||||||
|
|
||||||
}<!>
|
}<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
fun useDeclaredVariables() {
|
fun useDeclaredVariables() {
|
||||||
val (<!UNRESOLVED_REFERENCE!>a<!>, <!UNRESOLVED_REFERENCE!>b<!>) = <!UNRESOLVED_REFERENCE!>unresolved<!>
|
val (a, b) = <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING, UNRESOLVED_REFERENCE!>unresolved<!>
|
||||||
a
|
a
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkersShouldRun() {
|
fun checkersShouldRun() {
|
||||||
val (<!UNRESOLVED_REFERENCE!>@A a<!>, _) = <!UNRESOLVED_REFERENCE!>unresolved<!>
|
val (@A a, _) = <!COMPONENT_FUNCTION_MISSING, UNRESOLVED_REFERENCE!>unresolved<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
annotation class A
|
annotation class A
|
||||||
|
|||||||
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
fun useDeclaredVariables() {
|
fun useDeclaredVariables() {
|
||||||
<!INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION!>val (<!UNRESOLVED_REFERENCE!>a<!>, <!UNRESOLVED_REFERENCE!>b<!>)<!>
|
<!INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION!>val (a, b)<!>
|
||||||
a
|
a
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkersShouldRun() {
|
fun checkersShouldRun() {
|
||||||
<!INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION!>val (<!UNRESOLVED_REFERENCE!>@A a<!>, _)<!>
|
<!INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION!>val (@A a, _)<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
annotation class A
|
annotation class A
|
||||||
|
|||||||
+3
-3
@@ -6,12 +6,12 @@ val receiverAndReturnType = { Int.(<!SYNTAX!><!>)<!SYNTAX!>: Int -> 5<!> }
|
|||||||
val receiverAndReturnTypeWithParameter = { Int.(<!UNRESOLVED_REFERENCE!>a<!><!SYNTAX!><!SYNTAX!><!>: Int): Int -> 5<!> }
|
val receiverAndReturnTypeWithParameter = { Int.(<!UNRESOLVED_REFERENCE!>a<!><!SYNTAX!><!SYNTAX!><!>: Int): Int -> 5<!> }
|
||||||
|
|
||||||
val returnType = { (<!SYNTAX!><!>): Int -> 5 }
|
val returnType = { (<!SYNTAX!><!>): Int -> 5 }
|
||||||
val returnTypeWithParameter = { (<!UNRESOLVED_REFERENCE!>b: Int<!>): Int -> 5 }
|
val returnTypeWithParameter = { <!COMPONENT_FUNCTION_MISSING!>(b: Int): Int<!> -> 5 }
|
||||||
|
|
||||||
val receiverWithFunctionType = { ((Int)<!SYNTAX!><!> <!SYNTAX!>-> Int).() -><!> }
|
val receiverWithFunctionType = { ((Int)<!SYNTAX!><!> <!SYNTAX!>-> Int).() -><!> }
|
||||||
|
|
||||||
val parenthesizedParameters = { (<!UNRESOLVED_REFERENCE!>a: Int<!>) -> }
|
val parenthesizedParameters = { <!COMPONENT_FUNCTION_MISSING!>(a: Int)<!> -> }
|
||||||
val parenthesizedParameters2 = { (<!UNRESOLVED_REFERENCE!>b<!>) -> }
|
val parenthesizedParameters2 = { <!COMPONENT_FUNCTION_MISSING!>(b)<!> -> }
|
||||||
|
|
||||||
val none = { -> }
|
val none = { -> }
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -9,7 +9,7 @@ fun <X, Y> foo(y: Y, x: (X, Y) -> Unit) {}
|
|||||||
|
|
||||||
fun bar(aInstance: A, bInstance: B) {
|
fun bar(aInstance: A, bInstance: B) {
|
||||||
foo("") {
|
foo("") {
|
||||||
(<!UNRESOLVED_REFERENCE!>a<!>, <!UNRESOLVED_REFERENCE!>b<!>): A, c ->
|
<!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>(a, b): A<!>, c ->
|
||||||
a <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
a <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
b <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
b <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
c checkType { _<String>() }
|
c checkType { _<String>() }
|
||||||
|
|||||||
Vendored
+4
-4
@@ -4,28 +4,28 @@
|
|||||||
data class A(val x: Int, val y: String)
|
data class A(val x: Int, val y: String)
|
||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
val x = { (<!UNRESOLVED_REFERENCE!>a<!>, <!UNRESOLVED_REFERENCE!>b<!>): A ->
|
val x = { <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>(a, b): A<!> ->
|
||||||
a <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
a <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
b <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
b <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
x checkType { _<(A) -> Unit>() }
|
x checkType { _<(A) -> Unit>() }
|
||||||
|
|
||||||
val y = { (<!UNRESOLVED_REFERENCE!>a: Int<!>, <!UNRESOLVED_REFERENCE!>b<!>): A ->
|
val y = { <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>(a: Int, b): A<!> ->
|
||||||
a checkType { _<Int>() }
|
a checkType { _<Int>() }
|
||||||
b <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
b <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
y checkType { _<(A) -> Unit>() }
|
y checkType { _<(A) -> Unit>() }
|
||||||
|
|
||||||
val y2 = { (<!UNRESOLVED_REFERENCE!>a: Number<!>, <!UNRESOLVED_REFERENCE!>b<!>): A ->
|
val y2 = { <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>(a: Number, b): A<!> ->
|
||||||
a checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
a checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
b <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
b <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
y2 checkType { _<(A) -> Unit>() }
|
y2 checkType { _<(A) -> Unit>() }
|
||||||
|
|
||||||
val z = { (<!UNRESOLVED_REFERENCE!>a: Int<!>, <!UNRESOLVED_REFERENCE!>b: String<!>) ->
|
val z = { <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>(a: Int, b: String)<!> ->
|
||||||
a checkType { _<Int>() }
|
a checkType { _<Int>() }
|
||||||
b checkType { _<String>() }
|
b checkType { _<String>() }
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -46,5 +46,5 @@ fun foo() {
|
|||||||
propertyWithType: Int
|
propertyWithType: Int
|
||||||
|
|
||||||
val
|
val
|
||||||
(<!UNRESOLVED_REFERENCE!>a<!>, <!UNRESOLVED_REFERENCE!>b<!>) = 1
|
(a, b) = <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>1<!>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user