Stop tower resolve in K2 in more similar manner with K1
This commit is contained in:
@@ -835,7 +835,7 @@ class AllCandidatesCollector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We want to get candidates at all tower levels.
|
// We want to get candidates at all tower levels.
|
||||||
override fun shouldStopAtTheLevel(group: TowerGroup): Boolean = false
|
override fun shouldStopAtTheGroup(group: TowerGroup): Boolean = false
|
||||||
|
|
||||||
val allCandidates: List<Candidate>
|
val allCandidates: List<Candidate>
|
||||||
get() = allCandidatesSet.toList()
|
get() = allCandidatesSet.toList()
|
||||||
|
|||||||
+5
-5
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
@@ -24,8 +24,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.extractInputOutputTypesFromCal
|
|||||||
import org.jetbrains.kotlin.fir.types.isSuspendFunctionType
|
import org.jetbrains.kotlin.fir.types.isSuspendFunctionType
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
|
|
||||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
@@ -53,7 +51,9 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
|
|||||||
val resultingType = candidate.substitutor.substituteOrSelf(rawResultingType)
|
val resultingType = candidate.substitutor.substituteOrSelf(rawResultingType)
|
||||||
|
|
||||||
if (callableReferenceAdaptation.needCompatibilityResolveForCallableReference()) {
|
if (callableReferenceAdaptation.needCompatibilityResolveForCallableReference()) {
|
||||||
sink.reportDiagnostic(LowerPriorityToPreserveCompatibilityDiagnostic)
|
if (!context.session.languageVersionSettings.supportsFeature(LanguageFeature.DisableCompatibilityModeForNewInference)) {
|
||||||
|
sink.reportDiagnostic(LowerPriorityToPreserveCompatibilityDiagnostic)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
candidate.resultingTypeForCallableReference = resultingType
|
candidate.resultingTypeForCallableReference = resultingType
|
||||||
|
|||||||
+9
-6
@@ -8,8 +8,9 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerGroup
|
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerGroup
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability.DSL_SCOPE_VIOLATION
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability.K2_SYNTHETIC_RESOLVED
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.shouldStopResolve
|
|
||||||
|
|
||||||
open class CandidateCollector(
|
open class CandidateCollector(
|
||||||
val components: BodyResolveComponents,
|
val components: BodyResolveComponents,
|
||||||
@@ -48,10 +49,12 @@ open class CandidateCollector(
|
|||||||
|
|
||||||
fun bestCandidates(): List<Candidate> = candidates
|
fun bestCandidates(): List<Candidate> = candidates
|
||||||
|
|
||||||
open fun shouldStopAtTheLevel(group: TowerGroup): Boolean =
|
open fun shouldStopAtTheGroup(group: TowerGroup): Boolean =
|
||||||
currentApplicability.shouldStopResolve && bestGroup < group
|
shouldStopResolve && bestGroup < group
|
||||||
|
|
||||||
fun isSuccess(): Boolean {
|
private val shouldStopResolve: Boolean
|
||||||
return currentApplicability.isSuccess
|
get() = currentApplicability == DSL_SCOPE_VIOLATION || currentApplicability >= K2_SYNTHETIC_RESOLVED
|
||||||
}
|
|
||||||
|
val isSuccess: Boolean
|
||||||
|
get() = currentApplicability.isSuccess
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -504,7 +504,7 @@ internal object EagerResolveOfCallableReferences : CheckerStage() {
|
|||||||
internal object DiscriminateSynthetics : CheckerStage() {
|
internal object DiscriminateSynthetics : CheckerStage() {
|
||||||
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
||||||
if (candidate.symbol is SyntheticSymbol) {
|
if (candidate.symbol is SyntheticSymbol) {
|
||||||
sink.reportDiagnostic(ResolvedWithLowPriority)
|
sink.reportDiagnostic(ResolvedWithSynthetic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls.tower
|
package org.jetbrains.kotlin.fir.resolve.calls.tower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||||
@@ -316,7 +315,7 @@ private fun BodyResolveComponents.createExplicitReceiverForInvokeByCallable(
|
|||||||
explicitReceiver = info.explicitReceiver
|
explicitReceiver = info.explicitReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
if (candidate.currentApplicability == CandidateApplicability.PROPERTY_AS_OPERATOR) {
|
if (candidate.currentApplicability == CandidateApplicability.K2_PROPERTY_AS_OPERATOR) {
|
||||||
nonFatalDiagnostics.add(ConePropertyAsOperator(candidate.symbol as FirPropertySymbol))
|
nonFatalDiagnostics.add(ConePropertyAsOperator(candidate.symbol as FirPropertySymbol))
|
||||||
}
|
}
|
||||||
}.build().let(::transformQualifiedAccessUsingSmartcastInfo)
|
}.build().let(::transformQualifiedAccessUsingSmartcastInfo)
|
||||||
|
|||||||
+1
-1
@@ -164,7 +164,7 @@ internal abstract class FirBaseTowerResolveTask(
|
|||||||
finalGroup,
|
finalGroup,
|
||||||
towerLevel
|
towerLevel
|
||||||
)
|
)
|
||||||
if (collector.isSuccess()) onSuccessfulLevel(finalGroup)
|
if (collector.isSuccess) onSuccessfulLevel(finalGroup)
|
||||||
return result == ProcessResult.SCOPE_EMPTY
|
return result == ProcessResult.SCOPE_EMPTY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@ internal class TowerLevelHandler {
|
|||||||
CallKind.VariableAccess -> {
|
CallKind.VariableAccess -> {
|
||||||
processResult += towerLevel.processPropertiesByName(info, processor)
|
processResult += towerLevel.processPropertiesByName(info, processor)
|
||||||
|
|
||||||
if (!collector.isSuccess() && towerLevel is ScopeTowerLevel && !towerLevel.areThereExtensionReceiverOptions()) {
|
if (!collector.isSuccess && towerLevel is ScopeTowerLevel && !towerLevel.areThereExtensionReceiverOptions()) {
|
||||||
processResult += towerLevel.processObjectsByName(info, processor)
|
processResult += towerLevel.processObjectsByName(info, processor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ import kotlin.coroutines.resume
|
|||||||
|
|
||||||
class TowerResolveManager private constructor(private val shouldStopAtTheLevel: (TowerGroup) -> Boolean) {
|
class TowerResolveManager private constructor(private val shouldStopAtTheLevel: (TowerGroup) -> Boolean) {
|
||||||
|
|
||||||
constructor(collector: CandidateCollector) : this(collector::shouldStopAtTheLevel)
|
constructor(collector: CandidateCollector) : this(collector::shouldStopAtTheGroup)
|
||||||
|
|
||||||
private val queue = PriorityQueue<SuspendedResolverTask>()
|
private val queue = PriorityQueue<SuspendedResolverTask>()
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -149,7 +149,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
|
|
||||||
result.replaceContextReceiverArguments(subCandidate.contextReceiverArguments())
|
result.replaceContextReceiverArguments(subCandidate.contextReceiverArguments())
|
||||||
|
|
||||||
if (result is FirPropertyAccessExpressionImpl && calleeReference.candidate.currentApplicability == CandidateApplicability.PROPERTY_AS_OPERATOR) {
|
if (result is FirPropertyAccessExpressionImpl && calleeReference.candidate.currentApplicability == CandidateApplicability.K2_PROPERTY_AS_OPERATOR) {
|
||||||
result.nonFatalDiagnostics.add(ConePropertyAsOperator(calleeReference.candidate.symbol as FirPropertySymbol))
|
result.nonFatalDiagnostics.add(ConePropertyAsOperator(calleeReference.candidate.symbol as FirPropertySymbol))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -84,6 +84,8 @@ object VisibilityError : ResolutionDiagnostic(VISIBILITY_ERROR)
|
|||||||
|
|
||||||
object ResolvedWithLowPriority : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
object ResolvedWithLowPriority : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
||||||
|
|
||||||
|
object ResolvedWithSynthetic : ResolutionDiagnostic(K2_SYNTHETIC_RESOLVED)
|
||||||
|
|
||||||
class InapplicableWrongReceiver(
|
class InapplicableWrongReceiver(
|
||||||
val expectedType: ConeKotlinType? = null,
|
val expectedType: ConeKotlinType? = null,
|
||||||
val actualType: ConeKotlinType? = null,
|
val actualType: ConeKotlinType? = null,
|
||||||
@@ -123,7 +125,7 @@ class OperatorCallOfNonOperatorFunction(val function: FirNamedFunctionSymbol) :
|
|||||||
class InferenceError(val constraintError: ConstraintSystemError) : ResolutionDiagnostic(constraintError.applicability)
|
class InferenceError(val constraintError: ConstraintSystemError) : ResolutionDiagnostic(constraintError.applicability)
|
||||||
class Unsupported(val message: String, val source: KtSourceElement? = null) : ResolutionDiagnostic(UNSUPPORTED)
|
class Unsupported(val message: String, val source: KtSourceElement? = null) : ResolutionDiagnostic(UNSUPPORTED)
|
||||||
|
|
||||||
object PropertyAsOperator : ResolutionDiagnostic(PROPERTY_AS_OPERATOR)
|
object PropertyAsOperator : ResolutionDiagnostic(K2_PROPERTY_AS_OPERATOR)
|
||||||
|
|
||||||
class DslScopeViolation(val calleeSymbol: FirBasedSymbol<*>) : ResolutionDiagnostic(DSL_SCOPE_VIOLATION)
|
class DslScopeViolation(val calleeSymbol: FirBasedSymbol<*>) : ResolutionDiagnostic(DSL_SCOPE_VIOLATION)
|
||||||
|
|
||||||
|
|||||||
+2
-4
@@ -26,14 +26,12 @@ enum class CandidateApplicability {
|
|||||||
|
|
||||||
// Below has isSuccess = true
|
// Below has isSuccess = true
|
||||||
RESOLVED_LOW_PRIORITY,
|
RESOLVED_LOW_PRIORITY,
|
||||||
PROPERTY_AS_OPERATOR, // using property of functional type as an operator. From resolution perspective, this is considered successful.
|
K2_PROPERTY_AS_OPERATOR, // using property of functional type as an operator. From resolution perspective, this is considered successful.
|
||||||
RESOLVED_NEED_PRESERVE_COMPATIBILITY, // call resolved successfully, but using new features that changes resolve
|
RESOLVED_NEED_PRESERVE_COMPATIBILITY, // call resolved successfully, but using new features that changes resolve
|
||||||
|
K2_SYNTHETIC_RESOLVED, // used in K2 for (Java) synthetic discrimination at the same level
|
||||||
RESOLVED_WITH_ERROR, // call has error, but it is still successful from resolution perspective
|
RESOLVED_WITH_ERROR, // call has error, but it is still successful from resolution perspective
|
||||||
RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate
|
RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate
|
||||||
}
|
}
|
||||||
|
|
||||||
val CandidateApplicability.isSuccess: Boolean
|
val CandidateApplicability.isSuccess: Boolean
|
||||||
get() = this >= CandidateApplicability.RESOLVED_LOW_PRIORITY
|
get() = this >= CandidateApplicability.RESOLVED_LOW_PRIORITY
|
||||||
|
|
||||||
val CandidateApplicability.shouldStopResolve: Boolean
|
|
||||||
get() = this >= CandidateApplicability.DSL_SCOPE_VIOLATION
|
|
||||||
|
|||||||
@@ -150,7 +150,6 @@ class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType) : Resoluti
|
|||||||
object ErrorDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED) // todo discuss and change to INAPPLICABLE
|
object ErrorDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED) // todo discuss and change to INAPPLICABLE
|
||||||
object LowPriorityDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
object LowPriorityDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
||||||
object DynamicDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
object DynamicDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
||||||
object ResolvedUsingNewFeatures : ResolutionDiagnostic(RESOLVED_NEED_PRESERVE_COMPATIBILITY)
|
|
||||||
object UnstableSmartCastDiagnostic : ResolutionDiagnostic(UNSTABLE_SMARTCAST)
|
object UnstableSmartCastDiagnostic : ResolutionDiagnostic(UNSTABLE_SMARTCAST)
|
||||||
object HiddenExtensionRelatedToDynamicTypes : ResolutionDiagnostic(HIDDEN)
|
object HiddenExtensionRelatedToDynamicTypes : ResolutionDiagnostic(HIDDEN)
|
||||||
object HiddenDescriptor : ResolutionDiagnostic(HIDDEN)
|
object HiddenDescriptor : ResolutionDiagnostic(HIDDEN)
|
||||||
|
|||||||
-2
@@ -1,8 +1,6 @@
|
|||||||
// !LANGUAGE: +SuspendConversion
|
// !LANGUAGE: +SuspendConversion
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// FIR status: java.lang.Integer cannot be cast to java.lang.String
|
|
||||||
|
|
||||||
object Test1 {
|
object Test1 {
|
||||||
fun foo(f: () -> Unit) {}
|
fun foo(f: () -> Unit) {}
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ object Scope {
|
|||||||
fun test() {
|
fun test() {
|
||||||
// Despite the fact ::bar is resolved with compatibility warning, it's important not to propagate it to the outer call
|
// Despite the fact ::bar is resolved with compatibility warning, it's important not to propagate it to the outer call
|
||||||
val result = <!DEBUG_INFO_CALL("fqName: Scope.foo; typeCall: function")!>foo(::bar)<!>
|
val result = <!DEBUG_INFO_CALL("fqName: Scope.foo; typeCall: function")!>foo(::bar)<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>result<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit")!>result<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vendored
+2
-2
@@ -9,7 +9,7 @@ object Test1 {
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val result = foo(::bar)
|
val result = foo(::bar)
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>result<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>result<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ object Test3 {
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val result = foo(::bar)
|
val result = foo(::bar)
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>result<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>result<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -12,7 +12,7 @@ object Test1 {
|
|||||||
fun foo(r: KRunnable) {}
|
fun foo(r: KRunnable) {}
|
||||||
|
|
||||||
fun test(f: () -> Unit) {
|
fun test(f: () -> Unit) {
|
||||||
<!DEBUG_INFO_CALL("fqName: Test1.Scope.foo; typeCall: function")!>foo(f)<!>
|
<!DEBUG_INFO_CALL("fqName: Test1.foo; typeCall: function")!>foo(f)<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -18,7 +18,7 @@ object Test1 {
|
|||||||
fun foo(r: Runnable) {}
|
fun foo(r: Runnable) {}
|
||||||
|
|
||||||
fun test(f: () -> Unit) {
|
fun test(f: () -> Unit) {
|
||||||
<!DEBUG_INFO_CALL("fqName: Test1.Scope.foo; typeCall: function")!>foo(f)<!>
|
<!DEBUG_INFO_CALL("fqName: Test1.foo; typeCall: function")!>foo(f)<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ object Test5 {
|
|||||||
fun foo(r: Runnable) {}
|
fun foo(r: Runnable) {}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
<!DEBUG_INFO_CALL("fqName: Test5.Scope.foo; typeCall: function")!>foo { }<!>
|
<!DEBUG_INFO_CALL("fqName: Test5.foo; typeCall: function")!>foo { }<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vendored
+1
-1
@@ -12,7 +12,7 @@ object Test1 {
|
|||||||
fun call(r: SuspendRunnable) {}
|
fun call(r: SuspendRunnable) {}
|
||||||
|
|
||||||
fun bar(f: () -> Unit) {
|
fun bar(f: () -> Unit) {
|
||||||
<!DEBUG_INFO_CALL("fqName: Test1.Scope.call; typeCall: function")!>call(f)<!>
|
<!DEBUG_INFO_CALL("fqName: Test1.call; typeCall: function")!>call(f)<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -22,7 +22,7 @@ object Test2 {
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val result = foo(::bar)
|
val result = foo(::bar)
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>result<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>result<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ object Test2 {
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val result = foo(::bar)
|
val result = foo(::bar)
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>result<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>result<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -17,5 +17,5 @@ fun bar(x: MutableList<String>, y: java.util.ArrayList<String>, z: A) {
|
|||||||
x.<!DEPRECATION_ERROR!>sort<!> { a, b -> a.length - b.length }
|
x.<!DEPRECATION_ERROR!>sort<!> { a, b -> a.length - b.length }
|
||||||
y.sort { a, b -> a.length - b.length }
|
y.sort { a, b -> a.length - b.length }
|
||||||
|
|
||||||
z.sort { a, b -> a.length - b.length }
|
z.<!DEPRECATION_ERROR!>sort<!> { a, b -> a.length - b.length }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user