FIR UAST: commonize utils from UAST Kotlin
This commit is contained in:
committed by
Ilya Kirillov
parent
f37c722c76
commit
eac875b5d6
@@ -0,0 +1,18 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(kotlinStdlib())
|
||||
implementation(project(":compiler:psi"))
|
||||
implementation(project(":compiler:light-classes"))
|
||||
|
||||
// BEWARE: Uast should not depend on IDEA.
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "asm-all", rootProject = rootProject) }
|
||||
compileOnly(intellijPluginDep("java")) { includeJars("java-api", "java-impl") }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.internal
|
||||
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import org.jetbrains.kotlin.psi.KtValueArgument
|
||||
import org.jetbrains.uast.UComment
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
|
||||
interface KotlinUElementWithComments : UElement {
|
||||
|
||||
override val comments: List<UComment>
|
||||
get() {
|
||||
val psi = sourcePsi ?: return emptyList()
|
||||
val childrenComments = psi.children.filterIsInstance<PsiComment>().map { UComment(it, this) }
|
||||
if (this !is UExpression) return childrenComments
|
||||
val childrenAndSiblingComments = childrenComments +
|
||||
psi.nearestCommentSibling(forward = true)?.let { listOf(UComment(it, this)) }.orEmpty() +
|
||||
psi.nearestCommentSibling(forward = false)?.let { listOf(UComment(it, this)) }.orEmpty()
|
||||
val parent = psi.parent as? KtValueArgument ?: return childrenAndSiblingComments
|
||||
|
||||
return childrenAndSiblingComments +
|
||||
parent.nearestCommentSibling(forward = true)?.let { listOf(UComment(it, this)) }.orEmpty() +
|
||||
parent.nearestCommentSibling(forward = false)?.let { listOf(UComment(it, this)) }.orEmpty()
|
||||
}
|
||||
|
||||
private fun PsiElement.nearestCommentSibling(forward: Boolean): PsiComment? {
|
||||
var sibling = if (forward) nextSibling else prevSibling
|
||||
while (sibling is PsiWhiteSpace && !sibling.text.contains('\n')) {
|
||||
sibling = if (forward) sibling.nextSibling else sibling.prevSibling
|
||||
}
|
||||
return sibling as? PsiComment
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMember
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.uast.UDeclaration
|
||||
import org.jetbrains.uast.UElement
|
||||
|
||||
fun <T> lz(initializer: () -> T) =
|
||||
lazy(LazyThreadSafetyMode.SYNCHRONIZED, initializer)
|
||||
|
||||
inline fun <reified T : UDeclaration, reified P : PsiElement> unwrap(element: P): P {
|
||||
val unwrapped = if (element is T) element.javaPsi else element
|
||||
assert(unwrapped !is UElement)
|
||||
return unwrapped as P
|
||||
}
|
||||
|
||||
fun unwrapFakeFileForLightClass(file: PsiFile): PsiFile = (file as? FakeFileForLightClass)?.ktFile ?: file
|
||||
|
||||
fun getKotlinMemberOrigin(element: PsiElement?): KtDeclaration? {
|
||||
(element as? KtLightMember<*>)?.lightMemberOrigin?.auxiliaryOriginalElement?.let { return it }
|
||||
(element as? KtLightElement<*, *>)?.kotlinOrigin?.let { return it as? KtDeclaration }
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.uast.kotlin
|
||||
|
||||
import org.jetbrains.uast.DEFAULT_EXPRESSION_TYPES_LIST
|
||||
import org.jetbrains.uast.DEFAULT_TYPES_LIST
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
|
||||
fun expressionTypes(requiredType: Class<out UElement>?) =
|
||||
requiredType?.let { arrayOf(it) } ?: DEFAULT_EXPRESSION_TYPES_LIST
|
||||
|
||||
fun elementTypes(requiredType: Class<out UElement>?) =
|
||||
requiredType?.let { arrayOf(it) } ?: DEFAULT_TYPES_LIST
|
||||
|
||||
fun <T : UElement> Array<out Class<out T>>.nonEmptyOr(default: Array<out Class<out UElement>>) =
|
||||
takeIf { it.isNotEmpty() } ?: default
|
||||
|
||||
inline fun <reified ActualT : UElement> Array<out Class<out UElement>>.el(f: () -> UElement?): UElement? {
|
||||
return if (isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
inline fun <reified ActualT : UElement> Array<out Class<out UElement>>.expr(f: () -> UExpression?): UExpression? {
|
||||
return if (isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
fun Array<out Class<out UElement>>.isAssignableFrom(cls: Class<*>) = any { it.isAssignableFrom(cls) }
|
||||
|
||||
fun <U : UElement> Array<out Class<out UElement>>.accommodate(vararg makers: UElementAlternative<out U>): Sequence<UElement> {
|
||||
val makersSeq = makers.asSequence()
|
||||
return this.asSequence()
|
||||
.flatMap { requiredType -> makersSeq.filter { requiredType.isAssignableFrom(it.uType) } }
|
||||
.distinct()
|
||||
.mapNotNull { it.make.invoke() }
|
||||
}
|
||||
|
||||
inline fun <reified U : UElement> alternative(noinline make: () -> U?) = UElementAlternative(U::class.java, make)
|
||||
|
||||
class UElementAlternative<U : UElement>(val uType: Class<U>, val make: () -> U?)
|
||||
Reference in New Issue
Block a user