K2 IC: add lookups of candidates on tower level processing

Allow recording lookup to symbols from supertypes, required at least
for CRI.

partially fixes #KTIJ-29026
This commit is contained in:
Ilya Chernikov
2024-03-07 15:29:06 +01:00
committed by Space Team
parent 39b05a0a1c
commit 4fafa4b6e9
15 changed files with 65 additions and 24 deletions
@@ -454,14 +454,16 @@ internal class ScopeTowerLevel(
info: CallInfo, info: CallInfo,
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>> processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
): ProcessResult { ): ProcessResult {
val lookupTracker = session.lookupTracker
var empty = true var empty = true
session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames) lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames)
scope.processFunctionsAndConstructorsByName( scope.processFunctionsAndConstructorsByName(
info, info,
session, session,
bodyResolveComponents, bodyResolveComponents,
constructorFilter constructorFilter
) { candidate -> ) { candidate ->
lookupTracker?.recordCallableCandidateAsLookup(candidate, info.callSite.source, info.containingFile.source)
empty = false empty = false
consumeCallableCandidate(candidate, info, processor) consumeCallableCandidate(candidate, info, processor)
} }
@@ -472,9 +474,11 @@ internal class ScopeTowerLevel(
info: CallInfo, info: CallInfo,
processor: TowerScopeLevelProcessor<FirVariableSymbol<*>> processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>
): ProcessResult { ): ProcessResult {
val lookupTracker = session.lookupTracker
var empty = true var empty = true
session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames) lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames)
scope.processPropertiesByName(info.name) { candidate -> scope.processPropertiesByName(info.name) { candidate ->
lookupTracker?.recordCallableCandidateAsLookup(candidate, info.callSite.source, info.containingFile.source)
empty = false empty = false
consumeCallableCandidate(candidate, info, processor) consumeCallableCandidate(candidate, info, processor)
} }
@@ -17,8 +17,8 @@ package foo.bar
/*p:foo.bar(A) p:foo.bar(div) p:foo.bar(divAssign) p:foo.bar.A(div) p:foo.bar.A(divAssign)*/a /= b /*p:foo.bar(A) p:foo.bar(div) p:foo.bar(divAssign) p:foo.bar.A(div) p:foo.bar.A(divAssign)*/a /= b
// for var // for var
/*p:foo.bar(A) p:foo.bar(plusAssign) p:foo.bar.A(plus) p:foo.bar.A(plusAssign)*/d += b /*p:foo.bar(A) p:foo.bar(plusAssign) p:foo.bar.A(plus) p:foo.bar.A(plusAssign) p:kotlin.collections(plusAssign)*/d += b
/*p:foo.bar(A) p:foo.bar(minus) p:foo.bar(minusAssign) p:foo.bar.A(minus) p:foo.bar.A(minusAssign)*/d -= b /*p:foo.bar(A) p:foo.bar(minus) p:foo.bar(minusAssign) p:foo.bar.A(minus) p:foo.bar.A(minusAssign) p:kotlin.collections(minusAssign)*/d -= b
/*p:foo.bar(A) p:foo.bar(times) p:foo.bar.A(times) p:foo.bar.A(timesAssign)*/d *= b /*p:foo.bar(A) p:foo.bar(times) p:foo.bar.A(times) p:foo.bar.A(timesAssign)*/d *= b
/*p:foo.bar(A) p:foo.bar(div) p:foo.bar(divAssign) p:foo.bar.A(div) p:foo.bar.A(divAssign)*/d /= b /*p:foo.bar(A) p:foo.bar(div) p:foo.bar(divAssign) p:foo.bar.A(div) p:foo.bar.A(divAssign)*/d /= b
} }
@@ -6,8 +6,8 @@ package foo
/*p:foo*/fun getA() = /*p:foo*/A() /*p:foo*/fun getA() = /*p:foo*/A()
/*p:foo*/fun getB() = /*p:foo*/B() /*p:foo*/fun getB() = /*p:foo*/B()
/*p:foo*/fun getListOfA() = /*p:foo p:foo(A) p:kotlin.collections(List)*/listOf(/*p:foo*/A()) /*p:foo*/fun getListOfA() = /*p:foo p:foo(A) p:kotlin.collections p:kotlin.collections(List)*/listOf(/*p:foo*/A())
/*p:foo*/fun getListOfB() = /*p:foo p:foo(B) p:kotlin.collections(List)*/listOf(/*p:foo*/B()) /*p:foo*/fun getListOfB() = /*p:foo p:foo(B) p:kotlin.collections p:kotlin.collections(List)*/listOf(/*p:foo*/B())
/*p:foo*/fun useListOfA(a: /*p:foo p:foo(A) p:kotlin.collections*/List</*p:foo*/A>) {} /*p:foo*/fun useListOfA(a: /*p:foo p:foo(A) p:kotlin.collections*/List</*p:foo*/A>) {}
/*p:foo*/fun useListOfB(b: /*p:foo p:foo(B) p:kotlin.collections*/List</*p:foo*/B>) {} /*p:foo*/fun useListOfB(b: /*p:foo p:foo(B) p:kotlin.collections*/List</*p:foo*/B>) {}
@@ -13,12 +13,12 @@ package foo.bar
/*p:foo.bar(not) p:foo.bar.A(not)*/!/*p:foo.bar(A)*/a /*p:foo.bar(not) p:foo.bar.A(not)*/!/*p:foo.bar(A)*/a
// for val // for val
/*p:foo.bar(A) p:foo.bar(times) p:foo.bar.A(times) p:foo.bar.A(timesAssign)*/a *= b /*p:foo.bar(A) p:foo.bar(times) p:foo.bar.A(times) p:foo.bar.A(timesAssign) p:java.math(BigDecimal) p:java.math(BigInteger) p:kotlin(times)*/a *= b
/*p:foo.bar(A) p:foo.bar(div) p:foo.bar(divAssign) p:foo.bar.A(div) p:foo.bar.A(divAssign)*/a /= b /*p:foo.bar(A) p:foo.bar(div) p:foo.bar(divAssign) p:foo.bar.A(div) p:foo.bar.A(divAssign) p:java.math(BigDecimal) p:java.math(BigInteger) p:kotlin(div)*/a /= b
// for var // for var
/*p:foo.bar(A) p:foo.bar(plusAssign) p:foo.bar.A(plus) p:foo.bar.A(plusAssign)*/d += b /*p:foo.bar(A) p:foo.bar(plusAssign) p:foo.bar.A(plus) p:foo.bar.A(plusAssign) p:kotlin.collections(plusAssign)*/d += b
/*p:foo.bar(A) p:foo.bar(minus) p:foo.bar(minusAssign) p:foo.bar.A(minus) p:foo.bar.A(minusAssign)*/d -= b /*p:foo.bar(A) p:foo.bar(minus) p:foo.bar(minusAssign) p:foo.bar.A(minus) p:foo.bar.A(minusAssign) p:kotlin.collections(minusAssign)*/d -= b
/*p:foo.bar(A) p:foo.bar(times) p:foo.bar.A(times) p:foo.bar.A(timesAssign)*/d *= b /*p:foo.bar(A) p:foo.bar(times) p:foo.bar.A(times) p:foo.bar.A(timesAssign) p:java.math(BigDecimal) p:java.math(BigInteger) p:kotlin(times)*/d *= b
/*p:foo.bar(A) p:foo.bar(div) p:foo.bar(divAssign) p:foo.bar.A(div) p:foo.bar.A(divAssign)*/d /= b /*p:foo.bar(A) p:foo.bar(div) p:foo.bar(divAssign) p:foo.bar.A(div) p:foo.bar.A(divAssign) p:java.math(BigDecimal) p:java.math(BigInteger) p:kotlin(div)*/d /= b
} }
@@ -6,8 +6,8 @@ package foo
/*p:foo*/fun getA() = /*p:foo*/A() /*p:foo*/fun getA() = /*p:foo*/A()
/*p:foo*/fun getB() = /*p:foo*/B() /*p:foo*/fun getB() = /*p:foo*/B()
/*p:foo*/fun getListOfA() = /*p:foo p:foo(A) p:kotlin.collections(List)*/listOf(/*p:foo*/A()) /*p:foo*/fun getListOfA() = /*p:foo p:foo(A) p:kotlin.collections p:kotlin.collections(List)*/listOf(/*p:foo*/A())
/*p:foo*/fun getListOfB() = /*p:foo p:foo(B) p:kotlin.collections(List)*/listOf(/*p:foo*/B()) /*p:foo*/fun getListOfB() = /*p:foo p:foo(B) p:kotlin.collections p:kotlin.collections(List)*/listOf(/*p:foo*/B())
/*p:foo*/fun useListOfA(a: /*p:foo p:foo(A) p:kotlin.collections*/List</*p:foo*/A>) {} /*p:foo*/fun useListOfA(a: /*p:foo p:foo(A) p:kotlin.collections*/List</*p:foo*/A>) {}
/*p:foo*/fun useListOfB(b: /*p:foo p:foo(B) p:kotlin.collections*/List</*p:foo*/B>) {} /*p:foo*/fun useListOfB(b: /*p:foo p:foo(B) p:kotlin.collections*/List</*p:foo*/B>) {}
@@ -18,7 +18,7 @@ import baz.*
// inherited from I // inherited from I
/*p:bar(C) p:bar.C(ifunc)*/c.ifunc() /*p:bar(C) p:bar.C(ifunc)*/c.ifunc()
/*p:bar.C(isfield) p:baz p:foo*/C.isfield /*p:bar.C(isfield) p:baz p:foo p:foo.I(isfield)*/C.isfield
// expected error: Unresolved reference: IS // expected error: Unresolved reference: IS
/*p:bar.C(IS) p:baz p:baz(IS) p:foo p:foo(IS)*/C.IS() /*p:bar.C(IS) p:baz p:baz(IS) p:foo p:foo(IS)*/C.IS()
@@ -3,4 +3,12 @@ public class Main {
public static String staticField = ""; public static String staticField = "";
public void regularMethod() {} public void regularMethod() {}
public String regularField = ""; public String regularField = "";
public void invoke() {
}
public static Main INSTANCE = new Main();
public static class Other extends Main {
}
} }
@@ -1,4 +1,6 @@
==== INITIAL BUILD ==== ==== INITIAL BUILD ====
Compiling files: Compiling files:
src/instanceUsage0.kt
src/instanceUsage1.kt
src/kotlinUsage.kt src/kotlinUsage.kt
Exit code: OK Exit code: OK
@@ -0,0 +1,5 @@
/*p:Main.Other(INSTANCE)*/import /*p:<root>*/Main./*p:Main*/Other.INSTANCE
/*p:<root>*/fun foo() {
/*p:Main(invoke) p:Main.Other*/INSTANCE()
}
@@ -0,0 +1,5 @@
/*p:Main.Other(INSTANCE)*/import Main.Other.INSTANCE
/*p:<root>*/fun foo() {
/*p:Main(invoke) p:Main.Other*/INSTANCE()
}
@@ -0,0 +1,5 @@
import /*p:<root>*/Main./*p:Main*/Other.*
/*p:<root>*/fun bar() {
/*p:<root> p:<root>(invoke) p:Main(invoke) p:Main.Other p:Main.Other(invoke)*/INSTANCE()
}
@@ -0,0 +1,5 @@
import Main.Other.*
/*p:<root>*/fun bar() {
/*p:<root> p:Main(invoke) p:Main.Other*/INSTANCE()
}
@@ -1,4 +1,7 @@
/*p:<root>*/class MainClass {
package one
/*p:one*/class MainClass {
class NestedClass { class NestedClass {
object A { object A {
class B { class B {
@@ -1,7 +1,9 @@
/*p:<root>*/fun usageAsCall(): /*p:<root>*/Int /*p:kotlin(Nothing)*/{ package one
val f = /*p:<root> p:MainClass.NestedClass.A.B(F) p:java.lang p:kotlin p:kotlin.annotation p:kotlin.collections p:kotlin.comparisons p:kotlin.io p:kotlin.jvm p:kotlin.ranges p:kotlin.sequences p:kotlin.text*/MainClass./*p:MainClass*/NestedClass./*p:MainClass.NestedClass*/A./*p:MainClass.NestedClass.A*/B./*p:MainClass.NestedClass.A.B*/F
/*p:kotlin(Nothing)*/return /*p:<root> p:java.lang p:kotlin p:kotlin.annotation p:kotlin.collections p:kotlin.comparisons p:kotlin.io p:kotlin.jvm p:kotlin.ranges p:kotlin.sequences p:kotlin.text*/MainClass./*p:MainClass*/NestedClass./*p:MainClass.NestedClass*/A./*p:MainClass.NestedClass.A*/B./*p:MainClass.NestedClass.A.B*/F./*p:MainClass.NestedClass.A.B.F*/x /*p:one*/fun usageAsCall(): /*p:one*/Int /*p:kotlin(Nothing)*/{
val f = /*p:java.lang p:kotlin p:kotlin.annotation p:kotlin.collections p:kotlin.comparisons p:kotlin.io p:kotlin.jvm p:kotlin.ranges p:kotlin.sequences p:kotlin.text p:one p:one.MainClass.NestedClass.A.B(F)*/MainClass./*p:one.MainClass*/NestedClass./*p:one.MainClass.NestedClass*/A./*p:one.MainClass.NestedClass.A*/B./*p:one.MainClass.NestedClass.A.B*/F
/*p:kotlin(Nothing)*/return /*p:java.lang p:kotlin p:kotlin.annotation p:kotlin.collections p:kotlin.comparisons p:kotlin.io p:kotlin.jvm p:kotlin.ranges p:kotlin.sequences p:kotlin.text p:one*/MainClass./*p:one.MainClass*/NestedClass./*p:one.MainClass.NestedClass*/A./*p:one.MainClass.NestedClass.A*/B./*p:one.MainClass.NestedClass.A.B*/F./*p:one.MainClass.NestedClass.A.B.F*/x
} }
/*p:<root>*/fun usageAsType(f: /*p:<root>*/MainClass./*p:MainClass*/NestedClass./*p:MainClass.NestedClass*/A./*p:MainClass.NestedClass.A*/B./*p:MainClass.NestedClass.A.B*/F) {} /*p:one*/fun usageAsType(f: /*p:one*/MainClass./*p:one.MainClass*/NestedClass./*p:one.MainClass.NestedClass*/A./*p:one.MainClass.NestedClass.A*/B./*p:one.MainClass.NestedClass.A.B*/F) {}
@@ -1,7 +1,9 @@
/*p:<root>*/fun usageAsCall(): /*p:<root>*/Int { package one
val f = /*p:<root> p:MainClass(NestedClass) p:MainClass.NestedClass(A) p:MainClass.NestedClass.A(B) p:MainClass.NestedClass.A.B(F)*/MainClass.NestedClass./*p:MainClass.NestedClass*/A.B./*p:MainClass.NestedClass.A.B*/F
return /*p:<root> p:MainClass(NestedClass) p:MainClass.NestedClass(A) p:MainClass.NestedClass.A(B) p:MainClass.NestedClass.A.B(F) p:MainClass.NestedClass.A.B.F(x)*/MainClass.NestedClass./*p:MainClass.NestedClass*/A.B./*p:MainClass.NestedClass.A.B*/F.x /*p:one*/fun usageAsCall(): /*p:one*/Int {
val f = /*p:one p:one.MainClass(NestedClass) p:one.MainClass.NestedClass(A) p:one.MainClass.NestedClass.A(B) p:one.MainClass.NestedClass.A.B(F)*/MainClass.NestedClass./*p:one.MainClass.NestedClass*/A.B./*p:one.MainClass.NestedClass.A.B*/F
return /*p:one p:one.MainClass(NestedClass) p:one.MainClass.NestedClass(A) p:one.MainClass.NestedClass.A(B) p:one.MainClass.NestedClass.A.B(F) p:one.MainClass.NestedClass.A.B.F(x)*/MainClass.NestedClass./*p:one.MainClass.NestedClass*/A.B./*p:one.MainClass.NestedClass.A.B*/F.x
} }
/*p:<root>*/fun usageAsType(f: /*p:<root> p:MainClass(NestedClass) p:MainClass.NestedClass(A) p:MainClass.NestedClass.A(B) p:MainClass.NestedClass.A.B(F)*/MainClass.NestedClass.A.B.F) = /*p:MainClass.NestedClass.A.B(F)*/f /*p:one*/fun usageAsType(f: /*p:one p:one.MainClass(NestedClass) p:one.MainClass.NestedClass(A) p:one.MainClass.NestedClass.A(B) p:one.MainClass.NestedClass.A.B(F)*/MainClass.NestedClass.A.B.F) = /*p:one.MainClass.NestedClass.A.B(F)*/f