FIR: introduce Java type resolve and JavaSymbolProvider #KT-24098 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
5c53bdb142
commit
02bedeca05
@@ -41,6 +41,9 @@ class ConeClassErrorType(val reason: String) : ConeClassLikeType() {
|
|||||||
override val typeArguments: List<ConeKotlinTypeProjection>
|
override val typeArguments: List<ConeKotlinTypeProjection>
|
||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "<ERROR CLASS: $reason>"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class ConeSymbolBasedType : ConeKotlinType() {
|
sealed class ConeSymbolBasedType : ConeKotlinType() {
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
plugins {
|
||||||
|
kotlin("jvm")
|
||||||
|
id("jps-compatible")
|
||||||
|
}
|
||||||
|
|
||||||
|
jvmTarget = "1.6"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile(project(":compiler:frontend.java"))
|
||||||
|
compile(project(":compiler:fir:resolve"))
|
||||||
|
|
||||||
|
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "annotations") }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
"main" { projectDefault() }
|
||||||
|
"test" {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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.java
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.fir.java.symbols.JavaClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||||
|
|
||||||
|
class JavaSymbolProvider(val project: Project) : FirSymbolProvider {
|
||||||
|
|
||||||
|
// TODO: Concrete scope here
|
||||||
|
private val allScope = GlobalSearchScope.allScope(project)
|
||||||
|
|
||||||
|
private val classCache = mutableMapOf<ClassId, ConeSymbol?>()
|
||||||
|
private val packageCache = mutableMapOf<FqName, FqName?>()
|
||||||
|
|
||||||
|
private inline fun <K, V : Any?> MutableMap<K, V>.lookupCacheOrCalculate(key: K, l: (K) -> V): V? {
|
||||||
|
return if (key in this.keys) {
|
||||||
|
this[key]
|
||||||
|
} else {
|
||||||
|
val calculated = l(key)
|
||||||
|
this[key] = calculated
|
||||||
|
calculated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSymbolByFqName(classId: ClassId): ConeSymbol? {
|
||||||
|
return classCache.lookupCacheOrCalculate(classId) {
|
||||||
|
val facade = KotlinJavaPsiFacade.getInstance(project)
|
||||||
|
val foundClass = facade.findClass(classId, allScope)
|
||||||
|
foundClass?.let { javaClass -> JavaClassSymbol(javaClass) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPackage(fqName: FqName): FqName? {
|
||||||
|
return packageCache.lookupCacheOrCalculate(fqName) {
|
||||||
|
val facade = KotlinJavaPsiFacade.getInstance(project)
|
||||||
|
val javaPackage = facade.findPackage(fqName.asString(), allScope) ?: return@lookupCacheOrCalculate null
|
||||||
|
FqName(javaPackage.qualifiedName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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.java.symbols
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.classId
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
|
class JavaClassSymbol(javaClass: JavaClass) : ConeClassSymbol {
|
||||||
|
override val classId: ClassId = javaClass.classId ?: error("!")
|
||||||
|
|
||||||
|
override val typeParameters: List<ConeTypeParameterSymbol> =
|
||||||
|
javaClass.typeParameters.map { JavaTypeParameterSymbol(it.name) }
|
||||||
|
|
||||||
|
override val kind: ClassKind = when {
|
||||||
|
javaClass.isEnum -> ClassKind.ENUM_CLASS
|
||||||
|
javaClass.isInterface -> ClassKind.INTERFACE
|
||||||
|
javaClass.isAnnotationType -> ClassKind.ANNOTATION_CLASS
|
||||||
|
else -> ClassKind.CLASS
|
||||||
|
}
|
||||||
|
|
||||||
|
override val superTypes: List<ConeClassLikeType> =
|
||||||
|
listOf(ConeClassErrorType("Not supported: Java class supertypes"))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* 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.java.symbols
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class JavaTypeParameterSymbol(override val name: Name) : ConeTypeParameterSymbol
|
||||||
+5
-3
@@ -192,9 +192,9 @@ open class FirTypeResolveTransformer : FirTransformer<Nothing?>() {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (symbol is ConeTypeAliasSymbol) {
|
if (symbol is ConeTypeAliasSymbol) {
|
||||||
symbol.expansionType?.let { walkSymbols(it.symbol) }
|
symbol.expansionType?.let { if (it !is ConeClassErrorType) walkSymbols(it.symbol) }
|
||||||
} else if (symbol is ConeClassSymbol) {
|
} else if (symbol is ConeClassSymbol) {
|
||||||
symbol.superTypes.forEach { walkSymbols(it.symbol) }
|
symbol.superTypes.forEach { if (it !is ConeClassErrorType) walkSymbols(it.symbol) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,9 @@ open class FirTypeResolveTransformer : FirTransformer<Nothing?>() {
|
|||||||
val superClassType =
|
val superClassType =
|
||||||
this.superTypes
|
this.superTypes
|
||||||
.map { it.computePartialExpansion() }
|
.map { it.computePartialExpansion() }
|
||||||
.firstOrNull { (it?.symbol as? ConeClassSymbol)?.kind == ClassKind.CLASS } ?: return
|
.firstOrNull {
|
||||||
|
it !is ConeClassErrorType && (it?.symbol as? ConeClassSymbol)?.kind == ClassKind.CLASS
|
||||||
|
} ?: return
|
||||||
list += superClassType
|
list += superClassType
|
||||||
superClassType.symbol.collectSuperTypes(list)
|
superClassType.symbol.collectSuperTypes(list)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
import java.util.*
|
||||||
|
|
||||||
|
val x: SortedSet<Int> = TreeSet()
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
FILE: treeSet.kt
|
||||||
|
public? final? property x(val): R|java/util/SortedSet<kotlin/Int>| = STUB
|
||||||
|
public? get(): R|java/util/SortedSet<kotlin/Int>|
|
||||||
@@ -14,6 +14,7 @@ dependencies {
|
|||||||
testCompile(project(":compiler:fir:psi2fir"))
|
testCompile(project(":compiler:fir:psi2fir"))
|
||||||
testCompile(project(":compiler:fir:cones"))
|
testCompile(project(":compiler:fir:cones"))
|
||||||
testCompile(project(":compiler:fir:resolve"))
|
testCompile(project(":compiler:fir:resolve"))
|
||||||
|
testCompile(project(":compiler:fir:java"))
|
||||||
testCompile(project(":compiler:ir.ir2cfg"))
|
testCompile(project(":compiler:ir.ir2cfg"))
|
||||||
testCompile(project(":compiler:frontend"))
|
testCompile(project(":compiler:frontend"))
|
||||||
testCompile(project(":compiler:frontend.java"))
|
testCompile(project(":compiler:frontend.java"))
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ dependencies {
|
|||||||
testCompile(project(":compiler:fir:psi2fir"))
|
testCompile(project(":compiler:fir:psi2fir"))
|
||||||
testCompile(project(":compiler:fir:cones"))
|
testCompile(project(":compiler:fir:cones"))
|
||||||
testCompile(project(":compiler:fir:resolve"))
|
testCompile(project(":compiler:fir:resolve"))
|
||||||
|
testCompile(project(":compiler:fir:java"))
|
||||||
testCompile(project(":compiler:ir.ir2cfg"))
|
testCompile(project(":compiler:ir.ir2cfg"))
|
||||||
testCompile(project(":compiler:frontend"))
|
testCompile(project(":compiler:frontend"))
|
||||||
testCompile(project(":compiler:frontend.java"))
|
testCompile(project(":compiler:frontend.java"))
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir
|
package org.jetbrains.kotlin.fir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
|
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||||
@@ -14,14 +15,14 @@ import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
|
|||||||
|
|
||||||
abstract class AbstractFirResolveWithSessionTestCase : KotlinTestWithEnvironment() {
|
abstract class AbstractFirResolveWithSessionTestCase : KotlinTestWithEnvironment() {
|
||||||
|
|
||||||
fun createSession(): FirSession {
|
open fun createSession(): FirSession {
|
||||||
return object : FirSessionBase() {
|
return object : FirSessionBase() {
|
||||||
init {
|
init {
|
||||||
val firProvider = FirProviderImpl(this)
|
val firProvider = FirProviderImpl(this)
|
||||||
registerComponent(FirProvider::class, firProvider)
|
registerComponent(FirProvider::class, firProvider)
|
||||||
registerComponent(
|
registerComponent(
|
||||||
FirSymbolProvider::class,
|
FirSymbolProvider::class,
|
||||||
FirCompositeSymbolProvider(listOf(firProvider, FirLibrarySymbolProviderImpl(this)))
|
FirCompositeSymbolProvider(listOf(firProvider, JavaSymbolProvider(project), FirLibrarySymbolProviderImpl(this)))
|
||||||
)
|
)
|
||||||
registerComponent(FirQualifierResolver::class, FirQualifierResolverImpl(this))
|
registerComponent(FirQualifierResolver::class, FirQualifierResolverImpl(this))
|
||||||
registerComponent(FirTypeResolver::class, FirTypeResolverImpl())
|
registerComponent(FirTypeResolver::class, FirTypeResolverImpl())
|
||||||
|
|||||||
@@ -41,14 +41,12 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
|||||||
|
|
||||||
@TestMetadata("ft.kt")
|
@TestMetadata("ft.kt")
|
||||||
public void testFt() throws Exception {
|
public void testFt() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/ft.kt");
|
runTest("compiler/testData/fir/resolve/ft.kt");
|
||||||
doTest(fileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("functionTypes.kt")
|
@TestMetadata("functionTypes.kt")
|
||||||
public void testFunctionTypes() throws Exception {
|
public void testFunctionTypes() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/functionTypes.kt");
|
runTest("compiler/testData/fir/resolve/functionTypes.kt");
|
||||||
doTest(fileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("genericFunctions.kt")
|
@TestMetadata("genericFunctions.kt")
|
||||||
@@ -76,6 +74,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
|||||||
runTest("compiler/testData/fir/resolve/simpleTypeAlias.kt");
|
runTest("compiler/testData/fir/resolve/simpleTypeAlias.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("treeSet.kt")
|
||||||
|
public void testTreeSet() throws Exception {
|
||||||
|
runTest("compiler/testData/fir/resolve/treeSet.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("TwoDeclarationsInSameFile.kt")
|
@TestMetadata("TwoDeclarationsInSameFile.kt")
|
||||||
public void testTwoDeclarationsInSameFile() throws Exception {
|
public void testTwoDeclarationsInSameFile() throws Exception {
|
||||||
runTest("compiler/testData/fir/resolve/TwoDeclarationsInSameFile.kt");
|
runTest("compiler/testData/fir/resolve/TwoDeclarationsInSameFile.kt");
|
||||||
@@ -123,8 +126,7 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
|||||||
|
|
||||||
@TestMetadata("Annotations.kt")
|
@TestMetadata("Annotations.kt")
|
||||||
public void testAnnotations() throws Exception {
|
public void testAnnotations() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/multifile/Annotations.kt");
|
runTest("compiler/testData/fir/resolve/multifile/Annotations.kt");
|
||||||
doTest(fileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("NestedSuperType.kt")
|
@TestMetadata("NestedSuperType.kt")
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ include ":kotlin-build-common",
|
|||||||
":compiler:fir:tree:visitors-generator",
|
":compiler:fir:tree:visitors-generator",
|
||||||
":compiler:fir:psi2fir",
|
":compiler:fir:psi2fir",
|
||||||
":compiler:fir:resolve",
|
":compiler:fir:resolve",
|
||||||
|
":compiler:fir:java",
|
||||||
":compiler:frontend",
|
":compiler:frontend",
|
||||||
":compiler:frontend.java",
|
":compiler:frontend.java",
|
||||||
":compiler:frontend.script",
|
":compiler:frontend.script",
|
||||||
|
|||||||
Reference in New Issue
Block a user