FIR resolve: support nested class constructors
This commit is contained in:
+14
-2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class FirClassDeclaredMemberScope(
|
||||
@@ -20,11 +21,22 @@ class FirClassDeclaredMemberScope(
|
||||
private val classId = klass.symbol.classId
|
||||
private val callablesIndex by lazy {
|
||||
klass.declarations.filterIsInstance<FirCallableDeclaration>()
|
||||
.mapNotNull { it.symbol as? ConeCallableSymbol }
|
||||
.groupBy { it.callableId }
|
||||
.map { it.symbol }.groupBy { it.callableId }
|
||||
}
|
||||
private val classIndex by lazy {
|
||||
klass.declarations.filterIsInstance<FirRegularClass>()
|
||||
.map { it.symbol }.associateBy { it.classId }
|
||||
}
|
||||
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction {
|
||||
val matchedClass = classIndex[ClassId(classId.packageFqName, classId.relativeClassName.child(name), false)]
|
||||
|
||||
if (matchedClass != null) {
|
||||
if (FirClassDeclaredMemberScope(matchedClass.fir).processFunctionsByName(name, processor) == STOP) {
|
||||
return STOP
|
||||
}
|
||||
}
|
||||
val symbols = callablesIndex[CallableId(classId.packageFqName, classId.relativeClassName, name)] ?: emptyList()
|
||||
for (symbol in symbols) {
|
||||
if (symbol is ConeFunctionSymbol && !processor(symbol)) {
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ class FirTopLevelDeclaredMemberScope(
|
||||
val matchedClass = provider.getClassLikeSymbolByFqName(ClassId(packageFqName, name))
|
||||
|
||||
if (matchedClass != null && matchedClass is FirClassSymbol) {
|
||||
// TODO: why don't we use declared member scope at this point?
|
||||
if (matchedClass.fir.buildUseSiteScope(session).processFunctionsByName(name, processor) == STOP) {
|
||||
return STOP
|
||||
}
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
FILE: checkArguments.kt
|
||||
public final class A : R|kotlin/Any| {
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
public constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public open class B : R|kotlin/Any| {
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
public constructor(): R|B| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class C : R|B|, R|kotlin/Any| {
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
public final class C : R|B| {
|
||||
public constructor(): R|C| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final fun bar(a: R|A|): R|A| {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FILE: localImplicitBodies.kt
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
lval x: <ERROR TYPE REF: No result type for initializer> = object : R|kotlin/Any| {
|
||||
private constructor(): R|error: Symbol not found, for `<no name provided>`| {
|
||||
private constructor(): R|class error: Symbol not found, for `<no name provided>`| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
FILE: objectVsProperty.kt
|
||||
public final object A : R|kotlin/Any| {
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
private constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final val A: R|kotlin/Int| = Int(10)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
FILE: objects.kt
|
||||
public final object A : R|kotlin/Any| {
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
private constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun foo(): R|A| {
|
||||
^foo this#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FILE: fakeRecursiveSupertype.kt
|
||||
public final class My : R|error: Recursion detected: R|My|| {
|
||||
public final class My : R|class error: Recursion detected: R|My|| {
|
||||
public constructor(): R|My| {
|
||||
super<R|My|>()
|
||||
}
|
||||
@@ -11,7 +11,7 @@ FILE: fakeRecursiveSupertype.kt
|
||||
}
|
||||
|
||||
}
|
||||
public final class His : R|error: Recursion detected: R|Your|| {
|
||||
public final class His : R|class error: Recursion detected: R|Your|| {
|
||||
public constructor(): R|His| {
|
||||
super<R|Your|>()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
FILE: fakeRecursiveTypealias.kt
|
||||
public final typealias My = R|error: Symbol not found, for `incorrect.directory.My`|
|
||||
public final typealias Your = R|error: Recursion detected: R|Your||
|
||||
public final typealias My = R|class error: Symbol not found, for `incorrect.directory.My`|
|
||||
public final typealias Your = R|class error: Recursion detected: R|Your||
|
||||
|
||||
@@ -4,7 +4,7 @@ FILE: sealedStarImport.kt
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public abstract fun createTest(): R|error: Symbol not found, for `Test`|
|
||||
public abstract fun createTest(): R|class error: Symbol not found, for `Test`|
|
||||
|
||||
public abstract fun createObj(): R|test/Test.O|
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
class Owner {
|
||||
|
||||
fun foo() {
|
||||
bar()
|
||||
this.bar()
|
||||
}
|
||||
|
||||
fun bar() {
|
||||
val n = Nested()
|
||||
n.baz()
|
||||
}
|
||||
|
||||
class Nested {
|
||||
fun baz() {
|
||||
gau()
|
||||
this.gau()
|
||||
}
|
||||
|
||||
fun gau() {
|
||||
val o = Owner()
|
||||
o.foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val o = Owner()
|
||||
o.foo()
|
||||
val n = Owner.Nested()
|
||||
n.baz()
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
FILE: simple.kt
|
||||
public final class Owner : R|kotlin/Any| {
|
||||
public constructor(): R|Owner| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
R|/Owner.bar|()
|
||||
this#.R|/Owner.bar|()
|
||||
}
|
||||
|
||||
public final fun bar(): R|kotlin/Unit| {
|
||||
lval n: R|Owner.Nested| = R|/Owner.Nested.Nested|()
|
||||
R|<local>/n|.R|/Owner.Nested.baz|()
|
||||
}
|
||||
|
||||
public final class Nested : R|kotlin/Any| {
|
||||
public constructor(): R|Owner.Nested| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun baz(): R|kotlin/Unit| {
|
||||
R|/Owner.Nested.gau|()
|
||||
this#.R|/Owner.Nested.gau|()
|
||||
}
|
||||
|
||||
public final fun gau(): R|kotlin/Unit| {
|
||||
lval o: R|Owner| = R|/Owner.Owner|()
|
||||
R|<local>/o|.R|/Owner.foo|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
lval o: R|Owner| = R|/Owner.Owner|()
|
||||
R|<local>/o|.R|/Owner.foo|()
|
||||
lval n: R|Owner.Nested| = R|/Owner|.R|/Owner.Nested.Nested|()
|
||||
R|<local>/n|.R|/Owner.Nested.baz|()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class Some {
|
||||
class Nested
|
||||
|
||||
fun foo(): Nested {
|
||||
return Nested()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
FILE: nestedReturnType.kt
|
||||
public final class Some : R|kotlin/Any| {
|
||||
public constructor(): R|Some| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final class Nested : R|kotlin/Any| {
|
||||
public constructor(): R|Some.Nested| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final fun foo(): R|Some.Nested| {
|
||||
^foo R|/Some.Nested.Nested|()
|
||||
}
|
||||
|
||||
}
|
||||
+24
-3
@@ -84,6 +84,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
runTest("compiler/fir/resolve/testData/resolve/NestedOfAliasedType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedReturnType.kt")
|
||||
public void testNestedReturnType() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/nestedReturnType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NestedSuperType.kt")
|
||||
public void testNestedSuperType() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/NestedSuperType.kt");
|
||||
@@ -246,9 +251,7 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInference() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(),
|
||||
new File("compiler/fir/resolve/testData/resolve/expresssions/inference"),
|
||||
Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/resolve/expresssions/inference"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("id.kt")
|
||||
@@ -417,6 +420,24 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/resolve/nested")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Nested extends AbstractFirResolveTestCase {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInNested() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/resolve/nested"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/nested/simple.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/resolve/overrides")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user