提交 093a236e 编写于 作者: M Mikhail Glukhikh

FIR resolve: support star imports, enum entries

上级 929573e0
......@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.fir.declarations.FirResolvedClass
import org.jetbrains.kotlin.fir.declarations.FirResolvedEnumEntry
import org.jetbrains.kotlin.fir.descriptors.ConeClassDescriptor
import org.jetbrains.kotlin.fir.descriptors.ConeClassifierDescriptor
import org.jetbrains.kotlin.fir.descriptors.ConeTypeParameterDescriptor
......@@ -17,4 +18,11 @@ class ConeClassDescriptorImpl(
override val classId: ClassId,
override val superTypes: List<ConeKotlinType>,
override val nestedClassifiers: List<ConeClassifierDescriptor>
) : ConeClassDescriptor, AbstractFirBasedDescriptor<FirResolvedClass>()
\ No newline at end of file
) : ConeClassDescriptor, AbstractFirBasedDescriptor<FirResolvedClass>()
class ConeEnumEntryDescriptorImpl(
override val typeParameters: List<ConeTypeParameterDescriptor>,
override val classId: ClassId,
override val superTypes: List<ConeKotlinType>,
override val nestedClassifiers: List<ConeClassifierDescriptor>
) : ConeClassDescriptor, AbstractFirBasedDescriptor<FirResolvedEnumEntry>()
\ No newline at end of file
......@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirDescriptorOwner
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedClassImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedEnumEntryImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedTypeAliasImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedTypeParameterImpl
import org.jetbrains.kotlin.fir.descriptors.ConeClassifierDescriptor
......@@ -55,14 +56,18 @@ class FirClassifierResolveTransformer : FirTransformer<Nothing?>() {
val nestedClassifiers =
klass.declarations.filterIsInstance<FirDescriptorOwner<*>>().mapNotNull { it.descriptor as? ConeClassifierDescriptor }
val descriptor = ConeClassDescriptorImpl(
typeParameters,
ClassId(packageFqName, actualClassName, false),
superTypes,
nestedClassifiers
)
return FirResolvedClassImpl(klass, descriptor).compose()
val classId = ClassId(packageFqName, actualClassName, false)
return when (klass) {
is FirEnumEntry -> {
val descriptor = ConeEnumEntryDescriptorImpl(typeParameters, classId, superTypes, nestedClassifiers)
FirResolvedEnumEntryImpl(klass, descriptor).compose()
}
else -> {
val descriptor = ConeClassDescriptorImpl(typeParameters, classId, superTypes, nestedClassifiers)
FirResolvedClassImpl(klass, descriptor).compose()
}
}
}
override fun transformResolvedClass(resolvedClass: FirResolvedClass, data: Nothing?): CompositeTransformResult<FirDeclaration> {
......
......@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedPackageStarImport
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirTransformer
......@@ -33,6 +34,10 @@ class FirImportResolveTransformer : FirTransformer<Nothing?>() {
val lastPart = mutableListOf<String>()
var firstPart = fqName
if (import.isAllUnder && firProvider.getFirFilesByPackage(firstPart).isNotEmpty()) {
return FirResolvedPackageStarImport(import, firstPart).compose()
}
while (!firstPart.isRoot) {
lastPart.add(0, firstPart.shortName().asString())
firstPart = firstPart.parent()
......@@ -44,9 +49,7 @@ class FirImportResolveTransformer : FirTransformer<Nothing?>() {
return FirResolvedImportImpl(import, resolvedFqName).compose()
}
}
return import.compose()
} else {
return import.compose()
}
return import.compose()
}
}
\ No newline at end of file
......@@ -39,8 +39,10 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
scope = FirCompositeScope(
mutableListOf(
// from high priority to low priority
FirExplicitImportingScope(file.imports),
FirSelfImportingScope(file.packageFqName, file.session)
FirSelfImportingScope(file.packageFqName, file.session),
FirStarImportingScope(file.imports)
)
)
packageFqName = file.packageFqName
......
......@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
......@@ -15,9 +15,8 @@ import org.jetbrains.kotlin.name.Name
class FirExplicitImportingScope(imports: List<FirImport>) : FirScope {
// TODO: Resolve imports! Instead of computing it resolution results here
private val simpleImports =
imports.filterIsInstance<FirResolvedImport>()
imports.filterIsInstance<FirResolvedImportImpl>()
.filter { !it.isAllUnder }
.groupBy { it.aliasName ?: it.resolvedFqName.shortClassName }
......
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.toSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
class FirStarImportingScope(imports: List<FirImport>) : FirScope {
private val starImports = imports.filterIsInstance<FirResolvedImport>().filter { it.isAllUnder }
override fun processClassifiersByName(
name: Name,
position: FirPosition,
processor: (ConeSymbol) -> Boolean
): Boolean {
for (import in starImports) {
val relativeClassName = import.relativeClassName
val symbol = if (relativeClassName == null) {
ClassId(import.packageFqName, name)
} else {
ClassId(import.packageFqName, relativeClassName.child(name), false)
}.toSymbol()
if (!processor(symbol)) {
return false
}
}
return true
}
}
\ No newline at end of file
......@@ -182,6 +182,11 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
)
}
override fun visitResolvedEnumEntry(resolvedEnumEntry: FirResolvedEnumEntry) {
print("(resolved) ")
visitEnumEntry(resolvedEnumEntry)
}
override fun visitEnumEntry(enumEntry: FirEnumEntry) {
visitClass(enumEntry)
}
......
......@@ -14,4 +14,9 @@ interface FirResolvedClass : FirClass, FirDescriptorOwner<FirResolvedClass> {
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitResolvedClass(this, data)
}
interface FirResolvedEnumEntry : FirEnumEntry, FirDescriptorOwner<FirResolvedEnumEntry> {
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitResolvedEnumEntry(this, data)
}
\ No newline at end of file
......@@ -7,9 +7,14 @@ package org.jetbrains.kotlin.fir.declarations
import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
interface FirResolvedImport : FirImport {
val resolvedFqName: ClassId
val packageFqName: FqName
val relativeClassName: FqName?
val resolvedFqName: ClassId?
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitResolvedImport(this, data)
......
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.declarations.impl
import org.jetbrains.kotlin.fir.FirBasedDescriptor
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
import org.jetbrains.kotlin.fir.declarations.FirResolvedEnumEntry
import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
class FirResolvedEnumEntryImpl(
val delegate: FirEnumEntry,
override val descriptor: FirBasedDescriptor<FirResolvedEnumEntry>
) : FirResolvedEnumEntry, FirEnumEntry by delegate {
init {
descriptor.bind(this)
}
override fun accept(visitor: FirVisitorVoid) {
super<FirResolvedEnumEntry>.accept(visitor)
}
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R {
return super<FirResolvedEnumEntry>.accept(visitor, data)
}
}
\ No newline at end of file
......@@ -9,11 +9,18 @@ import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
class FirResolvedImportImpl(
val delegate: FirImport,
override val resolvedFqName: ClassId
) : FirResolvedImport, FirImport by delegate {
override val packageFqName: FqName
get() = resolvedFqName.packageFqName
override val relativeClassName: FqName
get() = resolvedFqName.relativeClassName
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitResolvedImport(this, data)
}
\ No newline at end of file
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.declarations.impl
import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
class FirResolvedPackageStarImport(
val delegate: FirImport,
override val packageFqName: FqName
) : FirResolvedImport, FirImport by delegate {
override val relativeClassName: FqName?
get() = null
override val resolvedFqName: ClassId?
get() = null
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitResolvedImport(this, data)
}
\ No newline at end of file
......@@ -66,6 +66,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformClass(enumEntry, data)
}
open fun transformResolvedEnumEntry(resolvedEnumEntry: FirResolvedEnumEntry, data: D): CompositeTransformResult<FirDeclaration> {
return transformEnumEntry(resolvedEnumEntry, data)
}
open fun transformResolvedClass(resolvedClass: FirResolvedClass, data: D): CompositeTransformResult<FirDeclaration> {
return transformClass(resolvedClass, data)
}
......@@ -214,6 +218,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformElement(element, data)
}
final override fun visitEnumEntry(enumEntry: FirEnumEntry, data: D): CompositeTransformResult<FirElement> {
return transformEnumEntry(enumEntry, data)
}
final override fun visitExpression(expression: FirExpression, data: D): CompositeTransformResult<FirElement> {
return transformExpression(expression, data)
}
......@@ -270,10 +278,6 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformDelegatedConstructorCall(delegatedConstructorCall, data)
}
final override fun visitEnumEntry(enumEntry: FirEnumEntry, data: D): CompositeTransformResult<FirElement> {
return transformEnumEntry(enumEntry, data)
}
final override fun visitResolvedClass(resolvedClass: FirResolvedClass, data: D): CompositeTransformResult<FirElement> {
return transformResolvedClass(resolvedClass, data)
}
......@@ -306,6 +310,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformAnonymousInitializer(anonymousInitializer, data)
}
final override fun visitResolvedEnumEntry(resolvedEnumEntry: FirResolvedEnumEntry, data: D): CompositeTransformResult<FirElement> {
return transformResolvedEnumEntry(resolvedEnumEntry, data)
}
final override fun visitBody(body: FirBody, data: D): CompositeTransformResult<FirElement> {
return transformBody(body, data)
}
......
......@@ -66,6 +66,10 @@ abstract class FirVisitor<out R, in D> {
return visitClass(enumEntry, data)
}
open fun visitResolvedEnumEntry(resolvedEnumEntry: FirResolvedEnumEntry, data: D): R {
return visitEnumEntry(resolvedEnumEntry, data)
}
open fun visitResolvedClass(resolvedClass: FirResolvedClass, data: D): R {
return visitClass(resolvedClass, data)
}
......
......@@ -66,6 +66,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitClass(enumEntry, null)
}
open fun visitResolvedEnumEntry(resolvedEnumEntry: FirResolvedEnumEntry) {
visitEnumEntry(resolvedEnumEntry, null)
}
open fun visitResolvedClass(resolvedClass: FirResolvedClass) {
visitClass(resolvedClass, null)
}
......@@ -214,6 +218,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitElement(element)
}
final override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Nothing?) {
visitEnumEntry(enumEntry)
}
final override fun visitExpression(expression: FirExpression, data: Nothing?) {
visitExpression(expression)
}
......@@ -270,10 +278,6 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitDelegatedConstructorCall(delegatedConstructorCall)
}
final override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Nothing?) {
visitEnumEntry(enumEntry)
}
final override fun visitResolvedClass(resolvedClass: FirResolvedClass, data: Nothing?) {
visitResolvedClass(resolvedClass)
}
......@@ -306,6 +310,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitAnonymousInitializer(anonymousInitializer)
}
final override fun visitResolvedEnumEntry(resolvedEnumEntry: FirResolvedEnumEntry, data: Nothing?) {
visitResolvedEnumEntry(resolvedEnumEntry)
}
final override fun visitBody(body: FirBody, data: Nothing?) {
visitBody(body)
}
......
interface Some
object O1 : Some
object O2 : Some
enum class SomeEnum(val x: Some) {
FIRST(O1) {
override fun check(y: Some): Boolean = true
},
SECOND(O2) {
override fun check(y: Some): Boolean = y == O2
};
abstract fun check(y: Some): Boolean
}
\ No newline at end of file
FILE: enum.kt
(resolved) public? abstract interface Some() {
}
(resolved) public? final object O1() : R/Some/ {
}
(resolved) public? final object O2() : R/Some/ {
}
(resolved) public? final enum class SomeEnum() {
public? constructor(x: R/Some/)
(resolved) public? final enum entry FIRST() : R/SomeEnum/ {
public? open? override function check(y: R/Some/): R/error: Symbol not found/ {
STUB
}
}
(resolved) public? final enum entry SECOND() : R/SomeEnum/ {
public? open? override function check(y: R/Some/): R/error: Symbol not found/ {
STUB
}
}
public? abstract function check(y: R/Some/): R/error: Symbol not found/
}
package test
sealed class Test {
object O : Test()
class Extra(val x: Int): Test
}
\ No newline at end of file
package other
import test.Test.*
abstract class Factory {
abstract fun createTest(): Test
abstract fun createObj(): O
abstract fun createExtra(): Extra
}
\ No newline at end of file
FILE: sealedStarImport.kt
(resolved) public? abstract class Factory() {
public? abstract function createTest(): R/error: Symbol not found/
public? abstract function createObj(): R/test/Test.O/
public? abstract function createExtra(): R/test/Test.Extra/
}
package b.d
expect interface Other
expect class Another
\ No newline at end of file
package a.d
import b.d.*
fun foo(arg: Other): Another
\ No newline at end of file
FILE: simpleStarImport.kt
public? final? function foo(arg: R/b/d/Other/): R/b/d/Another/
......@@ -25,6 +25,12 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/fir/resolve"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("enum.kt")
public void testEnum() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/enum.kt");
doTest(fileName);
}
@TestMetadata("F.kt")
public void testF() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/F.kt");
......@@ -93,6 +99,12 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
doTest(fileName);
}
@TestMetadata("sealedStarImport.kt")
public void testSealedStarImport() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/multifile/sealedStarImport.kt");
doTest(fileName);
}
@TestMetadata("simpleAliasedImport.kt")
public void testSimpleAliasedImport() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/multifile/simpleAliasedImport.kt");
......@@ -117,6 +129,12 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
doTest(fileName);
}
@TestMetadata("simpleStarImport.kt")
public void testSimpleStarImport() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/multifile/simpleStarImport.kt");
doTest(fileName);
}
@TestMetadata("TypeAliasExpansion.kt")
public void testTypeAliasExpansion() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/multifile/TypeAliasExpansion.kt");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册