[FIR] avoid jumping from super type transformer for local classes to unresolved non-local classes
In the worst case, we will visit the entire hierarchy of a local class, where non-local classes are not yet resolved ^KT-56550
This commit is contained in:
committed by
Space Team
parent
6f584bcbe7
commit
ee74e10f28
@@ -0,0 +1,24 @@
|
||||
open class TopLevelClass {
|
||||
open fun foo(i: Int) {
|
||||
|
||||
}
|
||||
|
||||
open fun boo(b: String) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
open class AnotherTopLevelClass : TopLevelClass() {
|
||||
override fun foo(i: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun reso<caret>lveMe() {
|
||||
class LocalClass : AnotherTopLevelClass() {
|
||||
override fun foo(i: Int) {
|
||||
}
|
||||
|
||||
class NestedLocalClass
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
RAW_FIR:
|
||||
FILE: [ResolvedTo(RAW_FIR)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? final? [ResolvedTo(RAW_FIR)] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
IMPORTS:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? final? [ResolvedTo(RAW_FIR)] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
COMPILER_REQUIRED_ANNOTATIONS:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
COMPANION_GENERATION:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? final? [ResolvedTo(COMPANION_GENERATION)] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
SUPER_TYPES:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? final? [ResolvedTo(SUPER_TYPES)] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
TYPES:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? final? [ResolvedTo(TYPES)] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
STATUS:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public final [ResolvedTo(STATUS)] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
EXPECT_ACTUAL_MATCHING:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public final [ResolvedTo(EXPECT_ACTUAL_MATCHING)] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
ARGUMENTS_OF_ANNOTATIONS:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
CONTRACTS:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public final [ResolvedTo(CONTRACTS)] fun resolveMe(): R|kotlin/Unit| {
|
||||
local final? [ResolvedTo(RAW_FIR)] class LocalClass : AnotherTopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=LocalClass] constructor(): R|LocalClass| {
|
||||
super<AnotherTopLevelClass>()
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
local final? [ResolvedTo(RAW_FIR)] [ContainingClassKey=LocalClass] class NestedLocalClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=NestedLocalClass] constructor(): R|LocalClass.NestedLocalClass| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IMPLICIT_TYPES_BODY_RESOLVE:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] fun resolveMe(): R|kotlin/Unit| {
|
||||
local final? [ResolvedTo(RAW_FIR)] class LocalClass : AnotherTopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=LocalClass] constructor(): R|LocalClass| {
|
||||
super<AnotherTopLevelClass>()
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
local final? [ResolvedTo(RAW_FIR)] [ContainingClassKey=LocalClass] class NestedLocalClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=NestedLocalClass] constructor(): R|LocalClass.NestedLocalClass| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ANNOTATIONS_ARGUMENTS_MAPPING:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public? open [ResolvedTo(RAW_FIR)] class TopLevelClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? open [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] b: String): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? open [ResolvedTo(RAW_FIR)] class AnotherTopLevelClass : TopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<TopLevelClass>
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] fun resolveMe(): R|kotlin/Unit| {
|
||||
local final? [ResolvedTo(RAW_FIR)] class LocalClass : AnotherTopLevelClass {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=LocalClass] constructor(): R|LocalClass| {
|
||||
super<AnotherTopLevelClass>()
|
||||
}
|
||||
|
||||
public? open? override [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] i: Int): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
local final? [ResolvedTo(RAW_FIR)] [ContainingClassKey=LocalClass] class NestedLocalClass : R|kotlin/Any| {
|
||||
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=NestedLocalClass] constructor(): R|LocalClass.NestedLocalClass| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BODY_RESOLVE:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(RAW_FIR)] annotations container
|
||||
public open [ResolvedTo(STATUS)] class TopLevelClass : R|kotlin/Any| {
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public open [ResolvedTo(STATUS)] fun foo([ResolvedTo(STATUS)] i: R|kotlin/Int|): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public open [ResolvedTo(STATUS)] fun boo([ResolvedTo(STATUS)] b: R|kotlin/String|): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class AnotherTopLevelClass : R|TopLevelClass| {
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
LAZY_super<R|TopLevelClass|>
|
||||
}
|
||||
|
||||
public open override [ResolvedTo(STATUS)] fun foo([ResolvedTo(STATUS)] i: R|kotlin/Int|): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public final [ResolvedTo(BODY_RESOLVE)] fun resolveMe(): R|kotlin/Unit| {
|
||||
local final [ResolvedTo(BODY_RESOLVE)] class LocalClass : R|AnotherTopLevelClass| {
|
||||
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=LocalClass] constructor(): R|LocalClass| {
|
||||
super<R|AnotherTopLevelClass|>()
|
||||
}
|
||||
|
||||
public open override [ResolvedTo(BODY_RESOLVE)] fun foo([ResolvedTo(BODY_RESOLVE)] i: R|kotlin/Int|): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
local final [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=LocalClass] class NestedLocalClass : R|kotlin/Any| {
|
||||
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=NestedLocalClass] constructor(): R|LocalClass.NestedLocalClass| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FILE RAW TO BODY:
|
||||
FILE: [ResolvedTo(IMPORTS)] localNestedClass.kt
|
||||
[ResolvedTo(BODY_RESOLVE)] annotations container
|
||||
public open [ResolvedTo(BODY_RESOLVE)] class TopLevelClass : R|kotlin/Any| {
|
||||
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=TopLevelClass] constructor(): R|TopLevelClass| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public open [ResolvedTo(BODY_RESOLVE)] fun foo([ResolvedTo(BODY_RESOLVE)] i: R|kotlin/Int|): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public open [ResolvedTo(BODY_RESOLVE)] fun boo([ResolvedTo(BODY_RESOLVE)] b: R|kotlin/String|): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
public open [ResolvedTo(BODY_RESOLVE)] class AnotherTopLevelClass : R|TopLevelClass| {
|
||||
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=AnotherTopLevelClass] constructor(): R|AnotherTopLevelClass| {
|
||||
super<R|TopLevelClass|>()
|
||||
}
|
||||
|
||||
public open override [ResolvedTo(BODY_RESOLVE)] fun foo([ResolvedTo(BODY_RESOLVE)] i: R|kotlin/Int|): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
public final [ResolvedTo(BODY_RESOLVE)] fun resolveMe(): R|kotlin/Unit| {
|
||||
local final [ResolvedTo(BODY_RESOLVE)] class LocalClass : R|AnotherTopLevelClass| {
|
||||
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=LocalClass] constructor(): R|LocalClass| {
|
||||
super<R|AnotherTopLevelClass|>()
|
||||
}
|
||||
|
||||
public open override [ResolvedTo(BODY_RESOLVE)] fun foo([ResolvedTo(BODY_RESOLVE)] i: R|kotlin/Int|): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
local final [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=LocalClass] class NestedLocalClass : R|kotlin/Any| {
|
||||
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=NestedLocalClass] constructor(): R|LocalClass.NestedLocalClass| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -198,6 +198,12 @@ public class FirOutOfContentRootLazyDeclarationResolveTestGenerated extends Abst
|
||||
runTest("analysis/low-level-api-fir/testdata/lazyResolve/lazyProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localNestedClass.kt")
|
||||
public void testLocalNestedClass() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/lazyResolve/localNestedClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("parameterOfNonLocalSetter.kt")
|
||||
public void testParameterOfNonLocalSetter() throws Exception {
|
||||
|
||||
+6
@@ -198,6 +198,12 @@ public class FirSourceLazyDeclarationResolveTestGenerated extends AbstractFirSou
|
||||
runTest("analysis/low-level-api-fir/testdata/lazyResolve/lazyProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localNestedClass.kt")
|
||||
public void testLocalNestedClass() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/lazyResolve/localNestedClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("parameterOfNonLocalSetter.kt")
|
||||
public void testParameterOfNonLocalSetter() throws Exception {
|
||||
|
||||
+45
-9
@@ -43,6 +43,8 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.types.model.TypeArgumentMarker
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||
|
||||
class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(
|
||||
session, scopeSession, FirResolvePhase.SUPER_TYPES
|
||||
@@ -81,7 +83,7 @@ fun <F : FirClassLikeDeclaration> F.runSupertypeResolvePhaseForLocalClass(
|
||||
useSiteFile: FirFile,
|
||||
containingDeclarations: List<FirDeclaration>,
|
||||
): F {
|
||||
val supertypeComputationSession = SupertypeComputationSession()
|
||||
val supertypeComputationSession = SupertypeComputationSessionForLocalClasses()
|
||||
val supertypeResolverVisitor = FirSupertypeResolverVisitor(
|
||||
session, supertypeComputationSession, scopeSession,
|
||||
currentScopeList.toPersistentList(),
|
||||
@@ -97,6 +99,41 @@ fun <F : FirClassLikeDeclaration> F.runSupertypeResolvePhaseForLocalClass(
|
||||
return this.transform<F, Nothing?>(applySupertypesTransformer, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* We should resolve non-local classes to [FirResolvePhase.SUPER_TYPES] explicitly
|
||||
* to avoid unsafe access to unresolved super type references
|
||||
*
|
||||
* Example:
|
||||
* ```
|
||||
* open class TopLevelClass
|
||||
* open class AnotherTopLevelClass : TopLevelClass()
|
||||
*
|
||||
* fun resolveMe() {
|
||||
* class LocalClass : AnotherTopLevelClass() {
|
||||
* class NestedLocalClass
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* During the resolution of local classes, in the best case, we will only try
|
||||
* to access the unresolved super type reference of "AnotherTopLevelClass" that is unsafe in the context of parallel resolution.
|
||||
* In the worst case, from NestedLocalClass we will visit the entire hierarchy of "LocalClass"
|
||||
*/
|
||||
private class SupertypeComputationSessionForLocalClasses : SupertypeComputationSession() {
|
||||
override fun getResolvedSuperTypeRefsForOutOfSessionDeclaration(classLikeDeclaration: FirClassLikeDeclaration): List<FirResolvedTypeRef>? {
|
||||
classLikeDeclaration.lazyResolveToPhase(FirResolvePhase.SUPER_TYPES)
|
||||
return super.getResolvedSuperTypeRefsForOutOfSessionDeclaration(classLikeDeclaration)
|
||||
}
|
||||
|
||||
override fun supertypeRefs(declaration: FirClassLikeDeclaration): List<FirTypeRef> {
|
||||
if (!declaration.isLocal) {
|
||||
declaration.lazyResolveToPhase(FirResolvePhase.SUPER_TYPES)
|
||||
}
|
||||
|
||||
return super.supertypeRefs(declaration)
|
||||
}
|
||||
}
|
||||
|
||||
private class FirApplySupertypesTransformer(
|
||||
private val supertypeComputationSession: SupertypeComputationSession,
|
||||
private val session: FirSession,
|
||||
@@ -285,16 +322,10 @@ class FirSupertypeResolverVisitor(
|
||||
if (supertype !is ConeClassLikeType) continue
|
||||
val supertypeModuleSession = supertype.toSymbol(session)?.moduleData?.session ?: continue
|
||||
val fir = supertype.lookupTag.toSymbol(supertypeModuleSession)?.fir ?: continue
|
||||
resolveAllSupertypes(fir, fir.supertypeRefs(), visited)
|
||||
resolveAllSupertypes(fir, supertypeComputationSession.supertypeRefs(fir), visited)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirClassLikeDeclaration.supertypeRefs() = when (this) {
|
||||
is FirRegularClass -> superTypeRefs
|
||||
is FirTypeAlias -> listOf(expandedTypeRef)
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
private fun prepareScopes(classLikeDeclaration: FirClassLikeDeclaration): PersistentList<FirScope> {
|
||||
val classId = classLikeDeclaration.symbol.classId
|
||||
val classModuleSession = classLikeDeclaration.moduleData.session
|
||||
@@ -580,6 +611,12 @@ open class SupertypeComputationSession {
|
||||
else -> null
|
||||
}
|
||||
|
||||
internal open fun supertypeRefs(declaration: FirClassLikeDeclaration): List<FirTypeRef> = when (declaration) {
|
||||
is FirRegularClass -> declaration.superTypeRefs
|
||||
is FirTypeAlias -> listOf(declaration.expandedTypeRef)
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param declaration declaration to be checked for loops
|
||||
* @param visited visited declarations during the current loop search
|
||||
@@ -725,7 +762,6 @@ open class SupertypeComputationSession {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sealed class SupertypeComputationStatus {
|
||||
object NotComputed : SupertypeComputationStatus()
|
||||
object Computing : SupertypeComputationStatus()
|
||||
|
||||
Reference in New Issue
Block a user