[FIR] Add NOTHING_TO_INLINE diagnostic
This commit is contained in:
committed by
teamcityserver
parent
28344c8530
commit
015c2d1875
@@ -1,5 +1,5 @@
|
||||
// !DUMP_CFG
|
||||
inline fun foo(vararg x: Any) {}
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun foo(vararg x: Any) {}
|
||||
|
||||
fun test(a: Any, b: Any, c: Any) {
|
||||
foo(a, { "" }, b)
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@ fun f() {
|
||||
LocalClass().foo = 1
|
||||
}
|
||||
|
||||
internal inline fun internal() {
|
||||
internal <!NOTHING_TO_INLINE!>inline<!> fun internal() {
|
||||
f()
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -1134,6 +1134,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<String>("message")
|
||||
}
|
||||
|
||||
val NOTHING_TO_INLINE by warning<KtDeclaration>(PositioningStrategy.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT)
|
||||
|
||||
val RECURSION_IN_INLINE by error<KtElement>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
|
||||
parameter<Symbol>("symbol")
|
||||
}
|
||||
|
||||
@@ -599,6 +599,7 @@ object FirErrors {
|
||||
val USAGE_IS_NOT_INLINABLE by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val NON_LOCAL_RETURN_NOT_ALLOWED by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val NOT_YET_SUPPORTED_IN_INLINE by error1<KtDeclaration, String>(SourceElementPositioningStrategies.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT)
|
||||
val NOTHING_TO_INLINE by warning0<KtDeclaration>(SourceElementPositioningStrategies.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT)
|
||||
val RECURSION_IN_INLINE by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val NON_PUBLIC_CALL_FROM_PUBLIC_INLINE by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
+18
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.PersistentCheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isInlineOnly
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.util.checkChildrenWithCustomVisitor
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
@@ -30,6 +31,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.isMarkedNullable
|
||||
import org.jetbrains.kotlin.fir.types.isNullable
|
||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -47,6 +49,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
|
||||
val effectiveVisibility = declaration.effectiveVisibility
|
||||
checkInlineFunctionBody(declaration, effectiveVisibility, context, reporter)
|
||||
checkParameters(declaration, context, reporter)
|
||||
checkNothingToInline(declaration, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkInlineFunctionBody(
|
||||
@@ -374,6 +377,21 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkNothingToInline(function: FirFunction, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (function !is FirSimpleFunction) return
|
||||
if (function.isExpect || function.isSuspend) return
|
||||
if (function.typeParameters.any { it.symbol.isReified }) return
|
||||
val hasInlinableParameters =
|
||||
function.valueParameters.any { param ->
|
||||
val type = param.returnTypeRef.coneType
|
||||
!param.isNoinline && !type.isNullable
|
||||
&& (type.isFunctionalType(context.session) || type.isSuspendFunctionType(context.session))
|
||||
}
|
||||
if (hasInlinableParameters) return
|
||||
if (function.isInlineOnly()) return
|
||||
|
||||
reporter.reportOn(function.source, FirErrors.NOTHING_TO_INLINE, context)
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -270,6 +270,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_CONST
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_VARARG_SPREAD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOTHING_TO_INLINE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOTHING_TO_OVERRIDE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_LOOP_LABEL
|
||||
@@ -1483,6 +1484,10 @@ class FirDefaultErrorMessages {
|
||||
SYMBOL
|
||||
)
|
||||
map.put(NOT_YET_SUPPORTED_IN_INLINE, "{0} are not yet supported in inline functions", STRING)
|
||||
map.put(
|
||||
NOTHING_TO_INLINE,
|
||||
"Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types"
|
||||
)
|
||||
map.put(SUPER_CALL_FROM_PUBLIC_INLINE, "Accessing super members from public-API inline function is deprecated", SYMBOL)
|
||||
|
||||
//imports
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
fun find2(): Any? {
|
||||
fun visit(element: Any) {
|
||||
<!RETURN_NOT_ALLOWED!>return@find2<!> element
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// For find(): AssertionError at ControlFlowInstructionsGeneratorWorker.getExitPoint()
|
||||
|
||||
fun find(): Any? {
|
||||
object : Any() {
|
||||
fun visit(element: Any) {
|
||||
<!RETURN_NOT_ALLOWED!>return@find<!> element
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun find4(): Any? {
|
||||
<!NOT_YET_SUPPORTED_IN_INLINE!>inline<!> fun visit(element: Any) {
|
||||
<!RETURN_NOT_ALLOWED!>return@find4<!> element
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun find3(): Any? {
|
||||
object : Any() {
|
||||
inline fun visit(element: Any) {
|
||||
<!RETURN_NOT_ALLOWED!>return@find3<!> element
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
fun find2(): Any? {
|
||||
fun visit(element: Any) {
|
||||
<!RETURN_NOT_ALLOWED!>return@find2<!> element
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ fun bar(arg: String) = arg
|
||||
|
||||
class Derived : Base("123") {
|
||||
|
||||
private inline fun foo() {
|
||||
private <!NOTHING_TO_INLINE!>inline<!> fun foo() {
|
||||
bar(<!INVISIBLE_REFERENCE!>v<!>)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
inline fun <R> onlyLocal(p: () -> R) {
|
||||
inlineAll(<!USAGE_IS_NOT_INLINABLE!>p<!>)
|
||||
}
|
||||
|
||||
inline fun <R> inlineAll(noinline p: () -> R) {
|
||||
p()
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
inline fun <R> onlyLocal(p: () -> R) {
|
||||
inlineAll(<!USAGE_IS_NOT_INLINABLE!>p<!>)
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
inline fun inlineFun() {
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun inlineFun() {
|
||||
<!NOT_YET_SUPPORTED_IN_INLINE!>fun<!> localFun() {}
|
||||
<!NOT_YET_SUPPORTED_IN_INLINE!>class<!> LocalClass {}
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@ fun box() : String {
|
||||
return "OK"
|
||||
}
|
||||
|
||||
inline fun <T> test(p: T) {
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun <T> test(p: T) {
|
||||
p.toString()
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,6 +6,6 @@ fun box() : String {
|
||||
return "OK"
|
||||
}
|
||||
|
||||
inline fun test(p: Any) {
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun test(p: Any) {
|
||||
p.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
inline fun foo() {
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun foo() {
|
||||
<!UNRESOLVED_REFERENCE!>unresolved<!>().another
|
||||
<!UNRESOLVED_REFERENCE!>unresolved<!>().another()
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NULLABLE_INLINE_PARAMETER -CONFLICTING_JVM_DECLARATIONS
|
||||
|
||||
inline fun test() {
|
||||
|
||||
}
|
||||
|
||||
inline fun test2(s : (Int) -> Int) {
|
||||
|
||||
}
|
||||
|
||||
inline fun test3(noinline s : (Int) -> Int) {
|
||||
|
||||
}
|
||||
|
||||
inline fun test4(noinline s : Int.() -> Int) {
|
||||
|
||||
}
|
||||
|
||||
inline fun Function1<Int, Int>?.test5() {
|
||||
|
||||
}
|
||||
|
||||
inline fun Function1<Int, Int>?.test6() {
|
||||
|
||||
}
|
||||
|
||||
inline fun test2(s : ((Int) -> Int)?) {
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NULLABLE_INLINE_PARAMETER -CONFLICTING_JVM_DECLARATIONS
|
||||
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun test() {
|
||||
|
||||
@@ -12,10 +12,10 @@ public inline fun <T> submitNoInline(noinline action: Function1<Int, Int>?, s: (
|
||||
action?.invoke(10)
|
||||
}
|
||||
|
||||
public inline fun <T> Function1<Int, Int>?.submit() {
|
||||
public <!NOTHING_TO_INLINE!>inline<!> fun <T> Function1<Int, Int>?.submit() {
|
||||
|
||||
}
|
||||
|
||||
public inline fun <T> submit(action: Function1<Int, Int>?) {
|
||||
public <!NOTHING_TO_INLINE!>inline<!> fun <T> submit(action: Function1<Int, Int>?) {
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
|
||||
(<!USAGE_IS_NOT_INLINABLE!>s<!>)
|
||||
}
|
||||
|
||||
inline fun Function1<Int, Unit>.inlineExt() {
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun Function1<Int, Unit>.inlineExt() {
|
||||
(this).invoke(11)
|
||||
(this) <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
|
||||
(this)(11)
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
inline fun inlineFun(s: (p: Int) -> Unit) : (p: Int) -> Unit {
|
||||
return <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
}
|
||||
|
||||
inline fun inlineFun2(s: (p: Int) -> Unit) : (p: Int) -> Unit = <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
|
||||
|
||||
inline fun inlineFunWithExt(ext: Int.(p: Int) -> Unit) : Int.(p: Int) -> Unit {
|
||||
return <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
|
||||
inline fun inlineFunWithExt2(ext: Int.(p: Int) -> Unit) : Int.(p: Int) -> Unit = <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
|
||||
|
||||
|
||||
inline fun Function1<Int, Unit>.inlineExt(): Function1<Int, Unit> {
|
||||
return this
|
||||
}
|
||||
|
||||
inline fun Function1<Int, Unit>.inlineExt2(): Function1<Int, Unit> = this
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
inline fun inlineFun(s: (p: Int) -> Unit) : (p: Int) -> Unit {
|
||||
return <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
// !DIAGNOSTICS: -NON_LOCAL_RETURN_NOT_ALLOWED
|
||||
// FILE: Run.java
|
||||
public interface Run {
|
||||
public int run();
|
||||
}
|
||||
|
||||
|
||||
// FILE: Test.java
|
||||
public class Test {
|
||||
public void test(Run r) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
inline fun inlineFunWithInvoke(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {
|
||||
Test().test(){
|
||||
s(11)
|
||||
s.invoke(11)
|
||||
s <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
|
||||
|
||||
11.ext(11)
|
||||
11 <!INFIX_MODIFIER_REQUIRED!>ext<!> 11
|
||||
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
11
|
||||
}
|
||||
}
|
||||
|
||||
inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {
|
||||
Test().test(){
|
||||
s(11)
|
||||
s.invoke(11)
|
||||
s <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
|
||||
|
||||
11.ext(11)
|
||||
11 <!INFIX_MODIFIER_REQUIRED!>ext<!> 11
|
||||
|
||||
s
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
|
||||
11
|
||||
}
|
||||
}
|
||||
|
||||
inline fun Function1<Int, Unit>.inlineExt() {
|
||||
Test().test(){
|
||||
invoke(11)
|
||||
this.invoke(11)
|
||||
this <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
|
||||
this(11)
|
||||
|
||||
this
|
||||
|
||||
11
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -NON_LOCAL_RETURN_NOT_ALLOWED
|
||||
// FILE: Run.java
|
||||
public interface Run {
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
inline fun foo(noinline x: Int) {}
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun foo(noinline x: Int) {}
|
||||
|
||||
inline fun bar(y: Int, crossinline x: String) {}
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun bar(y: Int, crossinline x: String) {}
|
||||
|
||||
fun gav(noinline x: (Int) -> Unit, crossinline y: (String) -> Int) {}
|
||||
|
||||
inline fun correct(noinline x: (Int) -> Unit, crossinline y: (String) -> Int) {}
|
||||
|
||||
inline fun incompatible(<!INCOMPATIBLE_MODIFIERS!>noinline<!> <!INCOMPATIBLE_MODIFIERS!>crossinline<!> x: () -> String) {}
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun incompatible(<!INCOMPATIBLE_MODIFIERS!>noinline<!> <!INCOMPATIBLE_MODIFIERS!>crossinline<!> x: () -> String) {}
|
||||
|
||||
class FunctionSubtype : () -> Unit {
|
||||
override fun invoke() {}
|
||||
}
|
||||
|
||||
inline fun functionSubtype(
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun functionSubtype(
|
||||
noinline f: FunctionSubtype,
|
||||
crossinline g: FunctionSubtype
|
||||
) { }
|
||||
|
||||
+2
-2
@@ -14,5 +14,5 @@ actual fun nonInlineFun() { }
|
||||
// MODULE: m3-js()()(m1-common)
|
||||
// FILE: js.kt
|
||||
|
||||
actual inline fun inlineFun() { }
|
||||
actual inline fun nonInlineFun() { }
|
||||
actual <!NOTHING_TO_INLINE!>inline<!> fun inlineFun() { }
|
||||
actual <!NOTHING_TO_INLINE!>inline<!> fun nonInlineFun() { }
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
// SKIP_TXT
|
||||
inline fun foo1(x: suspend () -> Unit) {}
|
||||
inline fun foo2(crossinline x: suspend () -> Unit) {}
|
||||
inline fun foo3(noinline x: suspend () -> Unit) {}
|
||||
inline fun foo4(<!INCOMPATIBLE_MODIFIERS!>noinline<!> <!INCOMPATIBLE_MODIFIERS!>crossinline<!> x: suspend () -> Unit) {}
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun foo3(noinline x: suspend () -> Unit) {}
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun foo4(<!INCOMPATIBLE_MODIFIERS!>noinline<!> <!INCOMPATIBLE_MODIFIERS!>crossinline<!> x: suspend () -> Unit) {}
|
||||
|
||||
suspend inline fun bar1(x: suspend () -> Unit) {}
|
||||
suspend inline fun bar2(crossinline x: suspend () -> Unit) {}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import kotlin.jvm.*
|
||||
|
||||
abstract class C {
|
||||
inline external fun foo()
|
||||
<!NOTHING_TO_INLINE!>inline<!> external fun foo()
|
||||
}
|
||||
|
||||
fun test() {
|
||||
abstract class Local {
|
||||
inline external fun foo()
|
||||
<!NOTHING_TO_INLINE!>inline<!> external fun foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION -EXTENSION_SHADOWED_BY_MEMBER
|
||||
// SKIP_TXT
|
||||
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-268
|
||||
* MAIN LINK: overload-resolution, building-the-overload-candidate-set-ocs, operator-call -> paragraph 2 -> sentence 3
|
||||
* PRIMARY LINKS: overload-resolution, building-the-overload-candidate-set-ocs, call-with-an-explicit-receiver -> paragraph 6 -> sentence 5
|
||||
* overload-resolution, building-the-overload-candidate-set-ocs, operator-call -> paragraph 4 -> sentence 1
|
||||
* NUMBER: 5
|
||||
* DESCRIPTION: Star-imported extension callables
|
||||
*/
|
||||
|
||||
|
||||
// FILE: LibCase1.kt
|
||||
// TESTCASE NUMBER: 1
|
||||
package libPackage
|
||||
import testPackCase1.Case
|
||||
import testPackCase1.Case.Inv
|
||||
import testPackCase1.Case.E
|
||||
|
||||
operator fun Case.E.plus(value: Int) = Inv()
|
||||
operator fun Case.Inv.invoke(i: Int) = 1
|
||||
|
||||
|
||||
// FILE: TestCase11.kt
|
||||
// TESTCASE NUMBER: 1
|
||||
package testPackCase1
|
||||
import libPackage.*
|
||||
|
||||
class Case() {
|
||||
class E(val plus: Inv? = null) {
|
||||
/*operator*/ fun plus(value: Int) = Case()
|
||||
}
|
||||
|
||||
class Inv() {
|
||||
/*operator*/ fun invoke(value: Int) = Case()
|
||||
}
|
||||
|
||||
fun foo(e: E) {
|
||||
/*operator*/ fun E.plus(value: Int) = Case()
|
||||
|
||||
run {
|
||||
<!DEBUG_INFO_CALL("fqName: libPackage.plus; typeCall: operator extension function")!>e + 1<!>
|
||||
}
|
||||
<!DEBUG_INFO_CALL("fqName: libPackage.plus; typeCall: operator extension function")!>e + 1<!>
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: Lib1.kt
|
||||
// TESTCASE NUMBER: 2
|
||||
package libPackage1
|
||||
|
||||
public inline operator fun CharSequence.contains(regex: Regex): Boolean = regex.containsMatchIn(this)
|
||||
|
||||
// FILE: TestCase12.kt
|
||||
// TESTCASE NUMBER: 2
|
||||
package testPackCase2
|
||||
import libPackage1.*
|
||||
class Case() {
|
||||
|
||||
fun foo() {
|
||||
"".<!DEBUG_INFO_CALL("fqName: libPackage1.contains; typeCall: inline operator extension function")!>contains(Regex(""))<!>
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: LibCase3.kt
|
||||
// TESTCASE NUMBER: 3
|
||||
package libPackage
|
||||
import testPackCase3.Case
|
||||
import testPackCase3.Case.Inv
|
||||
import testPackCase3.Case.E
|
||||
|
||||
operator fun Case.E.plusAssign(value: Int) {}
|
||||
operator fun Case.Inv.invoke(i: Int) {}
|
||||
|
||||
|
||||
// FILE: TestCase3.kt
|
||||
// TESTCASE NUMBER: 1
|
||||
package testPackCase3
|
||||
import libPackage.*
|
||||
|
||||
class Case() {
|
||||
class E(val plusAssign: Inv? = null) {
|
||||
/*operator*/ fun plusAssign(value: Int) {}
|
||||
}
|
||||
|
||||
class Inv() {
|
||||
/*operator*/ fun invoke(value: Int) {}
|
||||
}
|
||||
|
||||
fun foo(e: E) {
|
||||
/*operator*/ fun E.plusAssign(value: Int) {}
|
||||
|
||||
run {
|
||||
<!DEBUG_INFO_CALL("fqName: libPackage.plusAssign; typeCall: operator extension function")!>e += 1<!>
|
||||
}
|
||||
<!DEBUG_INFO_CALL("fqName: libPackage.plusAssign; typeCall: operator extension function")!>e += 1<!>
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION -EXTENSION_SHADOWED_BY_MEMBER
|
||||
// SKIP_TXT
|
||||
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
// SKIP_TXT
|
||||
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-268
|
||||
* MAIN LINK: overload-resolution, building-the-overload-candidate-set-ocs, operator-call -> paragraph 2 -> sentence 3
|
||||
* PRIMARY LINKS: overload-resolution, building-the-overload-candidate-set-ocs, call-with-an-explicit-receiver -> paragraph 6 -> sentence 5
|
||||
* overload-resolution, building-the-overload-candidate-set-ocs, operator-call -> paragraph 4 -> sentence 1
|
||||
* NUMBER: 6
|
||||
* DESCRIPTION: Star-imported extension callables
|
||||
*/
|
||||
|
||||
|
||||
// FILE: LibCase1.kt
|
||||
// TESTCASE NUMBER: 1
|
||||
package libPackage
|
||||
|
||||
/*public*/ private inline operator fun CharSequence.contains(regex: Regex): Boolean = regex.containsMatchIn(this)
|
||||
|
||||
|
||||
// FILE: TestCase1.kt
|
||||
// TESTCASE NUMBER: 1
|
||||
package testPackCase1
|
||||
import libPackage.*
|
||||
|
||||
class Case() {
|
||||
|
||||
fun foo() {
|
||||
"".<!DEBUG_INFO_CALL("fqName: kotlin.text.contains; typeCall: inline operator extension function")!>contains(Regex(""))<!>
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
// SKIP_TXT
|
||||
|
||||
+6
@@ -3099,6 +3099,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.NOTHING_TO_INLINE) { firDiagnostic ->
|
||||
NothingToInlineImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.RECURSION_IN_INLINE) { firDiagnostic ->
|
||||
RecursionInInlineImpl(
|
||||
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
|
||||
|
||||
+4
@@ -2160,6 +2160,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val message: String
|
||||
}
|
||||
|
||||
abstract class NothingToInline : KtFirDiagnostic<KtDeclaration>() {
|
||||
override val diagnosticClass get() = NothingToInline::class
|
||||
}
|
||||
|
||||
abstract class RecursionInInline : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = RecursionInInline::class
|
||||
abstract val symbol: KtSymbol
|
||||
|
||||
+7
@@ -3490,6 +3490,13 @@ internal class NotYetSupportedInInlineImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class NothingToInlineImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.NothingToInline(), KtAbstractFirDiagnostic<KtDeclaration> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RecursionInInlineImpl(
|
||||
override val symbol: KtSymbol,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
|
||||
Reference in New Issue
Block a user