FIR resolve: support nested class constructors

This commit is contained in:
Mikhail Glukhikh
2019-04-12 11:47:31 +03:00
parent 8b718c6822
commit 2e7d655b20
14 changed files with 157 additions and 17 deletions
@@ -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)) {
@@ -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|
+31
View File
@@ -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()
}
+40
View File
@@ -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|()
}
}
@@ -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)