FIR/UAST: commonize KotlinUFile

We can avoid explicit creation of UAnnotation and UImportStatement if we
use languagePlugin as a UAST element factory.
This commit is contained in:
Jinseong Jeon
2021-05-07 23:34:25 -07:00
committed by Ilya Kirillov
parent 5dc0b52e38
commit e5f3091f2c
5 changed files with 16 additions and 80 deletions
+1
View File
@@ -335,6 +335,7 @@ extra["tasksWithWarnings"] = listOf(
":kotlin-stdlib:compileTestKotlin",
":kotlin-stdlib-jdk7:compileTestKotlin",
":kotlin-stdlib-jdk8:compileTestKotlin",
":plugins:uast-kotlin-base:compileKotlin",
":plugins:uast-kotlin:compileKotlin",
":plugins:uast-kotlin:compileTestKotlin",
":plugins:uast-kotlin-fir:compileKotlin",
@@ -5,6 +5,7 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiRecursiveElementWalkingVisitor
@@ -15,19 +16,17 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.uast.*
import java.util.ArrayList
class FirKotlinUFile(
class KotlinUFile(
override val psi: KtFile,
override val languagePlugin: UastLanguagePlugin = firKotlinUastPlugin
override val languagePlugin: UastLanguagePlugin
) : UFile {
override val javaPsi: PsiElement? = null
override val sourcePsi: KtFile = psi
override val uAnnotations: List<UAnnotation>
get() {
// TODO: Not yet implemented
return emptyList()
}
override val uAnnotations: List<UAnnotation> by lz {
sourcePsi.annotationEntries.mapNotNull { languagePlugin.convertOpt(it, this) }
}
override val packageName: String by lz {
sourcePsi.packageFqName.asString()
@@ -35,24 +34,24 @@ class FirKotlinUFile(
override val allCommentsInFile by lz {
val comments = ArrayList<UComment>(0)
psi.accept(object : PsiRecursiveElementWalkingVisitor() {
sourcePsi.accept(object : PsiRecursiveElementWalkingVisitor() {
override fun visitComment(comment: PsiComment) {
comments += UComment(comment, this@FirKotlinUFile)
comments += UComment(comment, this@KotlinUFile)
}
})
comments
}
override val imports: List<UImportStatement> by lz {
sourcePsi.importDirectives.map { FirKotlinUImportStatement(it, this) }
sourcePsi.importDirectives.mapNotNull { languagePlugin.convertOpt(it, this@KotlinUFile) }
}
override val classes: List<UClass> by lz {
val facadeOrScriptClass = if (sourcePsi.isScript()) sourcePsi.script?.toLightClass() else sourcePsi.findFacadeClass()
val facadeOrScriptUClass = facadeOrScriptClass?.toUClass()?.let { listOf(it) } ?: emptyList()
val classes = sourcePsi.declarations.mapNotNull { (it as? KtClassOrObject)?.toUClass() }
val classes = sourcePsi.declarations.mapNotNull { (it as? KtClassOrObject)?.toLightClass()?.toUClass() }
facadeOrScriptUClass + classes
}
private fun PsiElement.toUClass() = languagePlugin.convertOpt<UClass>(this, this@FirKotlinUFile)
private fun PsiClass.toUClass() = languagePlugin.convertOpt<UClass>(this, this@KotlinUFile)
}
@@ -58,7 +58,7 @@ internal object FirKotlinConverter {
convertKtFile(original, givenParent, requiredTypes).firstOrNull()
}
is FakeFileForLightClass -> {
el<UFile> { FirKotlinUFile(original.navigationElement) }
el<UFile> { KotlinUFile(original.navigationElement, firKotlinUastPlugin) }
}
is KtLightClass -> {
@@ -112,7 +112,7 @@ internal object FirKotlinConverter {
): Sequence<UElement> {
return requiredTypes.accommodate(
// File
alternative { FirKotlinUFile(element) },
alternative { KotlinUFile(element, firKotlinUastPlugin) },
// Facade
alternative { element.findFacadeClass()?.let { AbstractFirKotlinUClass.create(it, givenParent) } }
)
@@ -562,7 +562,7 @@ internal object KotlinConverter {
is KtParameter -> convertParameter(original, givenParent, this).firstOrNull()
is KtFile -> convertKtFile(original, givenParent, this).firstOrNull()
is FakeFileForLightClass -> el<UFile> { KotlinUFile(original.navigationElement) }
is FakeFileForLightClass -> el<UFile> { KotlinUFile(original.navigationElement, kotlinUastPlugin) }
is KtAnnotationEntry -> el<UAnnotation>(build(::KotlinUAnnotation))
is KtCallExpression ->
if (expectedTypes.isAssignableFrom(KotlinUNestedAnnotation::class.java) && !expectedTypes.isAssignableFrom(UCallExpression::class.java)) {
@@ -680,7 +680,7 @@ internal object KotlinConverter {
givenParent: UElement?,
requiredTypes: Array<out Class<out UElement>>
): Sequence<UElement> = requiredTypes.accommodate(
alternative { KotlinUFile(element) },
alternative { KotlinUFile(element, kotlinUastPlugin) },
alternative { element.findFacadeClass()?.let { KotlinUClass.create(it, givenParent) } }
)
@@ -1,64 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiRecursiveElementWalkingVisitor
import org.jetbrains.kotlin.asJava.findFacadeClass
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.uast.*
import java.util.*
class KotlinUFile(
override val psi: KtFile,
override val languagePlugin: UastLanguagePlugin = kotlinUastPlugin
) : UFile {
override val packageName: String
get() = psi.packageFqName.asString()
override val annotations: List<UAnnotation>
get() = psi.annotationEntries.map { KotlinUAnnotation(it, this) }
override val javaPsi: PsiElement? = null
override val sourcePsi: KtFile = psi
override val allCommentsInFile by lz {
val comments = ArrayList<UComment>(0)
psi.accept(object : PsiRecursiveElementWalkingVisitor() {
override fun visitComment(comment: PsiComment) {
comments += UComment(comment, this@KotlinUFile)
}
})
comments
}
override val imports by lz { psi.importDirectives.map { KotlinUImportStatement(it, this) } }
override val classes by lz {
val facadeOrScriptClass = if (psi.isScript()) psi.script?.toLightClass() else psi.findFacadeClass()
val classes = psi.declarations.mapNotNull { (it as? KtClassOrObject)?.toLightClass()?.toUClass() }
(facadeOrScriptClass?.toUClass()?.let { listOf(it) } ?: emptyList()) + classes
}
private fun PsiClass.toUClass() = languagePlugin.convertOpt<UClass>(this, this@KotlinUFile)
}