mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
UAST: full sources reformatting
This commit is contained in:
+76
-76
@@ -1,95 +1,95 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.0.5'
|
||||
ext.intellij_core_version = '171.3019.7'
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
|
||||
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7'
|
||||
classpath 'de.undercouch:gradle-download-task:3.1.2'
|
||||
}
|
||||
ext.kotlin_version = '1.0.5'
|
||||
ext.intellij_core_version = '171.3019.7'
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
|
||||
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7'
|
||||
classpath 'de.undercouch:gradle-download-task:3.1.2'
|
||||
}
|
||||
}
|
||||
|
||||
String getUastVersion() {
|
||||
return System.getenv("ARTIFACT_VERSION") ?: "1.0"
|
||||
return System.getenv("ARTIFACT_VERSION") ?: "1.0"
|
||||
}
|
||||
|
||||
apply from: 'updateDependencies.gradle'
|
||||
|
||||
allprojects {
|
||||
group = 'org.jetbrains.uast'
|
||||
version = getUastVersion()
|
||||
group = 'org.jetbrains.uast'
|
||||
version = getUastVersion()
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
apply plugin: "maven-publish"
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
apply plugin: "maven-publish"
|
||||
|
||||
configurations {
|
||||
provided
|
||||
configurations {
|
||||
provided
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
compileClasspath += configurations.provided
|
||||
|
||||
java.srcDirs = ['src']
|
||||
kotlin.srcDirs = ['src']
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
compileClasspath += configurations.provided
|
||||
|
||||
java.srcDirs = ['src']
|
||||
kotlin.srcDirs = ['src']
|
||||
}
|
||||
|
||||
test {
|
||||
java.srcDirs = ['test']
|
||||
kotlin.srcDirs = ['test']
|
||||
}
|
||||
test {
|
||||
java.srcDirs = ['test']
|
||||
kotlin.srcDirs = ['test']
|
||||
}
|
||||
}
|
||||
|
||||
compileJava {
|
||||
sourceCompatibility = 1.6
|
||||
targetCompatibility = 1.6
|
||||
compileJava {
|
||||
sourceCompatibility = 1.6
|
||||
targetCompatibility = 1.6
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
bintray {
|
||||
user = System.getenv("BINTRAY_USER") ?: ""
|
||||
key = System.getenv("BINTRAY_API_KEY") ?: ""
|
||||
|
||||
publications = ['UastPublication']
|
||||
|
||||
pkg {
|
||||
repo = 'uast'
|
||||
name = 'uast'
|
||||
userOrg = 'kotlin'
|
||||
licenses = ['Apache-2.0']
|
||||
vcsUrl = SCM_URL
|
||||
|
||||
version {
|
||||
name = getUastVersion()
|
||||
released = new Date()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
bintray {
|
||||
user = System.getenv("BINTRAY_USER") ?: ""
|
||||
key = System.getenv("BINTRAY_API_KEY") ?: ""
|
||||
|
||||
publications = ['UastPublication']
|
||||
|
||||
pkg {
|
||||
repo = 'uast'
|
||||
name = 'uast'
|
||||
userOrg = 'kotlin'
|
||||
licenses = ['Apache-2.0']
|
||||
vcsUrl = SCM_URL
|
||||
|
||||
version {
|
||||
name = getUastVersion()
|
||||
released = new Date()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
UastPublication(MavenPublication) {
|
||||
from components.java
|
||||
groupId 'org.jetbrains.uast'
|
||||
artifactId project.name
|
||||
version getUastVersion()
|
||||
|
||||
artifact sourcesJar
|
||||
}
|
||||
}
|
||||
publishing {
|
||||
publications {
|
||||
UastPublication(MavenPublication) {
|
||||
from components.java
|
||||
groupId 'org.jetbrains.uast'
|
||||
artifactId project.name
|
||||
version getUastVersion()
|
||||
|
||||
artifact sourcesJar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,102 +28,102 @@ val CACHED_UELEMENT_KEY = Key.create<SoftReference<UElement>>("org.jetbrains.uas
|
||||
* Manages the UAST to PSI conversion.
|
||||
*/
|
||||
class UastContext(val project: Project) : UastLanguagePlugin {
|
||||
private companion object {
|
||||
private val CONTEXT_LANGUAGE = object : Language("UastContextLanguage") {}
|
||||
private companion object {
|
||||
private val CONTEXT_LANGUAGE = object : Language("UastContextLanguage") {}
|
||||
}
|
||||
|
||||
override val language: Language
|
||||
get() = CONTEXT_LANGUAGE
|
||||
|
||||
override val priority: Int
|
||||
get() = 0
|
||||
|
||||
val languagePlugins: Collection<UastLanguagePlugin>
|
||||
get() = UastLanguagePlugin.getInstances()
|
||||
|
||||
fun findPlugin(element: PsiElement): UastLanguagePlugin? {
|
||||
val language = element.language
|
||||
return languagePlugins.firstOrNull { it.language == language }
|
||||
}
|
||||
|
||||
override fun isFileSupported(fileName: String) = languagePlugins.any { it.isFileSupported(fileName) }
|
||||
|
||||
fun getMethod(method: PsiMethod): UMethod = convertWithParent<UMethod>(method)!!
|
||||
|
||||
fun getVariable(variable: PsiVariable): UVariable = convertWithParent<UVariable>(variable)!!
|
||||
|
||||
fun getClass(clazz: PsiClass): UClass = convertWithParent<UClass>(clazz)!!
|
||||
|
||||
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
val cachedElement = element.getUserData(CACHED_UELEMENT_KEY)?.get()
|
||||
if (cachedElement != null) {
|
||||
return if (requiredType == null || requiredType.isInstance(cachedElement)) cachedElement else null
|
||||
}
|
||||
|
||||
override val language: Language
|
||||
get() = CONTEXT_LANGUAGE
|
||||
return findPlugin(element)?.convertElement(element, parent, requiredType)
|
||||
}
|
||||
|
||||
override val priority: Int
|
||||
get() = 0
|
||||
|
||||
val languagePlugins: Collection<UastLanguagePlugin>
|
||||
get() = UastLanguagePlugin.getInstances()
|
||||
|
||||
fun findPlugin(element: PsiElement): UastLanguagePlugin? {
|
||||
val language = element.language
|
||||
return languagePlugins.firstOrNull { it.language == language }
|
||||
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
|
||||
val cachedElement = element.getUserData(CACHED_UELEMENT_KEY)?.get()
|
||||
if (cachedElement != null) {
|
||||
return if (requiredType == null || requiredType.isInstance(cachedElement)) cachedElement else null
|
||||
}
|
||||
|
||||
override fun isFileSupported(fileName: String) = languagePlugins.any { it.isFileSupported(fileName) }
|
||||
return findPlugin(element)?.convertElementWithParent(element, requiredType)
|
||||
}
|
||||
|
||||
fun getMethod(method: PsiMethod): UMethod = convertWithParent<UMethod>(method)!!
|
||||
override fun getMethodCallExpression(
|
||||
element: PsiElement,
|
||||
containingClassFqName: String?,
|
||||
methodName: String
|
||||
): UastLanguagePlugin.ResolvedMethod? {
|
||||
return findPlugin(element)?.getMethodCallExpression(element, containingClassFqName, methodName)
|
||||
}
|
||||
|
||||
fun getVariable(variable: PsiVariable): UVariable = convertWithParent<UVariable>(variable)!!
|
||||
override fun getConstructorCallExpression(
|
||||
element: PsiElement,
|
||||
fqName: String
|
||||
): UastLanguagePlugin.ResolvedConstructor? {
|
||||
return findPlugin(element)?.getConstructorCallExpression(element, fqName)
|
||||
}
|
||||
|
||||
fun getClass(clazz: PsiClass): UClass = convertWithParent<UClass>(clazz)!!
|
||||
override fun isExpressionValueUsed(element: UExpression): Boolean {
|
||||
val language = element.getLanguage()
|
||||
return (languagePlugins.firstOrNull { it.language == language })?.isExpressionValueUsed(element) ?: false
|
||||
}
|
||||
|
||||
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
val cachedElement = element.getUserData(CACHED_UELEMENT_KEY)?.get()
|
||||
if (cachedElement != null) {
|
||||
return if (requiredType == null || requiredType.isInstance(cachedElement)) cachedElement else null
|
||||
}
|
||||
|
||||
return findPlugin(element)?.convertElement(element, parent, requiredType)
|
||||
}
|
||||
|
||||
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
|
||||
val cachedElement = element.getUserData(CACHED_UELEMENT_KEY)?.get()
|
||||
if (cachedElement != null) {
|
||||
return if (requiredType == null || requiredType.isInstance(cachedElement)) cachedElement else null
|
||||
}
|
||||
|
||||
return findPlugin(element)?.convertElementWithParent(element, requiredType)
|
||||
}
|
||||
|
||||
override fun getMethodCallExpression(
|
||||
element: PsiElement,
|
||||
containingClassFqName: String?,
|
||||
methodName: String
|
||||
): UastLanguagePlugin.ResolvedMethod? {
|
||||
return findPlugin(element)?.getMethodCallExpression(element, containingClassFqName, methodName)
|
||||
}
|
||||
|
||||
override fun getConstructorCallExpression(
|
||||
element: PsiElement,
|
||||
fqName: String
|
||||
): UastLanguagePlugin.ResolvedConstructor? {
|
||||
return findPlugin(element)?.getConstructorCallExpression(element, fqName)
|
||||
}
|
||||
|
||||
override fun isExpressionValueUsed(element: UExpression): Boolean {
|
||||
val language = element.getLanguage()
|
||||
return (languagePlugins.firstOrNull { it.language == language })?.isExpressionValueUsed(element) ?: false
|
||||
}
|
||||
|
||||
private tailrec fun UElement.getLanguage(): Language {
|
||||
psi?.language?.let { return it }
|
||||
val containingElement = this.uastParent ?: throw IllegalStateException("At least UFile should have a language")
|
||||
return containingElement.getLanguage()
|
||||
}
|
||||
private tailrec fun UElement.getLanguage(): Language {
|
||||
psi?.language?.let { return it }
|
||||
val containingElement = this.uastParent ?: throw IllegalStateException("At least UFile should have a language")
|
||||
return containingElement.getLanguage()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the element along with its parents to UAST.
|
||||
*/
|
||||
fun PsiElement?.toUElement() =
|
||||
this?.let { ServiceManager.getService(project, UastContext::class.java).convertElementWithParent(this, null) }
|
||||
this?.let { ServiceManager.getService(project, UastContext::class.java).convertElementWithParent(this, null) }
|
||||
|
||||
/**
|
||||
* Converts the element to an UAST element of the given type. Returns null if the PSI element type does not correspond
|
||||
* to the given UAST element type.
|
||||
*/
|
||||
fun <T : UElement> PsiElement?.toUElement(cls: Class<out T>): T? =
|
||||
this?.let { ServiceManager.getService(project, UastContext::class.java).convertElementWithParent(this, cls) as T? }
|
||||
this?.let { ServiceManager.getService(project, UastContext::class.java).convertElementWithParent(this, cls) as T? }
|
||||
|
||||
inline fun <reified T : UElement> PsiElement?.toUElementOfType(): T? =
|
||||
this?.let { ServiceManager.getService(project, UastContext::class.java).convertElementWithParent(this, T::class.java) as T? }
|
||||
this?.let { ServiceManager.getService(project, UastContext::class.java).convertElementWithParent(this, T::class.java) as T? }
|
||||
|
||||
/**
|
||||
* Finds an UAST element of a given type at the given [offset] in the specified file. Returns null if there is no UAST
|
||||
* element of the given type at the given offset.
|
||||
*/
|
||||
fun <T : UElement> PsiFile.findUElementAt(offset: Int, cls: Class<out T>): T? {
|
||||
val element = findElementAt(offset) ?: return null
|
||||
val uElement = element.toUElement() ?: return null
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return uElement.withContainingElements.firstOrNull { cls.isInstance(it) } as T?
|
||||
val element = findElementAt(offset) ?: return null
|
||||
val uElement = element.toUElement() ?: return null
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return uElement.withContainingElements.firstOrNull { cls.isInstance(it) } as T?
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,12 +131,12 @@ fun <T : UElement> PsiFile.findUElementAt(offset: Int, cls: Class<out T>): T? {
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun <T : UElement> PsiElement?.getUastParentOfType(cls: Class<out T>, strict: Boolean = false): T? = this?.run {
|
||||
val startingElement = if (strict) this.parent else this
|
||||
val parentSequence = generateSequence(startingElement, PsiElement::getParent)
|
||||
val firstUElement = parentSequence.mapNotNull { it.toUElement() }.firstOrNull() ?: return null
|
||||
val startingElement = if (strict) this.parent else this
|
||||
val parentSequence = generateSequence(startingElement, PsiElement::getParent)
|
||||
val firstUElement = parentSequence.mapNotNull { it.toUElement() }.firstOrNull() ?: return null
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return firstUElement.withContainingElements.firstOrNull { cls.isInstance(it) } as T?
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return firstUElement.withContainingElements.firstOrNull { cls.isInstance(it) } as T?
|
||||
}
|
||||
|
||||
inline fun <reified T : UElement> PsiElement?.getUastParentOfType(strict: Boolean = false): T? = getUastParentOfType(T::class.java, strict)
|
||||
|
||||
@@ -21,103 +21,103 @@ import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.psi.*
|
||||
|
||||
interface UastLanguagePlugin {
|
||||
companion object {
|
||||
val extensionPointName: ExtensionPointName<UastLanguagePlugin> =
|
||||
ExtensionPointName.create<UastLanguagePlugin>("org.jetbrains.uast.uastLanguagePlugin")
|
||||
companion object {
|
||||
val extensionPointName: ExtensionPointName<UastLanguagePlugin> =
|
||||
ExtensionPointName.create<UastLanguagePlugin>("org.jetbrains.uast.uastLanguagePlugin")
|
||||
|
||||
fun getInstances(): Collection<UastLanguagePlugin> {
|
||||
val rootArea = Extensions.getRootArea()
|
||||
if (!rootArea.hasExtensionPoint(extensionPointName.name)) return listOf()
|
||||
return rootArea.getExtensionPoint(extensionPointName).extensions.toList()
|
||||
}
|
||||
fun getInstances(): Collection<UastLanguagePlugin> {
|
||||
val rootArea = Extensions.getRootArea()
|
||||
if (!rootArea.hasExtensionPoint(extensionPointName.name)) return listOf()
|
||||
return rootArea.getExtensionPoint(extensionPointName).extensions.toList()
|
||||
}
|
||||
}
|
||||
|
||||
data class ResolvedMethod(val call: UCallExpression, val method: PsiMethod)
|
||||
data class ResolvedConstructor(val call: UCallExpression, val constructor: PsiMethod, val clazz: PsiClass)
|
||||
data class ResolvedMethod(val call: UCallExpression, val method: PsiMethod)
|
||||
data class ResolvedConstructor(val call: UCallExpression, val constructor: PsiMethod, val clazz: PsiClass)
|
||||
|
||||
val language: Language
|
||||
val language: Language
|
||||
|
||||
/**
|
||||
* Checks if the file with the given [fileName] is supported.
|
||||
*
|
||||
* @param fileName the source file name.
|
||||
* @return true, if the file is supported by this converter, false otherwise.
|
||||
*/
|
||||
fun isFileSupported(fileName: String): Boolean
|
||||
|
||||
/**
|
||||
* Returns the converter priority. Might be positive, negative or 0 (Java's is 0).
|
||||
* UastConverter with the higher priority will be queried earlier.
|
||||
*
|
||||
* Priority is useful when a language N wraps its own elements (NElement) to, for example, Java's PsiElements,
|
||||
* and Java resolves the reference to such wrapped PsiElements, not the original NElement.
|
||||
* In this case N implementation can handle such wrappers in UastConverter earlier than Java's converter,
|
||||
* so N language converter will have a higher priority.
|
||||
*/
|
||||
val priority: Int
|
||||
/**
|
||||
* Checks if the file with the given [fileName] is supported.
|
||||
*
|
||||
* @param fileName the source file name.
|
||||
* @return true, if the file is supported by this converter, false otherwise.
|
||||
*/
|
||||
fun isFileSupported(fileName: String): Boolean
|
||||
|
||||
/**
|
||||
* Converts a PSI element, the parent of which already has an UAST representation, to UAST.
|
||||
*
|
||||
* @param element the element to convert
|
||||
* @param parent the parent as an UAST element, or null if the element is a file
|
||||
* @param requiredType the expected type of the result.
|
||||
* @return the converted element, or null if the element isn't supported or doesn't match the required result type.
|
||||
*/
|
||||
fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>? = null): UElement?
|
||||
/**
|
||||
* Returns the converter priority. Might be positive, negative or 0 (Java's is 0).
|
||||
* UastConverter with the higher priority will be queried earlier.
|
||||
*
|
||||
* Priority is useful when a language N wraps its own elements (NElement) to, for example, Java's PsiElements,
|
||||
* and Java resolves the reference to such wrapped PsiElements, not the original NElement.
|
||||
* In this case N implementation can handle such wrappers in UastConverter earlier than Java's converter,
|
||||
* so N language converter will have a higher priority.
|
||||
*/
|
||||
val priority: Int
|
||||
|
||||
/**
|
||||
* Converts a PSI element, along with its chain of parents, to UAST.
|
||||
*
|
||||
* @param element the element to convert
|
||||
* @param requiredType the expected type of the result.
|
||||
* @return the converted element, or null if the element isn't supported or doesn't match the required result type.
|
||||
*/
|
||||
fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement?
|
||||
/**
|
||||
* Converts a PSI element, the parent of which already has an UAST representation, to UAST.
|
||||
*
|
||||
* @param element the element to convert
|
||||
* @param parent the parent as an UAST element, or null if the element is a file
|
||||
* @param requiredType the expected type of the result.
|
||||
* @return the converted element, or null if the element isn't supported or doesn't match the required result type.
|
||||
*/
|
||||
fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>? = null): UElement?
|
||||
|
||||
fun getMethodCallExpression(
|
||||
element: PsiElement,
|
||||
containingClassFqName: String?,
|
||||
methodName: String
|
||||
): ResolvedMethod?
|
||||
/**
|
||||
* Converts a PSI element, along with its chain of parents, to UAST.
|
||||
*
|
||||
* @param element the element to convert
|
||||
* @param requiredType the expected type of the result.
|
||||
* @return the converted element, or null if the element isn't supported or doesn't match the required result type.
|
||||
*/
|
||||
fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement?
|
||||
|
||||
fun getConstructorCallExpression(
|
||||
element: PsiElement,
|
||||
fqName: String
|
||||
) : ResolvedConstructor?
|
||||
fun getMethodCallExpression(
|
||||
element: PsiElement,
|
||||
containingClassFqName: String?,
|
||||
methodName: String
|
||||
): ResolvedMethod?
|
||||
|
||||
fun getMethodBody(element: PsiMethod): UExpression? {
|
||||
if (element is UMethod) return element.uastBody
|
||||
return (convertElementWithParent(element, null) as? UMethod)?.uastBody
|
||||
}
|
||||
fun getConstructorCallExpression(
|
||||
element: PsiElement,
|
||||
fqName: String
|
||||
): ResolvedConstructor?
|
||||
|
||||
fun getInitializerBody(element: PsiClassInitializer): UExpression {
|
||||
if (element is UClassInitializer) return element.uastBody
|
||||
return (convertElementWithParent(element, null) as? UClassInitializer)?.uastBody ?: UastEmptyExpression
|
||||
}
|
||||
fun getMethodBody(element: PsiMethod): UExpression? {
|
||||
if (element is UMethod) return element.uastBody
|
||||
return (convertElementWithParent(element, null) as? UMethod)?.uastBody
|
||||
}
|
||||
|
||||
fun getInitializerBody(element: PsiVariable): UExpression? {
|
||||
if (element is UVariable) return element.uastInitializer
|
||||
return (convertElementWithParent(element, null) as? UVariable)?.uastInitializer
|
||||
}
|
||||
fun getInitializerBody(element: PsiClassInitializer): UExpression {
|
||||
if (element is UClassInitializer) return element.uastBody
|
||||
return (convertElementWithParent(element, null) as? UClassInitializer)?.uastBody ?: UastEmptyExpression
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the expression value is used.
|
||||
* Do not rely on this property too much, its value can be approximate in some cases.
|
||||
*/
|
||||
fun isExpressionValueUsed(element: UExpression): Boolean
|
||||
fun getInitializerBody(element: PsiVariable): UExpression? {
|
||||
if (element is UVariable) return element.uastInitializer
|
||||
return (convertElementWithParent(element, null) as? UVariable)?.uastInitializer
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the expression value is used.
|
||||
* Do not rely on this property too much, its value can be approximate in some cases.
|
||||
*/
|
||||
fun isExpressionValueUsed(element: UExpression): Boolean
|
||||
}
|
||||
|
||||
inline fun <reified T : UElement> UastLanguagePlugin.convertOpt(element: PsiElement?, parent: UElement?): T? {
|
||||
if (element == null) return null
|
||||
return convertElement(element, parent) as? T
|
||||
if (element == null) return null
|
||||
return convertElement(element, parent) as? T
|
||||
}
|
||||
|
||||
inline fun <reified T : UElement> UastLanguagePlugin.convert(element: PsiElement, parent: UElement?): T {
|
||||
return convertElement(element, parent, T::class.java) as T
|
||||
return convertElement(element, parent, T::class.java) as T
|
||||
}
|
||||
|
||||
inline fun <reified T : UElement> UastLanguagePlugin.convertWithParent(element: PsiElement?): T? {
|
||||
if (element == null) return null
|
||||
return convertElementWithParent(element, T::class.java) as? T
|
||||
if (element == null) return null
|
||||
return convertElementWithParent(element, T::class.java) as? T
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("UastUtils")
|
||||
|
||||
package org.jetbrains.uast
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
@@ -29,51 +30,51 @@ inline fun <reified T : UElement> UElement.getParentOfType(strict: Boolean = tru
|
||||
|
||||
@JvmOverloads
|
||||
fun <T : UElement> UElement.getParentOfType(parentClass: Class<out UElement>, strict: Boolean = true): T? {
|
||||
var element = (if (strict) uastParent else this) ?: return null
|
||||
while (true) {
|
||||
if (parentClass.isInstance(element)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return element as T
|
||||
}
|
||||
element = element.uastParent ?: return null
|
||||
var element = (if (strict) uastParent else this) ?: return null
|
||||
while (true) {
|
||||
if (parentClass.isInstance(element)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return element as T
|
||||
}
|
||||
element = element.uastParent ?: return null
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : UElement> UElement.getParentOfType(
|
||||
parentClass: Class<out UElement>,
|
||||
strict: Boolean = true,
|
||||
vararg terminators: Class<out UElement>
|
||||
parentClass: Class<out UElement>,
|
||||
strict: Boolean = true,
|
||||
vararg terminators: Class<out UElement>
|
||||
): T? {
|
||||
var element = (if (strict) uastParent else this) ?: return null
|
||||
while (true) {
|
||||
if (parentClass.isInstance(element)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return element as T
|
||||
}
|
||||
if (terminators.any { it.isInstance(element) }) {
|
||||
return null
|
||||
}
|
||||
element = element.uastParent ?: return null
|
||||
var element = (if (strict) uastParent else this) ?: return null
|
||||
while (true) {
|
||||
if (parentClass.isInstance(element)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return element as T
|
||||
}
|
||||
if (terminators.any { it.isInstance(element) }) {
|
||||
return null
|
||||
}
|
||||
element = element.uastParent ?: return null
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : UElement> UElement.getParentOfType(
|
||||
strict: Boolean = true,
|
||||
firstParentClass: Class<out T>,
|
||||
vararg parentClasses: Class<out T>
|
||||
strict: Boolean = true,
|
||||
firstParentClass: Class<out T>,
|
||||
vararg parentClasses: Class<out T>
|
||||
): T? {
|
||||
var element = (if (strict) uastParent else this) ?: return null
|
||||
while (true) {
|
||||
if (firstParentClass.isInstance(element)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return element as T
|
||||
}
|
||||
if (parentClasses.any { it.isInstance(element) }) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return element as T
|
||||
}
|
||||
element = element.uastParent ?: return null
|
||||
var element = (if (strict) uastParent else this) ?: return null
|
||||
while (true) {
|
||||
if (firstParentClass.isInstance(element)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return element as T
|
||||
}
|
||||
if (parentClasses.any { it.isInstance(element) }) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return element as T
|
||||
}
|
||||
element = element.uastParent ?: return null
|
||||
}
|
||||
}
|
||||
|
||||
fun UElement.getUCallExpression(): UCallExpression? = this.withContainingElements.mapNotNull {
|
||||
@@ -86,6 +87,7 @@ fun UElement.getUCallExpression(): UCallExpression? = this.withContainingElement
|
||||
|
||||
@Deprecated(message = "This function is deprecated, use getContainingUFile", replaceWith = ReplaceWith("getContainingUFile()"))
|
||||
fun UElement.getContainingFile() = getContainingUFile()
|
||||
|
||||
fun UElement.getContainingUFile() = getParentOfType<UFile>(UFile::class.java)
|
||||
|
||||
fun UElement.getContainingUClass() = getParentOfType<UClass>(UClass::class.java)
|
||||
@@ -99,16 +101,16 @@ fun UElement.getContainingVariable() = getContainingUVariable()?.psi
|
||||
fun PsiElement?.getContainingClass() = this?.let { PsiTreeUtil.getParentOfType(it, PsiClass::class.java) }
|
||||
|
||||
fun UElement.isChildOf(probablyParent: UElement?, strict: Boolean = false): Boolean {
|
||||
tailrec fun isChildOf(current: UElement?, probablyParent: UElement): Boolean {
|
||||
return when (current) {
|
||||
null -> false
|
||||
probablyParent -> true
|
||||
else -> isChildOf(current.uastParent, probablyParent)
|
||||
}
|
||||
tailrec fun isChildOf(current: UElement?, probablyParent: UElement): Boolean {
|
||||
return when (current) {
|
||||
null -> false
|
||||
probablyParent -> true
|
||||
else -> isChildOf(current.uastParent, probablyParent)
|
||||
}
|
||||
|
||||
if (probablyParent == null) return false
|
||||
return isChildOf(if (strict) this else uastParent, probablyParent)
|
||||
}
|
||||
|
||||
if (probablyParent == null) return false
|
||||
return isChildOf(if (strict) this else uastParent, probablyParent)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,7 +123,7 @@ fun UElement.tryResolve(): PsiElement? = (this as? UResolvable)?.resolve()
|
||||
fun UElement.tryResolveNamed(): PsiNamedElement? = (this as? UResolvable)?.resolve() as? PsiNamedElement
|
||||
|
||||
fun UElement.tryResolveUDeclaration(context: UastContext): UDeclaration? {
|
||||
return (this as? UResolvable)?.resolve()?.let { context.convertElementWithParent(it, null) as? UDeclaration }
|
||||
return (this as? UResolvable)?.resolve()?.let { context.convertElementWithParent(it, null) as? UDeclaration }
|
||||
}
|
||||
|
||||
fun UReferenceExpression?.getQualifiedName() = (this?.resolve() as? PsiClass)?.qualifiedName
|
||||
@@ -137,22 +139,22 @@ fun UExpression.evaluateString(): String? = evaluate() as? String
|
||||
fun UFile.getIoFile(): File? = psi.virtualFile?.let { VfsUtilCore.virtualToIoFile(it) }
|
||||
|
||||
tailrec fun UElement.getUastContext(): UastContext {
|
||||
val psi = this.psi
|
||||
if (psi != null) {
|
||||
return ServiceManager.getService(psi.project, UastContext::class.java) ?: error("UastContext not found")
|
||||
}
|
||||
val psi = this.psi
|
||||
if (psi != null) {
|
||||
return ServiceManager.getService(psi.project, UastContext::class.java) ?: error("UastContext not found")
|
||||
}
|
||||
|
||||
return (uastParent ?: error("PsiElement should exist at least for UFile")).getUastContext()
|
||||
return (uastParent ?: error("PsiElement should exist at least for UFile")).getUastContext()
|
||||
}
|
||||
|
||||
tailrec fun UElement.getLanguagePlugin(): UastLanguagePlugin {
|
||||
val psi = this.psi
|
||||
if (psi != null) {
|
||||
val uastContext = ServiceManager.getService(psi.project, UastContext::class.java) ?: error("UastContext not found")
|
||||
return uastContext.findPlugin(psi) ?: error("Language plugin was not found for $this (${this.javaClass.name})")
|
||||
}
|
||||
val psi = this.psi
|
||||
if (psi != null) {
|
||||
val uastContext = ServiceManager.getService(psi.project, UastContext::class.java) ?: error("UastContext not found")
|
||||
return uastContext.findPlugin(psi) ?: error("Language plugin was not found for $this (${this.javaClass.name})")
|
||||
}
|
||||
|
||||
return (uastParent ?: error("PsiElement should exist at least for UFile")).getLanguagePlugin()
|
||||
return (uastParent ?: error("PsiElement should exist at least for UFile")).getLanguagePlugin()
|
||||
}
|
||||
|
||||
fun Collection<UElement?>.toPsiElements() = mapNotNull { it?.psi }
|
||||
|
||||
@@ -20,14 +20,14 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.uast.internal.log
|
||||
|
||||
class UComment(override val psi: PsiComment, override val uastParent: UElement) : JvmDeclarationUElement {
|
||||
@Deprecated("Use a constructor that takes PsiComment as parameter")
|
||||
constructor(psi: PsiElement, parent: UElement) : this(psi as PsiComment, parent)
|
||||
@Deprecated("Use a constructor that takes PsiComment as parameter")
|
||||
constructor(psi: PsiElement, parent: UElement) : this(psi as PsiComment, parent)
|
||||
|
||||
val text: String
|
||||
get() = asSourceString()
|
||||
val text: String
|
||||
get() = asSourceString()
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun asRenderString(): String = asSourceString()
|
||||
override fun asSourceString(): String = psi.text
|
||||
override fun asRenderString(): String = asSourceString()
|
||||
override fun asSourceString(): String = psi.text
|
||||
}
|
||||
@@ -23,82 +23,82 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* The common interface for all Uast elements.
|
||||
*/
|
||||
interface UElement {
|
||||
/**
|
||||
* Returns the element parent.
|
||||
*/
|
||||
val uastParent: UElement?
|
||||
/**
|
||||
* Returns the element parent.
|
||||
*/
|
||||
val uastParent: UElement?
|
||||
|
||||
/**
|
||||
* Returns the PSI element underlying this element. Note that some UElements are synthetic and do not have
|
||||
* an underlying PSI element; this doesn't mean that they are invalid.
|
||||
*/
|
||||
val psi: PsiElement?
|
||||
/**
|
||||
* Returns the PSI element underlying this element. Note that some UElements are synthetic and do not have
|
||||
* an underlying PSI element; this doesn't mean that they are invalid.
|
||||
*/
|
||||
val psi: PsiElement?
|
||||
|
||||
/**
|
||||
* Returns true if this element is valid, false otherwise.
|
||||
*/
|
||||
val isPsiValid: Boolean
|
||||
get() = psi?.isValid ?: true
|
||||
/**
|
||||
* Returns true if this element is valid, false otherwise.
|
||||
*/
|
||||
val isPsiValid: Boolean
|
||||
get() = psi?.isValid ?: true
|
||||
|
||||
/**
|
||||
* Returns the list of comments for this element.
|
||||
*/
|
||||
val comments: List<UComment>
|
||||
get() = emptyList()
|
||||
/**
|
||||
* Returns the list of comments for this element.
|
||||
*/
|
||||
val comments: List<UComment>
|
||||
get() = emptyList()
|
||||
|
||||
/**
|
||||
* Returns the log string (usually one line containing the class name and some additional information).
|
||||
*
|
||||
* Examples:
|
||||
* UWhileExpression
|
||||
* UBinaryExpression (>)
|
||||
* UCallExpression (println)
|
||||
* USimpleReferenceExpression (i)
|
||||
* ULiteralExpression (5)
|
||||
*
|
||||
* @return the expression tree for this element.
|
||||
* @see [UIfExpression] for example.
|
||||
*/
|
||||
fun asLogString(): String
|
||||
/**
|
||||
* Returns the log string (usually one line containing the class name and some additional information).
|
||||
*
|
||||
* Examples:
|
||||
* UWhileExpression
|
||||
* UBinaryExpression (>)
|
||||
* UCallExpression (println)
|
||||
* USimpleReferenceExpression (i)
|
||||
* ULiteralExpression (5)
|
||||
*
|
||||
* @return the expression tree for this element.
|
||||
* @see [UIfExpression] for example.
|
||||
*/
|
||||
fun asLogString(): String
|
||||
|
||||
/**
|
||||
* Returns the string in pseudo-code.
|
||||
*
|
||||
* Output example (should be something like this):
|
||||
* while (i > 5) {
|
||||
* println("Hello, world")
|
||||
* i--
|
||||
* }
|
||||
*
|
||||
* @return the rendered text.
|
||||
* @see [UIfExpression] for example.
|
||||
*/
|
||||
fun asRenderString(): String = asLogString()
|
||||
/**
|
||||
* Returns the string in pseudo-code.
|
||||
*
|
||||
* Output example (should be something like this):
|
||||
* while (i > 5) {
|
||||
* println("Hello, world")
|
||||
* i--
|
||||
* }
|
||||
*
|
||||
* @return the rendered text.
|
||||
* @see [UIfExpression] for example.
|
||||
*/
|
||||
fun asRenderString(): String = asLogString()
|
||||
|
||||
/**
|
||||
* Returns the string as written in the source file.
|
||||
* Use this String only for logging and diagnostic text messages.
|
||||
*
|
||||
* @return the original text.
|
||||
*/
|
||||
fun asSourceString(): String = asRenderString()
|
||||
/**
|
||||
* Returns the string as written in the source file.
|
||||
* Use this String only for logging and diagnostic text messages.
|
||||
*
|
||||
* @return the original text.
|
||||
*/
|
||||
fun asSourceString(): String = asRenderString()
|
||||
|
||||
/**
|
||||
* Passes the element to the specified visitor.
|
||||
*
|
||||
* @param visitor the visitor to pass the element to.
|
||||
*/
|
||||
fun accept(visitor: UastVisitor) {
|
||||
visitor.visitElement(this)
|
||||
visitor.afterVisitElement(this)
|
||||
}
|
||||
/**
|
||||
* Passes the element to the specified visitor.
|
||||
*
|
||||
* @param visitor the visitor to pass the element to.
|
||||
*/
|
||||
fun accept(visitor: UastVisitor) {
|
||||
visitor.visitElement(this)
|
||||
visitor.afterVisitElement(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes the element to the specified typed visitor.
|
||||
*
|
||||
* @param visitor the visitor to pass the element to.
|
||||
*/
|
||||
fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D): R = visitor.visitElement(this, data)
|
||||
/**
|
||||
* Passes the element to the specified typed visitor.
|
||||
*
|
||||
* @param visitor the visitor to pass the element to.
|
||||
*/
|
||||
fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D): R = visitor.visitElement(this, data)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,34 +107,34 @@ interface UElement {
|
||||
*/
|
||||
interface JvmDeclarationUElement : UElement {
|
||||
|
||||
/**
|
||||
* Returns the PSI element in original (physical) tree to which this UElement corresponds.
|
||||
* **Note**: that some UElements are synthetic and do not have an underlying PSI element;
|
||||
* this doesn't mean that they are invalid.
|
||||
*/
|
||||
val sourcePsi: PsiElement?
|
||||
get() = psi
|
||||
/**
|
||||
* Returns the PSI element in original (physical) tree to which this UElement corresponds.
|
||||
* **Note**: that some UElements are synthetic and do not have an underlying PSI element;
|
||||
* this doesn't mean that they are invalid.
|
||||
*/
|
||||
val sourcePsi: PsiElement?
|
||||
get() = psi
|
||||
|
||||
/**
|
||||
* Returns the element which try to mimic Java-api psi element: [com.intellij.psi.PsiClass], [com.intellij.psi.PsiMethod] or [com.intellij.psi.PsiAnnotation] etc.
|
||||
* Will return null if this UElement doesn't have Java representation or it is not implemented.
|
||||
*/
|
||||
val javaPsi: PsiElement?
|
||||
get() = psi
|
||||
/**
|
||||
* Returns the element which try to mimic Java-api psi element: [com.intellij.psi.PsiClass], [com.intellij.psi.PsiMethod] or [com.intellij.psi.PsiAnnotation] etc.
|
||||
* Will return null if this UElement doesn't have Java representation or it is not implemented.
|
||||
*/
|
||||
val javaPsi: PsiElement?
|
||||
get() = psi
|
||||
|
||||
/**
|
||||
* Returns the PSI element underlying this element. Note that some UElements are synthetic and do not have
|
||||
* an underlying PSI element; this doesn't mean that they are invalid.
|
||||
*
|
||||
* **Node for implementors**: please implement both [sourcePsi] and [javaPsi] fields or make them return `null` explicitly
|
||||
* if implementing is not possible. Redirect `psi` to one of them keeping existing behavior, use [sourcePsi] if nothing else is specified.
|
||||
*/
|
||||
@Deprecated("ambiguous psi element, use `sourcePsi` or `javaPsi`", ReplaceWith("javaPsi"))
|
||||
override val psi: PsiElement?
|
||||
/**
|
||||
* Returns the PSI element underlying this element. Note that some UElements are synthetic and do not have
|
||||
* an underlying PSI element; this doesn't mean that they are invalid.
|
||||
*
|
||||
* **Node for implementors**: please implement both [sourcePsi] and [javaPsi] fields or make them return `null` explicitly
|
||||
* if implementing is not possible. Redirect `psi` to one of them keeping existing behavior, use [sourcePsi] if nothing else is specified.
|
||||
*/
|
||||
@Deprecated("ambiguous psi element, use `sourcePsi` or `javaPsi`", ReplaceWith("javaPsi"))
|
||||
override val psi: PsiElement?
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequence including this element and its containing elements.
|
||||
*/
|
||||
val UElement.withContainingElements: Sequence<UElement>
|
||||
get() = generateSequence(this, UElement::uastParent)
|
||||
get() = generateSequence(this, UElement::uastParent)
|
||||
|
||||
@@ -25,55 +25,55 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents an expression or statement (which is considered as an expression in Uast).
|
||||
*/
|
||||
interface UExpression : UElement, UAnnotated {
|
||||
/**
|
||||
* Returns the expression value or null if the value can't be calculated.
|
||||
*/
|
||||
fun evaluate(): Any? = null
|
||||
/**
|
||||
* Returns the expression value or null if the value can't be calculated.
|
||||
*/
|
||||
fun evaluate(): Any? = null
|
||||
|
||||
/**
|
||||
* Returns expression type, or null if type can not be inferred, or if this expression is a statement.
|
||||
*/
|
||||
fun getExpressionType(): PsiType? = null
|
||||
/**
|
||||
* Returns expression type, or null if type can not be inferred, or if this expression is a statement.
|
||||
*/
|
||||
fun getExpressionType(): PsiType? = null
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
visitor.visitElement(this)
|
||||
visitor.afterVisitElement(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
visitor.visitElement(this)
|
||||
visitor.afterVisitElement(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitExpression(this, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an annotated element.
|
||||
*/
|
||||
interface UAnnotated : UElement {
|
||||
/**
|
||||
* Returns the list of annotations applied to the current element.
|
||||
*/
|
||||
val annotations: List<UAnnotation>
|
||||
/**
|
||||
* Returns the list of annotations applied to the current element.
|
||||
*/
|
||||
val annotations: List<UAnnotation>
|
||||
|
||||
/**
|
||||
* Looks up for annotation element using the annotation qualified name.
|
||||
*
|
||||
* @param fqName the qualified name to search
|
||||
* @return the first annotation element with the specified qualified name, or null if there is no annotation with such name.
|
||||
*/
|
||||
fun findAnnotation(fqName: String): UAnnotation? = annotations.firstOrNull { it.qualifiedName == fqName }
|
||||
/**
|
||||
* Looks up for annotation element using the annotation qualified name.
|
||||
*
|
||||
* @param fqName the qualified name to search
|
||||
* @return the first annotation element with the specified qualified name, or null if there is no annotation with such name.
|
||||
*/
|
||||
fun findAnnotation(fqName: String): UAnnotation? = annotations.firstOrNull { it.qualifiedName == fqName }
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a labeled element.
|
||||
*/
|
||||
interface ULabeled : UElement {
|
||||
/**
|
||||
* Returns the label name, or null if the label is empty.
|
||||
*/
|
||||
val label: String?
|
||||
/**
|
||||
* Returns the label name, or null if the label is empty.
|
||||
*/
|
||||
val label: String?
|
||||
|
||||
/**
|
||||
* Returns the label identifier, or null if the label is empty.
|
||||
*/
|
||||
val labelIdentifier: UIdentifier?
|
||||
/**
|
||||
* Returns the label identifier, or null if the label is empty.
|
||||
*/
|
||||
val labelIdentifier: UIdentifier?
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,14 +85,14 @@ interface ULabeled : UElement {
|
||||
* Use [UastEmptyExpression] in this case.
|
||||
*/
|
||||
object UastEmptyExpression : UExpression, JvmDeclarationUElement {
|
||||
override val uastParent: UElement?
|
||||
get() = null
|
||||
override val uastParent: UElement?
|
||||
get() = null
|
||||
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
|
||||
override val psi: PsiElement?
|
||||
get() = null
|
||||
override val psi: PsiElement?
|
||||
get() = null
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
}
|
||||
@@ -20,18 +20,18 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.uast.internal.log
|
||||
|
||||
class UIdentifier(
|
||||
override val psi: PsiElement?,
|
||||
override val uastParent: UElement?
|
||||
override val psi: PsiElement?,
|
||||
override val uastParent: UElement?
|
||||
) : JvmDeclarationUElement {
|
||||
/**
|
||||
* Returns the identifier name.
|
||||
*/
|
||||
val name: String
|
||||
get() = psi?.text ?: "<error>"
|
||||
|
||||
override fun asLogString() = log("Identifier ($name)")
|
||||
/**
|
||||
* Returns the identifier name.
|
||||
*/
|
||||
val name: String
|
||||
get() = psi?.text ?: "<error>"
|
||||
|
||||
override val sourcePsi: PsiElement? = psi
|
||||
override fun asLogString() = log("Identifier ($name)")
|
||||
|
||||
override val javaPsi: PsiElement? = null
|
||||
override val sourcePsi: PsiElement? = psi
|
||||
|
||||
override val javaPsi: PsiElement? = null
|
||||
}
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.uast
|
||||
import com.intellij.psi.PsiElement
|
||||
|
||||
interface UResolvable {
|
||||
/**
|
||||
* Resolve the reference.
|
||||
* Note that the reference is *always* resolved to an unwrapped [PsiElement], never to a [UElement].
|
||||
*
|
||||
* @return the resolved element, or null if the reference couldn't be resolved.
|
||||
*/
|
||||
fun resolve(): PsiElement?
|
||||
/**
|
||||
* Resolve the reference.
|
||||
* Note that the reference is *always* resolved to an unwrapped [PsiElement], never to a [UElement].
|
||||
*
|
||||
* @return the resolved element, or null if the reference couldn't be resolved.
|
||||
*/
|
||||
fun resolve(): PsiElement?
|
||||
}
|
||||
|
||||
fun UResolvable.resolveToUElement(): UElement? = resolve().toUElement()
|
||||
|
||||
@@ -19,13 +19,13 @@ import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.PsiTypeVisitor
|
||||
|
||||
object UastErrorType : PsiType(emptyArray()) {
|
||||
override fun getInternalCanonicalText() = "<ErrorType>"
|
||||
override fun equalsToText(text: String) = false
|
||||
override fun getCanonicalText() = internalCanonicalText
|
||||
override fun getPresentableText() = canonicalText
|
||||
override fun isValid() = false
|
||||
override fun getResolveScope() = null
|
||||
override fun getSuperTypes() = emptyArray<PsiType>()
|
||||
override fun getInternalCanonicalText() = "<ErrorType>"
|
||||
override fun equalsToText(text: String) = false
|
||||
override fun getCanonicalText() = internalCanonicalText
|
||||
override fun getPresentableText() = canonicalText
|
||||
override fun isValid() = false
|
||||
override fun getResolveScope() = null
|
||||
override fun getSuperTypes() = emptyArray<PsiType>()
|
||||
|
||||
override fun <A : Any?> accept(visitor: PsiTypeVisitor<A>) = visitor.visitType(this)
|
||||
override fun <A : Any?> accept(visitor: PsiTypeVisitor<A>) = visitor.visitType(this)
|
||||
}
|
||||
@@ -30,37 +30,37 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* loop expression.
|
||||
*/
|
||||
interface UDoWhileExpression : ULoopExpression {
|
||||
/**
|
||||
* Returns the loop post-condition.
|
||||
*/
|
||||
val condition: UExpression
|
||||
/**
|
||||
* Returns the loop post-condition.
|
||||
*/
|
||||
val condition: UExpression
|
||||
|
||||
/**
|
||||
* Returns an identifier for the 'do' keyword.
|
||||
*/
|
||||
val doIdentifier: UIdentifier
|
||||
/**
|
||||
* Returns an identifier for the 'do' keyword.
|
||||
*/
|
||||
val doIdentifier: UIdentifier
|
||||
|
||||
/**
|
||||
* Returns an identifier for the 'while' keyword.
|
||||
*/
|
||||
val whileIdentifier: UIdentifier
|
||||
/**
|
||||
* Returns an identifier for the 'while' keyword.
|
||||
*/
|
||||
val whileIdentifier: UIdentifier
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitDoWhileExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
condition.accept(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitDoWhileExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitDoWhileExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
condition.accept(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitDoWhileExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitDoWhileExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitDoWhileExpression(this, data)
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
append("do ")
|
||||
append(body.asRenderString())
|
||||
appendln("while (${condition.asRenderString()})")
|
||||
}
|
||||
override fun asRenderString() = buildString {
|
||||
append("do ")
|
||||
append(body.asRenderString())
|
||||
appendln("while (${condition.asRenderString()})")
|
||||
}
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
}
|
||||
|
||||
@@ -30,40 +30,40 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* loop expression.
|
||||
*/
|
||||
interface UForEachExpression : ULoopExpression {
|
||||
/**
|
||||
* Returns the loop variable.
|
||||
*/
|
||||
val variable: UParameter
|
||||
/**
|
||||
* Returns the loop variable.
|
||||
*/
|
||||
val variable: UParameter
|
||||
|
||||
/**
|
||||
* Returns the iterated value (collection, sequence, iterable etc.)
|
||||
*/
|
||||
val iteratedValue: UExpression
|
||||
/**
|
||||
* Returns the iterated value (collection, sequence, iterable etc.)
|
||||
*/
|
||||
val iteratedValue: UExpression
|
||||
|
||||
/**
|
||||
* Returns the identifier for the 'for' ('foreach') keyword.
|
||||
*/
|
||||
val forIdentifier: UIdentifier
|
||||
/**
|
||||
* Returns the identifier for the 'for' ('foreach') keyword.
|
||||
*/
|
||||
val forIdentifier: UIdentifier
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitForEachExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
iteratedValue.accept(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitForEachExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitForEachExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
iteratedValue.accept(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitForEachExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitForEachExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitForEachExpression(this, data)
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
append("for (")
|
||||
append(variable.name)
|
||||
append(" : ")
|
||||
append(iteratedValue.asRenderString())
|
||||
append(") ")
|
||||
append(body.asRenderString())
|
||||
}
|
||||
override fun asRenderString() = buildString {
|
||||
append("for (")
|
||||
append(variable.name)
|
||||
append(" : ")
|
||||
append(iteratedValue.asRenderString())
|
||||
append(") ")
|
||||
append(body.asRenderString())
|
||||
}
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
}
|
||||
|
||||
@@ -30,49 +30,49 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* loop expression.
|
||||
*/
|
||||
interface UForExpression : ULoopExpression {
|
||||
/**
|
||||
* Returns the [UExpression] containing variable declarations, or null if the are no variables declared.
|
||||
*/
|
||||
val declaration: UExpression?
|
||||
/**
|
||||
* Returns the [UExpression] containing variable declarations, or null if the are no variables declared.
|
||||
*/
|
||||
val declaration: UExpression?
|
||||
|
||||
/**
|
||||
* Returns the loop condition, or null if the condition is empty.
|
||||
*/
|
||||
val condition: UExpression?
|
||||
/**
|
||||
* Returns the loop condition, or null if the condition is empty.
|
||||
*/
|
||||
val condition: UExpression?
|
||||
|
||||
/**
|
||||
* Returns the loop update expression(s).
|
||||
*/
|
||||
val update: UExpression?
|
||||
/**
|
||||
* Returns the loop update expression(s).
|
||||
*/
|
||||
val update: UExpression?
|
||||
|
||||
/**
|
||||
* Returns the identifier for the 'for' keyword.
|
||||
*/
|
||||
val forIdentifier: UIdentifier
|
||||
/**
|
||||
* Returns the identifier for the 'for' keyword.
|
||||
*/
|
||||
val forIdentifier: UIdentifier
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitForExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
declaration?.accept(visitor)
|
||||
condition?.accept(visitor)
|
||||
update?.accept(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitForExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitForExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
declaration?.accept(visitor)
|
||||
condition?.accept(visitor)
|
||||
update?.accept(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitForExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitForExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitForExpression(this, data)
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
append("for (")
|
||||
declaration?.let { append(it.asRenderString()) }
|
||||
append("; ")
|
||||
condition?.let { append(it.asRenderString()) }
|
||||
append("; ")
|
||||
update?.let { append(it.asRenderString()) }
|
||||
append(") ")
|
||||
append(body.asRenderString())
|
||||
}
|
||||
override fun asRenderString() = buildString {
|
||||
append("for (")
|
||||
declaration?.let { append(it.asRenderString()) }
|
||||
append("; ")
|
||||
condition?.let { append(it.asRenderString()) }
|
||||
append("; ")
|
||||
update?.let { append(it.asRenderString()) }
|
||||
append(") ")
|
||||
append(body.asRenderString())
|
||||
}
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
}
|
||||
|
||||
@@ -36,66 +36,67 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* condition expressions.
|
||||
*/
|
||||
interface UIfExpression : UExpression {
|
||||
/**
|
||||
* Returns the condition expression.
|
||||
*/
|
||||
val condition: UExpression
|
||||
/**
|
||||
* Returns the condition expression.
|
||||
*/
|
||||
val condition: UExpression
|
||||
|
||||
/**
|
||||
* Returns the expression which is executed if the condition is true, or null if the expression is empty.
|
||||
*/
|
||||
val thenExpression: UExpression?
|
||||
/**
|
||||
* Returns the expression which is executed if the condition is true, or null if the expression is empty.
|
||||
*/
|
||||
val thenExpression: UExpression?
|
||||
|
||||
/**
|
||||
* Returns the expression which is executed if the condition is false, or null if the expression is empty.
|
||||
*/
|
||||
val elseExpression: UExpression?
|
||||
/**
|
||||
* Returns the expression which is executed if the condition is false, or null if the expression is empty.
|
||||
*/
|
||||
val elseExpression: UExpression?
|
||||
|
||||
/**
|
||||
* Returns true if the expression is ternary (condition ? trueExpression : falseExpression).
|
||||
*/
|
||||
val isTernary: Boolean
|
||||
/**
|
||||
* Returns true if the expression is ternary (condition ? trueExpression : falseExpression).
|
||||
*/
|
||||
val isTernary: Boolean
|
||||
|
||||
/**
|
||||
* Returns an identifier for the 'if' keyword.
|
||||
*/
|
||||
val ifIdentifier: UIdentifier
|
||||
/**
|
||||
* Returns an identifier for the 'if' keyword.
|
||||
*/
|
||||
val ifIdentifier: UIdentifier
|
||||
|
||||
/**
|
||||
* Returns an identifier for the 'else' keyword, or null if the conditional expression has not the 'else' part.
|
||||
*/
|
||||
val elseIdentifier: UIdentifier?
|
||||
/**
|
||||
* Returns an identifier for the 'else' keyword, or null if the conditional expression has not the 'else' part.
|
||||
*/
|
||||
val elseIdentifier: UIdentifier?
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitIfExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
condition.accept(visitor)
|
||||
thenExpression?.accept(visitor)
|
||||
elseExpression?.accept(visitor)
|
||||
visitor.afterVisitIfExpression(this)
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitIfExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
condition.accept(visitor)
|
||||
thenExpression?.accept(visitor)
|
||||
elseExpression?.accept(visitor)
|
||||
visitor.afterVisitIfExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitIfExpression(this, data)
|
||||
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
if (isTernary) {
|
||||
append("(" + condition.asRenderString() + ")")
|
||||
append(" ? ")
|
||||
append("(" + (thenExpression?.asRenderString() ?: "<noexpr>") + ")")
|
||||
append(" : ")
|
||||
append("(" + (elseExpression?.asRenderString() ?: "<noexpr>") + ")")
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitIfExpression(this, data)
|
||||
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
if (isTernary) {
|
||||
append("(" + condition.asRenderString() + ")")
|
||||
append(" ? ")
|
||||
append("(" + (thenExpression?.asRenderString() ?: "<noexpr>") + ")")
|
||||
append(" : ")
|
||||
append("(" + (elseExpression?.asRenderString() ?: "<noexpr>") + ")")
|
||||
} else {
|
||||
append("if (${condition.asRenderString()}) ")
|
||||
thenExpression?.let { append(it.asRenderString()) }
|
||||
val elseBranch = elseExpression
|
||||
if (elseBranch != null && elseBranch !is UastEmptyExpression) {
|
||||
if (thenExpression !is UBlockExpression) append(" ")
|
||||
append("else ")
|
||||
append(elseBranch.asRenderString())
|
||||
}
|
||||
}
|
||||
else {
|
||||
append("if (${condition.asRenderString()}) ")
|
||||
thenExpression?.let { append(it.asRenderString()) }
|
||||
val elseBranch = elseExpression
|
||||
if (elseBranch != null && elseBranch !is UastEmptyExpression) {
|
||||
if (thenExpression !is UBlockExpression) append(" ")
|
||||
append("else ")
|
||||
append(elseBranch.asRenderString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@ import org.jetbrains.uast.visitor.UastTypedVisitor
|
||||
* Represents a loop expression.
|
||||
*/
|
||||
interface ULoopExpression : UExpression {
|
||||
/**
|
||||
* Returns the loop body [UExpression].
|
||||
*/
|
||||
val body: UExpression
|
||||
/**
|
||||
* Returns the loop body [UExpression].
|
||||
*/
|
||||
val body: UExpression
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitLoopExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitLoopExpression(this, data)
|
||||
}
|
||||
@@ -33,40 +33,40 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* conditional expression.
|
||||
*/
|
||||
interface USwitchExpression : UExpression {
|
||||
/**
|
||||
Returns the expression on which the `switch` expression is performed.
|
||||
*/
|
||||
val expression: UExpression?
|
||||
/**
|
||||
Returns the expression on which the `switch` expression is performed.
|
||||
*/
|
||||
val expression: UExpression?
|
||||
|
||||
/**
|
||||
Returns the switch body.
|
||||
The body should contain [USwitchClauseExpression] expressions.
|
||||
*/
|
||||
val body: UExpressionList
|
||||
/**
|
||||
Returns the switch body.
|
||||
The body should contain [USwitchClauseExpression] expressions.
|
||||
*/
|
||||
val body: UExpressionList
|
||||
|
||||
/**
|
||||
* Returns an identifier for the 'switch' ('case', 'when', ...) keyword.
|
||||
*/
|
||||
val switchIdentifier: UIdentifier
|
||||
/**
|
||||
* Returns an identifier for the 'switch' ('case', 'when', ...) keyword.
|
||||
*/
|
||||
val switchIdentifier: UIdentifier
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitSwitchExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expression?.accept(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitSwitchExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitSwitchExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expression?.accept(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitSwitchExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitSwitchExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitSwitchExpression(this, data)
|
||||
|
||||
override fun asLogString() = log<USwitchExpression>()
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
val expr = expression?.let { "(" + it.asRenderString() + ") " } ?: ""
|
||||
appendln("switch $expr")
|
||||
appendln(body.asRenderString())
|
||||
}
|
||||
override fun asLogString() = log<USwitchExpression>()
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
val expr = expression?.let { "(" + it.asRenderString() + ") " } ?: ""
|
||||
appendln("switch $expr")
|
||||
appendln(body.asRenderString())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,25 +75,25 @@ interface USwitchExpression : UExpression {
|
||||
* and the actual body expression should be the next element in the parent expression list.
|
||||
*/
|
||||
interface USwitchClauseExpression : UExpression {
|
||||
/**
|
||||
* Returns the list of values for this clause, or null if the are no values for this close
|
||||
* (for example, for the `else` clause).
|
||||
*/
|
||||
val caseValues: List<UExpression>
|
||||
/**
|
||||
* Returns the list of values for this clause, or null if the are no values for this close
|
||||
* (for example, for the `else` clause).
|
||||
*/
|
||||
val caseValues: List<UExpression>
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitSwitchClauseExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
caseValues.acceptList(visitor)
|
||||
visitor.afterVisitSwitchClauseExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitSwitchClauseExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
caseValues.acceptList(visitor)
|
||||
visitor.afterVisitSwitchClauseExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitSwitchClauseExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitSwitchClauseExpression(this, data)
|
||||
|
||||
override fun asRenderString() = caseValues.joinToString { it.asRenderString() } + " -> "
|
||||
override fun asRenderString() = caseValues.joinToString { it.asRenderString() } + " -> "
|
||||
|
||||
override fun asLogString() = "USwitchClauseExpression"
|
||||
override fun asLogString() = "USwitchClauseExpression"
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,20 +103,20 @@ interface USwitchClauseExpression : UExpression {
|
||||
* Implementing this interface *is the right way* to support `switch` clauses in your language.
|
||||
*/
|
||||
interface USwitchClauseExpressionWithBody : USwitchClauseExpression {
|
||||
/**
|
||||
* Returns the body expression for this clause.
|
||||
*/
|
||||
val body: UExpressionList
|
||||
/**
|
||||
* Returns the body expression for this clause.
|
||||
*/
|
||||
val body: UExpressionList
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitSwitchClauseExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
caseValues.acceptList(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitSwitchClauseExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitSwitchClauseExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
caseValues.acceptList(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitSwitchClauseExpression(this)
|
||||
}
|
||||
|
||||
override fun asRenderString() = caseValues.joinToString { it.asRenderString() } + " -> " + body.asRenderString()
|
||||
override fun asRenderString() = caseValues.joinToString { it.asRenderString() } + " -> " + body.asRenderString()
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
}
|
||||
@@ -42,104 +42,104 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* expressions.
|
||||
*/
|
||||
interface UTryExpression : UExpression {
|
||||
/**
|
||||
* Returns `true` if the try expression is a try-with-resources expression.
|
||||
*/
|
||||
val hasResources: Boolean
|
||||
/**
|
||||
* Returns `true` if the try expression is a try-with-resources expression.
|
||||
*/
|
||||
val hasResources: Boolean
|
||||
|
||||
/**
|
||||
* Returns the list of resource variables declared in this expression, or an empty list if this expression is not a `try-with-resources` expression.
|
||||
*/
|
||||
val resourceVariables: List<UVariable>
|
||||
/**
|
||||
* Returns the list of resource variables declared in this expression, or an empty list if this expression is not a `try-with-resources` expression.
|
||||
*/
|
||||
val resourceVariables: List<UVariable>
|
||||
|
||||
/**
|
||||
* Returns the `try` clause expression.
|
||||
*/
|
||||
val tryClause: UExpression
|
||||
/**
|
||||
* Returns the `try` clause expression.
|
||||
*/
|
||||
val tryClause: UExpression
|
||||
|
||||
/**
|
||||
* Returns the `catch` clauses [UCatchClause] expression list.
|
||||
*/
|
||||
val catchClauses: List<UCatchClause>
|
||||
/**
|
||||
* Returns the `catch` clauses [UCatchClause] expression list.
|
||||
*/
|
||||
val catchClauses: List<UCatchClause>
|
||||
|
||||
/**
|
||||
* Returns the `finally` clause expression, or null if the `finally` clause is absent.
|
||||
*/
|
||||
val finallyClause: UExpression?
|
||||
/**
|
||||
* Returns the `finally` clause expression, or null if the `finally` clause is absent.
|
||||
*/
|
||||
val finallyClause: UExpression?
|
||||
|
||||
/**
|
||||
* Returns an identifier for the 'try' keyword.
|
||||
*/
|
||||
val tryIdentifier: UIdentifier
|
||||
/**
|
||||
* Returns an identifier for the 'try' keyword.
|
||||
*/
|
||||
val tryIdentifier: UIdentifier
|
||||
|
||||
/**
|
||||
* Returns an identifier for the 'finally' keyword, or null if the 'try' expression has not a 'finally' clause.
|
||||
*/
|
||||
val finallyIdentifier: UIdentifier?
|
||||
/**
|
||||
* Returns an identifier for the 'finally' keyword, or null if the 'try' expression has not a 'finally' clause.
|
||||
*/
|
||||
val finallyIdentifier: UIdentifier?
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitTryExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
resourceVariables.acceptList(visitor)
|
||||
tryClause.accept(visitor)
|
||||
catchClauses.acceptList(visitor)
|
||||
finallyClause?.accept(visitor)
|
||||
visitor.afterVisitTryExpression(this)
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitTryExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
resourceVariables.acceptList(visitor)
|
||||
tryClause.accept(visitor)
|
||||
catchClauses.acceptList(visitor)
|
||||
finallyClause?.accept(visitor)
|
||||
visitor.afterVisitTryExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitTryExpression(this, data)
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
append("try ")
|
||||
if (hasResources) {
|
||||
append("(")
|
||||
append(resourceVariables.joinToString("\n") { it.asRenderString() })
|
||||
append(")")
|
||||
}
|
||||
appendln(tryClause.asRenderString().trim('\n', '\r'))
|
||||
catchClauses.forEach { appendln(it.asRenderString().trim('\n', '\r')) }
|
||||
finallyClause?.let { append("finally ").append(it.asRenderString().trim('\n', '\r')) }
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitTryExpression(this, data)
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
append("try ")
|
||||
if (hasResources) {
|
||||
append("(")
|
||||
append(resourceVariables.joinToString("\n") { it.asRenderString() })
|
||||
append(")")
|
||||
}
|
||||
appendln(tryClause.asRenderString().trim('\n', '\r'))
|
||||
catchClauses.forEach { appendln(it.asRenderString().trim('\n', '\r')) }
|
||||
finallyClause?.let { append("finally ").append(it.asRenderString().trim('\n', '\r')) }
|
||||
}
|
||||
|
||||
override fun asLogString() = log(if (hasResources) "with resources" else "")
|
||||
override fun asLogString() = log(if (hasResources) "with resources" else "")
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the `catch` clause in [UTryExpression].
|
||||
*/
|
||||
interface UCatchClause : UElement {
|
||||
/**
|
||||
* Returns the `catch` clause body expression.
|
||||
*/
|
||||
val body: UExpression
|
||||
/**
|
||||
* Returns the `catch` clause body expression.
|
||||
*/
|
||||
val body: UExpression
|
||||
|
||||
/**
|
||||
* Returns the exception parameter variables for this `catch` clause.
|
||||
*/
|
||||
val parameters: List<UParameter>
|
||||
/**
|
||||
* Returns the exception parameter variables for this `catch` clause.
|
||||
*/
|
||||
val parameters: List<UParameter>
|
||||
|
||||
/**
|
||||
* Returns the exception type references for this `catch` clause.
|
||||
*/
|
||||
val typeReferences: List<UTypeReferenceExpression>
|
||||
/**
|
||||
* Returns the exception type references for this `catch` clause.
|
||||
*/
|
||||
val typeReferences: List<UTypeReferenceExpression>
|
||||
|
||||
/**
|
||||
* Returns the expression types for this `catch` clause.
|
||||
*/
|
||||
val types: List<PsiType>
|
||||
get() = typeReferences.map { it.type }
|
||||
/**
|
||||
* Returns the expression types for this `catch` clause.
|
||||
*/
|
||||
val types: List<PsiType>
|
||||
get() = typeReferences.map { it.type }
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitCatchClause(this)) return
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitCatchClause(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitCatchClause(this)) return
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitCatchClause(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitCatchClause(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitCatchClause(this, data)
|
||||
|
||||
override fun asLogString() = log(parameters.joinToString { it.name ?: "<error>" })
|
||||
override fun asLogString() = log(parameters.joinToString { it.name ?: "<error>" })
|
||||
|
||||
override fun asRenderString() = "catch (e) " + body.asRenderString()
|
||||
override fun asRenderString() = "catch (e) " + body.asRenderString()
|
||||
}
|
||||
@@ -30,31 +30,31 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* expression.
|
||||
*/
|
||||
interface UWhileExpression : ULoopExpression {
|
||||
/**
|
||||
* Returns the loop condition.
|
||||
*/
|
||||
val condition: UExpression
|
||||
/**
|
||||
* Returns the loop condition.
|
||||
*/
|
||||
val condition: UExpression
|
||||
|
||||
/**
|
||||
* Returns an identifier for the 'while' keyword.
|
||||
*/
|
||||
val whileIdentifier: UIdentifier
|
||||
/**
|
||||
* Returns an identifier for the 'while' keyword.
|
||||
*/
|
||||
val whileIdentifier: UIdentifier
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitWhileExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
condition.accept(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitWhileExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitWhileExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
condition.accept(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitWhileExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitWhileExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitWhileExpression(this, data)
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
append("while (${condition.asRenderString()}) ")
|
||||
append(body.asRenderString())
|
||||
}
|
||||
override fun asRenderString() = buildString {
|
||||
append("while (${condition.asRenderString()}) ")
|
||||
append(body.asRenderString())
|
||||
}
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
}
|
||||
|
||||
@@ -25,45 +25,45 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* An annotation wrapper to be used in [UastVisitor].
|
||||
*/
|
||||
interface UAnnotation : UElement, UResolvable {
|
||||
/**
|
||||
* Returns the annotation qualified name.
|
||||
*/
|
||||
val qualifiedName: String?
|
||||
/**
|
||||
* Returns the annotation qualified name.
|
||||
*/
|
||||
val qualifiedName: String?
|
||||
|
||||
/**
|
||||
* Returns the annotation class, or null if the class reference was not resolved.
|
||||
*/
|
||||
override fun resolve(): PsiClass?
|
||||
/**
|
||||
* Returns the annotation class, or null if the class reference was not resolved.
|
||||
*/
|
||||
override fun resolve(): PsiClass?
|
||||
|
||||
/**
|
||||
* Returns the annotation values.
|
||||
*/
|
||||
val attributeValues: List<UNamedExpression>
|
||||
/**
|
||||
* Returns the annotation values.
|
||||
*/
|
||||
val attributeValues: List<UNamedExpression>
|
||||
|
||||
fun findAttributeValue(name: String?): UExpression?
|
||||
fun findAttributeValue(name: String?): UExpression?
|
||||
|
||||
fun findDeclaredAttributeValue(name: String?): UExpression?
|
||||
fun findDeclaredAttributeValue(name: String?): UExpression?
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
append("@")
|
||||
append(qualifiedName)
|
||||
if(attributeValues.isNotEmpty()) {
|
||||
attributeValues.joinTo(
|
||||
buffer = this,
|
||||
prefix = "(",
|
||||
postfix = ")",
|
||||
transform = UNamedExpression::asRenderString)
|
||||
}
|
||||
override fun asRenderString() = buildString {
|
||||
append("@")
|
||||
append(qualifiedName)
|
||||
if (attributeValues.isNotEmpty()) {
|
||||
attributeValues.joinTo(
|
||||
buffer = this,
|
||||
prefix = "(",
|
||||
postfix = ")",
|
||||
transform = UNamedExpression::asRenderString)
|
||||
}
|
||||
}
|
||||
|
||||
override fun asLogString() = log("fqName = $qualifiedName")
|
||||
override fun asLogString() = log("fqName = $qualifiedName")
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitAnnotation(this)) return
|
||||
attributeValues.acceptList(visitor)
|
||||
visitor.afterVisitAnnotation(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitAnnotation(this)) return
|
||||
attributeValues.acceptList(visitor)
|
||||
visitor.afterVisitAnnotation(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitAnnotation(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitAnnotation(this, data)
|
||||
}
|
||||
@@ -26,69 +26,69 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* A class wrapper to be used in [UastVisitor].
|
||||
*/
|
||||
interface UClass : UDeclaration, PsiClass {
|
||||
override val psi: PsiClass
|
||||
override val psi: PsiClass
|
||||
|
||||
/**
|
||||
* Returns a [UClass] wrapper of the superclass of this class, or null if this class is [java.lang.Object].
|
||||
*/
|
||||
override fun getSuperClass(): UClass? {
|
||||
val superClass = psi.superClass ?: return null
|
||||
return getUastContext().convertWithParent(superClass)
|
||||
/**
|
||||
* Returns a [UClass] wrapper of the superclass of this class, or null if this class is [java.lang.Object].
|
||||
*/
|
||||
override fun getSuperClass(): UClass? {
|
||||
val superClass = psi.superClass ?: return null
|
||||
return getUastContext().convertWithParent(superClass)
|
||||
}
|
||||
|
||||
val uastSuperTypes: List<UTypeReferenceExpression>
|
||||
|
||||
/**
|
||||
* Returns [UDeclaration] wrappers for the class declarations.
|
||||
*/
|
||||
val uastDeclarations: List<UDeclaration>
|
||||
|
||||
override fun getFields(): Array<UField> =
|
||||
psi.fields.map { getLanguagePlugin().convert<UField>(it, this) }.toTypedArray()
|
||||
|
||||
override fun getInitializers(): Array<UClassInitializer> =
|
||||
psi.initializers.map { getLanguagePlugin().convert<UClassInitializer>(it, this) }.toTypedArray()
|
||||
|
||||
override fun getMethods(): Array<UMethod> =
|
||||
psi.methods.map { getLanguagePlugin().convert<UMethod>(it, this) }.toTypedArray()
|
||||
|
||||
override fun getInnerClasses(): Array<UClass> =
|
||||
psi.innerClasses.map { getLanguagePlugin().convert<UClass>(it, this) }.toTypedArray()
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitClass(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
uastDeclarations.acceptList(visitor)
|
||||
visitor.afterVisitClass(this)
|
||||
}
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
append(psi.renderModifiers())
|
||||
val kind = when {
|
||||
psi.isAnnotationType -> "annotation"
|
||||
psi.isInterface -> "interface"
|
||||
psi.isEnum -> "enum"
|
||||
else -> "class"
|
||||
}
|
||||
|
||||
val uastSuperTypes: List<UTypeReferenceExpression>
|
||||
|
||||
/**
|
||||
* Returns [UDeclaration] wrappers for the class declarations.
|
||||
*/
|
||||
val uastDeclarations: List<UDeclaration>
|
||||
|
||||
override fun getFields(): Array<UField> =
|
||||
psi.fields.map { getLanguagePlugin().convert<UField>(it, this) }.toTypedArray()
|
||||
|
||||
override fun getInitializers(): Array<UClassInitializer> =
|
||||
psi.initializers.map { getLanguagePlugin().convert<UClassInitializer>(it, this) }.toTypedArray()
|
||||
|
||||
override fun getMethods(): Array<UMethod> =
|
||||
psi.methods.map { getLanguagePlugin().convert<UMethod>(it, this) }.toTypedArray()
|
||||
|
||||
override fun getInnerClasses(): Array<UClass> =
|
||||
psi.innerClasses.map { getLanguagePlugin().convert<UClass>(it, this) }.toTypedArray()
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitClass(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
uastDeclarations.acceptList(visitor)
|
||||
visitor.afterVisitClass(this)
|
||||
append(kind).append(' ').append(psi.name)
|
||||
val superTypes = uastSuperTypes
|
||||
if (superTypes.isNotEmpty()) {
|
||||
append(" : ")
|
||||
append(superTypes.joinToString { it.asRenderString() })
|
||||
}
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
append(psi.renderModifiers())
|
||||
val kind = when {
|
||||
psi.isAnnotationType -> "annotation"
|
||||
psi.isInterface -> "interface"
|
||||
psi.isEnum -> "enum"
|
||||
else -> "class"
|
||||
}
|
||||
append(kind).append(' ').append(psi.name)
|
||||
val superTypes = uastSuperTypes
|
||||
if (superTypes.isNotEmpty()) {
|
||||
append(" : ")
|
||||
append(superTypes.joinToString { it.asRenderString() })
|
||||
}
|
||||
appendln(" {")
|
||||
uastDeclarations.forEachIndexed { index, declaration ->
|
||||
appendln(declaration.asRenderString().withMargin)
|
||||
}
|
||||
append("}")
|
||||
appendln(" {")
|
||||
uastDeclarations.forEachIndexed { index, declaration ->
|
||||
appendln(declaration.asRenderString().withMargin)
|
||||
}
|
||||
append("}")
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitClass(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitClass(this, data)
|
||||
}
|
||||
|
||||
interface UAnonymousClass : UClass, PsiAnonymousClass {
|
||||
override val psi: PsiAnonymousClass
|
||||
override val psi: PsiAnonymousClass
|
||||
}
|
||||
@@ -26,30 +26,30 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* A class initializer wrapper to be used in [UastVisitor].
|
||||
*/
|
||||
interface UClassInitializer : UDeclaration, PsiClassInitializer {
|
||||
override val psi: PsiClassInitializer
|
||||
override val psi: PsiClassInitializer
|
||||
|
||||
/**
|
||||
* Returns the body of this class initializer.
|
||||
*/
|
||||
val uastBody: UExpression
|
||||
/**
|
||||
* Returns the body of this class initializer.
|
||||
*/
|
||||
val uastBody: UExpression
|
||||
|
||||
@Deprecated("Use uastBody instead.", ReplaceWith("uastBody"))
|
||||
override fun getBody() = psi.body
|
||||
@Deprecated("Use uastBody instead.", ReplaceWith("uastBody"))
|
||||
override fun getBody() = psi.body
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitInitializer(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
uastBody.accept(visitor)
|
||||
visitor.afterVisitInitializer(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitInitializer(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
uastBody.accept(visitor)
|
||||
visitor.afterVisitInitializer(this)
|
||||
}
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
append(modifierList)
|
||||
appendln(uastBody.asRenderString().withMargin)
|
||||
}
|
||||
override fun asRenderString() = buildString {
|
||||
append(modifierList)
|
||||
appendln(uastBody.asRenderString().withMargin)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitClassInitializer(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitClassInitializer(this, data)
|
||||
|
||||
override fun asLogString() = log("isStatic = $isStatic")
|
||||
override fun asLogString() = log("isStatic = $isStatic")
|
||||
}
|
||||
@@ -24,37 +24,37 @@ import org.jetbrains.uast.visitor.UastTypedVisitor
|
||||
* A [PsiElement] declaration wrapper.
|
||||
*/
|
||||
interface UDeclaration : UElement, PsiModifierListOwner, UAnnotated {
|
||||
/**
|
||||
* Returns the original declaration (which is *always* unwrapped, never a [UDeclaration]).
|
||||
*/
|
||||
override val psi: PsiModifierListOwner
|
||||
/**
|
||||
* Returns the original declaration (which is *always* unwrapped, never a [UDeclaration]).
|
||||
*/
|
||||
override val psi: PsiModifierListOwner
|
||||
|
||||
override fun getOriginalElement(): PsiElement? = psi.originalElement
|
||||
override fun getOriginalElement(): PsiElement? = psi.originalElement
|
||||
|
||||
/**
|
||||
* Returns the declaration name identifier, or null if the declaration is anonymous.
|
||||
*/
|
||||
val uastAnchor: UElement?
|
||||
/**
|
||||
* Returns the declaration name identifier, or null if the declaration is anonymous.
|
||||
*/
|
||||
val uastAnchor: UElement?
|
||||
|
||||
/**
|
||||
* Returns `true` if this declaration has a [PsiModifier.STATIC] modifier.
|
||||
*/
|
||||
val isStatic: Boolean
|
||||
get() = hasModifierProperty(PsiModifier.STATIC)
|
||||
/**
|
||||
* Returns `true` if this declaration has a [PsiModifier.STATIC] modifier.
|
||||
*/
|
||||
val isStatic: Boolean
|
||||
get() = hasModifierProperty(PsiModifier.STATIC)
|
||||
|
||||
/**
|
||||
* Returns `true` if this declaration has a [PsiModifier.FINAL] modifier.
|
||||
*/
|
||||
val isFinal: Boolean
|
||||
get() = hasModifierProperty(PsiModifier.FINAL)
|
||||
/**
|
||||
* Returns `true` if this declaration has a [PsiModifier.FINAL] modifier.
|
||||
*/
|
||||
val isFinal: Boolean
|
||||
get() = hasModifierProperty(PsiModifier.FINAL)
|
||||
|
||||
/**
|
||||
* Returns a declaration visibility.
|
||||
*/
|
||||
val visibility: UastVisibility
|
||||
get() = UastVisibility[this]
|
||||
/**
|
||||
* Returns a declaration visibility.
|
||||
*/
|
||||
val visibility: UastVisibility
|
||||
get() = UastVisibility[this]
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitDeclaration(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitDeclaration(this, data)
|
||||
}
|
||||
|
||||
fun UElement.getContainingDeclaration() = withContainingElements.filterIsInstance<UDeclaration>().firstOrNull()
|
||||
|
||||
@@ -25,74 +25,74 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a Uast file.
|
||||
*/
|
||||
interface UFile : UElement, UAnnotated {
|
||||
/**
|
||||
* Returns the original [PsiFile].
|
||||
*/
|
||||
override val psi: PsiFile
|
||||
/**
|
||||
* Returns the original [PsiFile].
|
||||
*/
|
||||
override val psi: PsiFile
|
||||
|
||||
/**
|
||||
* Returns the Java package name of this file.
|
||||
* Returns an empty [String] for the default package.
|
||||
*/
|
||||
val packageName: String
|
||||
/**
|
||||
* Returns the Java package name of this file.
|
||||
* Returns an empty [String] for the default package.
|
||||
*/
|
||||
val packageName: String
|
||||
|
||||
/**
|
||||
* Returns the import statements for this file.
|
||||
*/
|
||||
val imports: List<UImportStatement>
|
||||
/**
|
||||
* Returns the import statements for this file.
|
||||
*/
|
||||
val imports: List<UImportStatement>
|
||||
|
||||
/**
|
||||
* Returns the list of top-level classes declared in this file.
|
||||
*/
|
||||
val classes: List<UClass>
|
||||
/**
|
||||
* Returns the list of top-level classes declared in this file.
|
||||
*/
|
||||
val classes: List<UClass>
|
||||
|
||||
/**
|
||||
* Returns the plugin for a language used in this file.
|
||||
*/
|
||||
val languagePlugin: UastLanguagePlugin
|
||||
/**
|
||||
* Returns the plugin for a language used in this file.
|
||||
*/
|
||||
val languagePlugin: UastLanguagePlugin
|
||||
|
||||
/**
|
||||
* Returns all comments in file.
|
||||
*/
|
||||
val allCommentsInFile: List<UComment>
|
||||
/**
|
||||
* Returns all comments in file.
|
||||
*/
|
||||
val allCommentsInFile: List<UComment>
|
||||
|
||||
override fun asLogString() = log("package = $packageName")
|
||||
override fun asLogString() = log("package = $packageName")
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
if (annotations.isNotEmpty()) {
|
||||
annotations.joinTo(buffer = this, separator = "\n", postfix = "\n", transform = UAnnotation::asRenderString)
|
||||
}
|
||||
|
||||
val packageName = this@UFile.packageName
|
||||
if (packageName.isNotEmpty()) appendln("package $packageName").appendln()
|
||||
|
||||
val imports = this@UFile.imports
|
||||
if (imports.isNotEmpty()) {
|
||||
imports.forEach { appendln(it.asRenderString()) }
|
||||
appendln()
|
||||
}
|
||||
|
||||
classes.forEachIndexed { index, clazz ->
|
||||
if (index > 0) appendln()
|
||||
appendln(clazz.asRenderString())
|
||||
}
|
||||
override fun asRenderString() = buildString {
|
||||
if (annotations.isNotEmpty()) {
|
||||
annotations.joinTo(buffer = this, separator = "\n", postfix = "\n", transform = UAnnotation::asRenderString)
|
||||
}
|
||||
|
||||
/**
|
||||
* [UFile] is a top-level element of the Uast hierarchy, thus the [uastParent] always returns null for it.
|
||||
*/
|
||||
override val uastParent: UElement?
|
||||
get() = null
|
||||
val packageName = this@UFile.packageName
|
||||
if (packageName.isNotEmpty()) appendln("package $packageName").appendln()
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitFile(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
imports.acceptList(visitor)
|
||||
classes.acceptList(visitor)
|
||||
visitor.afterVisitFile(this)
|
||||
val imports = this@UFile.imports
|
||||
if (imports.isNotEmpty()) {
|
||||
imports.forEach { appendln(it.asRenderString()) }
|
||||
appendln()
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitFile(this, data)
|
||||
classes.forEachIndexed { index, clazz ->
|
||||
if (index > 0) appendln()
|
||||
appendln(clazz.asRenderString())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [UFile] is a top-level element of the Uast hierarchy, thus the [uastParent] always returns null for it.
|
||||
*/
|
||||
override val uastParent: UElement?
|
||||
get() = null
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitFile(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
imports.acceptList(visitor)
|
||||
classes.acceptList(visitor)
|
||||
visitor.afterVisitFile(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitFile(this, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,25 +23,25 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents an import statement.
|
||||
*/
|
||||
interface UImportStatement : UResolvable, UElement {
|
||||
/**
|
||||
* Returns true if the statement is an import-on-demand (star-import) statement.
|
||||
*/
|
||||
val isOnDemand: Boolean
|
||||
/**
|
||||
* Returns true if the statement is an import-on-demand (star-import) statement.
|
||||
*/
|
||||
val isOnDemand: Boolean
|
||||
|
||||
/**
|
||||
* Returns the reference to the imported element.
|
||||
*/
|
||||
val importReference: UElement?
|
||||
|
||||
override fun asLogString() = log("isOnDemand = $isOnDemand")
|
||||
/**
|
||||
* Returns the reference to the imported element.
|
||||
*/
|
||||
val importReference: UElement?
|
||||
|
||||
override fun asRenderString() = "import " + (importReference?.asRenderString() ?: "<error>")
|
||||
override fun asLogString() = log("isOnDemand = $isOnDemand")
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitImportStatement(this)) return
|
||||
visitor.afterVisitImportStatement(this)
|
||||
}
|
||||
override fun asRenderString() = "import " + (importReference?.asRenderString() ?: "<error>")
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitImportStatement(this, data)
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitImportStatement(this)) return
|
||||
visitor.afterVisitImportStatement(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitImportStatement(this, data)
|
||||
}
|
||||
@@ -26,83 +26,83 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* A method visitor to be used in [UastVisitor].
|
||||
*/
|
||||
interface UMethod : UDeclaration, PsiMethod {
|
||||
override val psi: PsiMethod
|
||||
override val psi: PsiMethod
|
||||
|
||||
/**
|
||||
* Returns the body expression (which can be also a [UBlockExpression]).
|
||||
*/
|
||||
val uastBody: UExpression?
|
||||
/**
|
||||
* Returns the body expression (which can be also a [UBlockExpression]).
|
||||
*/
|
||||
val uastBody: UExpression?
|
||||
|
||||
/**
|
||||
* Returns the method parameters.
|
||||
*/
|
||||
val uastParameters: List<UParameter>
|
||||
/**
|
||||
* Returns the method parameters.
|
||||
*/
|
||||
val uastParameters: List<UParameter>
|
||||
|
||||
/**
|
||||
* Returns true, if the method overrides a method of a super class.
|
||||
*/
|
||||
val isOverride: Boolean
|
||||
/**
|
||||
* Returns true, if the method overrides a method of a super class.
|
||||
*/
|
||||
val isOverride: Boolean
|
||||
|
||||
@Deprecated("Use uastBody instead.", ReplaceWith("uastBody"))
|
||||
override fun getBody() = psi.body
|
||||
@Deprecated("Use uastBody instead.", ReplaceWith("uastBody"))
|
||||
override fun getBody() = psi.body
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitMethod(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
uastParameters.acceptList(visitor)
|
||||
uastBody?.accept(visitor)
|
||||
visitor.afterVisitMethod(this)
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitMethod(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
uastParameters.acceptList(visitor)
|
||||
uastBody?.accept(visitor)
|
||||
visitor.afterVisitMethod(this)
|
||||
}
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
if (annotations.isNotEmpty()) {
|
||||
annotations.joinTo(buffer = this, separator = "\n", postfix = "\n", transform = UAnnotation::asRenderString)
|
||||
}
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
if (annotations.isNotEmpty()) {
|
||||
annotations.joinTo(buffer = this, separator = "\n", postfix = "\n", transform = UAnnotation::asRenderString)
|
||||
}
|
||||
append(psi.renderModifiers())
|
||||
append("fun ").append(name)
|
||||
|
||||
append(psi.renderModifiers())
|
||||
append("fun ").append(name)
|
||||
|
||||
uastParameters.joinTo(this, prefix = "(", postfix = ")") { parameter ->
|
||||
val annotationsText = if (parameter.annotations.isNotEmpty())
|
||||
parameter.annotations.joinToString(separator = " ", postfix = " ") { it.asRenderString() }
|
||||
else
|
||||
""
|
||||
annotationsText + parameter.name + ": " + parameter.type.canonicalText
|
||||
}
|
||||
|
||||
psi.returnType?.let { append(" : " + it.canonicalText) }
|
||||
|
||||
val body = uastBody
|
||||
append(when (body) {
|
||||
is UBlockExpression -> " " + body.asRenderString()
|
||||
else -> " = " + ((body ?: UastEmptyExpression).asRenderString())
|
||||
})
|
||||
uastParameters.joinTo(this, prefix = "(", postfix = ")") { parameter ->
|
||||
val annotationsText = if (parameter.annotations.isNotEmpty())
|
||||
parameter.annotations.joinToString(separator = " ", postfix = " ") { it.asRenderString() }
|
||||
else
|
||||
""
|
||||
annotationsText + parameter.name + ": " + parameter.type.canonicalText
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitMethod(this, data)
|
||||
psi.returnType?.let { append(" : " + it.canonicalText) }
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
val body = uastBody
|
||||
append(when (body) {
|
||||
is UBlockExpression -> " " + body.asRenderString()
|
||||
else -> " = " + ((body ?: UastEmptyExpression).asRenderString())
|
||||
})
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitMethod(this, data)
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
}
|
||||
|
||||
interface UAnnotationMethod : UMethod, PsiAnnotationMethod {
|
||||
override val psi: PsiAnnotationMethod
|
||||
override val psi: PsiAnnotationMethod
|
||||
|
||||
/**
|
||||
* Returns the default value of this annotation method.
|
||||
*/
|
||||
val uastDefaultValue: UExpression?
|
||||
/**
|
||||
* Returns the default value of this annotation method.
|
||||
*/
|
||||
val uastDefaultValue: UExpression?
|
||||
|
||||
override fun getDefaultValue() = psi.defaultValue
|
||||
override fun getDefaultValue() = psi.defaultValue
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitMethod(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
uastParameters.acceptList(visitor)
|
||||
uastBody?.accept(visitor)
|
||||
uastDefaultValue?.accept(visitor)
|
||||
visitor.afterVisitMethod(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitMethod(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
uastParameters.acceptList(visitor)
|
||||
uastBody?.accept(visitor)
|
||||
uastDefaultValue?.accept(visitor)
|
||||
visitor.afterVisitMethod(this)
|
||||
}
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
override fun asLogString() = log("name = $name")
|
||||
}
|
||||
@@ -25,123 +25,123 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* A variable wrapper to be used in [UastVisitor].
|
||||
*/
|
||||
interface UVariable : UDeclaration, PsiVariable {
|
||||
override val psi: PsiVariable
|
||||
override val psi: PsiVariable
|
||||
|
||||
/**
|
||||
* Returns the variable initializer or the parameter default value, or null if the variable has not an initializer.
|
||||
*/
|
||||
val uastInitializer: UExpression?
|
||||
/**
|
||||
* Returns the variable initializer or the parameter default value, or null if the variable has not an initializer.
|
||||
*/
|
||||
val uastInitializer: UExpression?
|
||||
|
||||
/**
|
||||
* Returns variable type reference.
|
||||
*/
|
||||
val typeReference: UTypeReferenceExpression?
|
||||
/**
|
||||
* Returns variable type reference.
|
||||
*/
|
||||
val typeReference: UTypeReferenceExpression?
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitVariable(this)) return
|
||||
visitContents(visitor)
|
||||
visitor.afterVisitVariable(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitVariable(this)) return
|
||||
visitContents(visitor)
|
||||
visitor.afterVisitVariable(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitVariable(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitVariable(this, data)
|
||||
|
||||
@Deprecated("Use uastInitializer instead.", ReplaceWith("uastInitializer"))
|
||||
override fun getInitializer() = psi.initializer
|
||||
@Deprecated("Use uastInitializer instead.", ReplaceWith("uastInitializer"))
|
||||
override fun getInitializer() = psi.initializer
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
override fun asLogString() = log("name = $name")
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
if (annotations.isNotEmpty()) {
|
||||
annotations.joinTo(this, separator = " ", postfix = " ") { it.asRenderString() }
|
||||
}
|
||||
append(psi.renderModifiers())
|
||||
append("var ").append(psi.name).append(": ").append(psi.type.getCanonicalText(false))
|
||||
uastInitializer?.let { initializer -> append(" = " + initializer.asRenderString()) }
|
||||
override fun asRenderString() = buildString {
|
||||
if (annotations.isNotEmpty()) {
|
||||
annotations.joinTo(this, separator = " ", postfix = " ") { it.asRenderString() }
|
||||
}
|
||||
append(psi.renderModifiers())
|
||||
append("var ").append(psi.name).append(": ").append(psi.type.getCanonicalText(false))
|
||||
uastInitializer?.let { initializer -> append(" = " + initializer.asRenderString()) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun UVariable.visitContents(visitor: UastVisitor) {
|
||||
annotations.acceptList(visitor)
|
||||
uastInitializer?.accept(visitor)
|
||||
annotations.acceptList(visitor)
|
||||
uastInitializer?.accept(visitor)
|
||||
}
|
||||
|
||||
interface UParameter : UVariable, PsiParameter {
|
||||
override val psi: PsiParameter
|
||||
override val psi: PsiParameter
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
override fun asLogString() = log("name = $name")
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitParameter(this)) return
|
||||
visitContents(visitor)
|
||||
visitor.afterVisitParameter(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitParameter(this)) return
|
||||
visitContents(visitor)
|
||||
visitor.afterVisitParameter(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitParameter(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitParameter(this, data)
|
||||
}
|
||||
|
||||
interface UField : UVariable, PsiField {
|
||||
override val psi: PsiField
|
||||
override val psi: PsiField
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
override fun asLogString() = log("name = $name")
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitField(this)) return
|
||||
visitContents(visitor)
|
||||
visitor.afterVisitField(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitField(this)) return
|
||||
visitContents(visitor)
|
||||
visitor.afterVisitField(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitField(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitField(this, data)
|
||||
}
|
||||
|
||||
interface ULocalVariable : UVariable, PsiLocalVariable {
|
||||
override val psi: PsiLocalVariable
|
||||
override val psi: PsiLocalVariable
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
override fun asLogString() = log("name = $name")
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitLocalVariable(this)) return
|
||||
visitContents(visitor)
|
||||
visitor.afterVisitLocalVariable(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitLocalVariable(this)) return
|
||||
visitContents(visitor)
|
||||
visitor.afterVisitLocalVariable(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitLocalVariable(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitLocalVariable(this, data)
|
||||
}
|
||||
|
||||
interface UEnumConstant : UField, UCallExpression, PsiEnumConstant {
|
||||
override val psi: PsiEnumConstant
|
||||
override val psi: PsiEnumConstant
|
||||
|
||||
val initializingClass: UClass?
|
||||
val initializingClass: UClass?
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
override fun asLogString() = log("name = $name")
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitEnumConstant(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
methodIdentifier?.accept(visitor)
|
||||
classReference?.accept(visitor)
|
||||
valueArguments.acceptList(visitor)
|
||||
initializingClass?.accept(visitor)
|
||||
visitor.afterVisitEnumConstant(this)
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitEnumConstant(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
methodIdentifier?.accept(visitor)
|
||||
classReference?.accept(visitor)
|
||||
valueArguments.acceptList(visitor)
|
||||
initializingClass?.accept(visitor)
|
||||
visitor.afterVisitEnumConstant(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitEnumConstantExpression(this, data)
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
if (annotations.isNotEmpty()) {
|
||||
annotations.joinTo(this, separator = " ", postfix = " ", transform = UAnnotation::asRenderString)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitEnumConstantExpression(this, data)
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
if (annotations.isNotEmpty()) {
|
||||
annotations.joinTo(this, separator = " ", postfix = " ", transform = UAnnotation::asRenderString)
|
||||
}
|
||||
append(name ?: "<ERROR>")
|
||||
if (valueArguments.isNotEmpty()) {
|
||||
valueArguments.joinTo(this, prefix = "(", postfix = ")", transform = UExpression::asRenderString)
|
||||
}
|
||||
initializingClass?.let {
|
||||
appendln(" {")
|
||||
it.uastDeclarations.forEach { declaration ->
|
||||
appendln(declaration.asRenderString().withMargin)
|
||||
}
|
||||
append("}")
|
||||
}
|
||||
append(name ?: "<ERROR>")
|
||||
if (valueArguments.isNotEmpty()) {
|
||||
valueArguments.joinTo(this, prefix = "(", postfix = ")", transform = UExpression::asRenderString)
|
||||
}
|
||||
initializingClass?.let {
|
||||
appendln(" {")
|
||||
it.uastDeclarations.forEach { declaration ->
|
||||
appendln(declaration.asRenderString().withMargin)
|
||||
}
|
||||
append("}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,91 +22,94 @@ import org.jetbrains.uast.values.UUndeterminedValue
|
||||
import org.jetbrains.uast.values.UValue
|
||||
|
||||
abstract class AbstractEvaluatorExtension(override val language: Language) : UEvaluatorExtension {
|
||||
override fun evaluatePostfix(
|
||||
operator: UastPostfixOperator,
|
||||
operandValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo = UUndeterminedValue to state
|
||||
override fun evaluatePostfix(
|
||||
operator: UastPostfixOperator,
|
||||
operandValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo = UUndeterminedValue to state
|
||||
|
||||
override fun evaluatePrefix(
|
||||
operator: UastPrefixOperator,
|
||||
operandValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo = UUndeterminedValue to state
|
||||
override fun evaluatePrefix(
|
||||
operator: UastPrefixOperator,
|
||||
operandValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo = UUndeterminedValue to state
|
||||
|
||||
override fun evaluateBinary(
|
||||
binaryExpression: UBinaryExpression,
|
||||
leftValue: UValue,
|
||||
rightValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo = UUndeterminedValue to state
|
||||
override fun evaluateBinary(
|
||||
binaryExpression: UBinaryExpression,
|
||||
leftValue: UValue,
|
||||
rightValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo = UUndeterminedValue to state
|
||||
|
||||
override fun evaluateQualified(
|
||||
accessType: UastQualifiedExpressionAccessType,
|
||||
receiverInfo: UEvaluationInfo,
|
||||
selectorInfo: UEvaluationInfo
|
||||
): UEvaluationInfo = UUndeterminedValue to selectorInfo.state
|
||||
override fun evaluateQualified(
|
||||
accessType: UastQualifiedExpressionAccessType,
|
||||
receiverInfo: UEvaluationInfo,
|
||||
selectorInfo: UEvaluationInfo
|
||||
): UEvaluationInfo = UUndeterminedValue to selectorInfo.state
|
||||
|
||||
override fun evaluateMethodCall(
|
||||
target: PsiMethod,
|
||||
argumentValues: List<UValue>,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo = UUndeterminedValue to state
|
||||
override fun evaluateMethodCall(
|
||||
target: PsiMethod,
|
||||
argumentValues: List<UValue>,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo = UUndeterminedValue to state
|
||||
|
||||
override fun evaluateVariable(
|
||||
variable: UVariable,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo = UUndeterminedValue to state
|
||||
override fun evaluateVariable(
|
||||
variable: UVariable,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo = UUndeterminedValue to state
|
||||
}
|
||||
|
||||
abstract class SimpleEvaluatorExtension : AbstractEvaluatorExtension(Language.ANY) {
|
||||
override final fun evaluatePostfix(operator: UastPostfixOperator, operandValue: UValue, state: UEvaluationState): UEvaluationInfo {
|
||||
val result = evaluatePostfix(operator, operandValue)
|
||||
return if (result != UUndeterminedValue)
|
||||
result.toConstant() to state
|
||||
else
|
||||
super.evaluatePostfix(operator, operandValue, state)
|
||||
}
|
||||
override final fun evaluatePostfix(operator: UastPostfixOperator, operandValue: UValue, state: UEvaluationState): UEvaluationInfo {
|
||||
val result = evaluatePostfix(operator, operandValue)
|
||||
return if (result != UUndeterminedValue)
|
||||
result.toConstant() to state
|
||||
else
|
||||
super.evaluatePostfix(operator, operandValue, state)
|
||||
}
|
||||
|
||||
open fun evaluatePostfix(operator: UastPostfixOperator, operandValue: UValue): Any? = UUndeterminedValue
|
||||
open fun evaluatePostfix(operator: UastPostfixOperator, operandValue: UValue): Any? = UUndeterminedValue
|
||||
|
||||
override final fun evaluatePrefix(operator: UastPrefixOperator, operandValue: UValue, state: UEvaluationState): UEvaluationInfo {
|
||||
val result = evaluatePrefix(operator, operandValue)
|
||||
return if (result != UUndeterminedValue)
|
||||
result.toConstant() to state
|
||||
else
|
||||
super.evaluatePrefix(operator, operandValue, state)
|
||||
}
|
||||
override final fun evaluatePrefix(operator: UastPrefixOperator, operandValue: UValue, state: UEvaluationState): UEvaluationInfo {
|
||||
val result = evaluatePrefix(operator, operandValue)
|
||||
return if (result != UUndeterminedValue)
|
||||
result.toConstant() to state
|
||||
else
|
||||
super.evaluatePrefix(operator, operandValue, state)
|
||||
}
|
||||
|
||||
open fun evaluatePrefix(operator: UastPrefixOperator, operandValue: UValue): Any? = UUndeterminedValue
|
||||
open fun evaluatePrefix(operator: UastPrefixOperator, operandValue: UValue): Any? = UUndeterminedValue
|
||||
|
||||
override final fun evaluateBinary(binaryExpression: UBinaryExpression, leftValue: UValue, rightValue: UValue, state: UEvaluationState): UEvaluationInfo {
|
||||
val result = evaluateBinary(binaryExpression, leftValue, rightValue)
|
||||
return if (result != UUndeterminedValue)
|
||||
result.toConstant() to state
|
||||
else
|
||||
super.evaluateBinary(binaryExpression, leftValue, rightValue, state)
|
||||
}
|
||||
override final fun evaluateBinary(binaryExpression: UBinaryExpression,
|
||||
leftValue: UValue,
|
||||
rightValue: UValue,
|
||||
state: UEvaluationState): UEvaluationInfo {
|
||||
val result = evaluateBinary(binaryExpression, leftValue, rightValue)
|
||||
return if (result != UUndeterminedValue)
|
||||
result.toConstant() to state
|
||||
else
|
||||
super.evaluateBinary(binaryExpression, leftValue, rightValue, state)
|
||||
}
|
||||
|
||||
open fun evaluateBinary(binaryExpression: UBinaryExpression, leftValue: UValue, rightValue: UValue): Any? = UUndeterminedValue
|
||||
open fun evaluateBinary(binaryExpression: UBinaryExpression, leftValue: UValue, rightValue: UValue): Any? = UUndeterminedValue
|
||||
|
||||
override final fun evaluateMethodCall(target: PsiMethod, argumentValues: List<UValue>, state: UEvaluationState): UEvaluationInfo {
|
||||
val result = evaluateMethodCall(target, argumentValues)
|
||||
return if (result != UUndeterminedValue)
|
||||
result.toConstant() to state
|
||||
else
|
||||
super.evaluateMethodCall(target, argumentValues, state)
|
||||
}
|
||||
override final fun evaluateMethodCall(target: PsiMethod, argumentValues: List<UValue>, state: UEvaluationState): UEvaluationInfo {
|
||||
val result = evaluateMethodCall(target, argumentValues)
|
||||
return if (result != UUndeterminedValue)
|
||||
result.toConstant() to state
|
||||
else
|
||||
super.evaluateMethodCall(target, argumentValues, state)
|
||||
}
|
||||
|
||||
open fun evaluateMethodCall(target: PsiMethod, argumentValues: List<UValue>): Any? = UUndeterminedValue
|
||||
open fun evaluateMethodCall(target: PsiMethod, argumentValues: List<UValue>): Any? = UUndeterminedValue
|
||||
|
||||
override final fun evaluateVariable(variable: UVariable, state: UEvaluationState): UEvaluationInfo {
|
||||
val result = evaluateVariable(variable)
|
||||
return if (result != UUndeterminedValue)
|
||||
result.toConstant() to state
|
||||
else
|
||||
super.evaluateVariable(variable, state)
|
||||
}
|
||||
override final fun evaluateVariable(variable: UVariable, state: UEvaluationState): UEvaluationInfo {
|
||||
val result = evaluateVariable(variable)
|
||||
return if (result != UUndeterminedValue)
|
||||
result.toConstant() to state
|
||||
else
|
||||
super.evaluateVariable(variable, state)
|
||||
}
|
||||
|
||||
open fun evaluateVariable(variable: UVariable): Any? = UUndeterminedValue
|
||||
open fun evaluateVariable(variable: UVariable): Any? = UUndeterminedValue
|
||||
}
|
||||
|
||||
@@ -23,75 +23,75 @@ import java.lang.ref.SoftReference
|
||||
import java.util.*
|
||||
|
||||
class MapBasedEvaluationContext(
|
||||
override val uastContext: UastContext,
|
||||
override val extensions: List<UEvaluatorExtension>
|
||||
override val uastContext: UastContext,
|
||||
override val extensions: List<UEvaluatorExtension>
|
||||
) : UEvaluationContext {
|
||||
|
||||
data class UEvaluatorWithStamp(val evaluator: UEvaluator, val stamp: Long)
|
||||
data class UEvaluatorWithStamp(val evaluator: UEvaluator, val stamp: Long)
|
||||
|
||||
private val evaluators = WeakHashMap<UDeclaration, SoftReference<UEvaluatorWithStamp>>()
|
||||
private val evaluators = WeakHashMap<UDeclaration, SoftReference<UEvaluatorWithStamp>>()
|
||||
|
||||
override fun analyzeAll(file: UFile, state: UEvaluationState): UEvaluationContext {
|
||||
file.accept(object: UastVisitor {
|
||||
override fun visitElement(node: UElement) = false
|
||||
override fun analyzeAll(file: UFile, state: UEvaluationState): UEvaluationContext {
|
||||
file.accept(object : UastVisitor {
|
||||
override fun visitElement(node: UElement) = false
|
||||
|
||||
override fun visitMethod(node: UMethod): Boolean {
|
||||
analyze(node, state)
|
||||
return true
|
||||
}
|
||||
override fun visitMethod(node: UMethod): Boolean {
|
||||
analyze(node, state)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun visitVariable(node: UVariable): Boolean {
|
||||
if (node is UField) {
|
||||
analyze(node, state)
|
||||
return true
|
||||
}
|
||||
else return false
|
||||
}
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
@Throws(ProcessCanceledException::class)
|
||||
private fun getOrCreateEvaluator(declaration: UDeclaration, state: UEvaluationState? = null): UEvaluator {
|
||||
val containingFile = declaration.getContainingUFile()
|
||||
val modificationStamp = containingFile?.psi?.modificationStamp ?: -1L
|
||||
val evaluatorWithStamp = evaluators[declaration]?.get()
|
||||
if (evaluatorWithStamp != null && evaluatorWithStamp.stamp == modificationStamp) {
|
||||
return evaluatorWithStamp.evaluator
|
||||
}
|
||||
return createEvaluator(uastContext, extensions).apply {
|
||||
when (declaration) {
|
||||
is UMethod -> this.analyze(declaration, state ?: declaration.createEmptyState())
|
||||
is UField -> this.analyze(declaration, state ?: declaration.createEmptyState())
|
||||
}
|
||||
evaluators[declaration] = SoftReference(UEvaluatorWithStamp(this, modificationStamp))
|
||||
override fun visitVariable(node: UVariable): Boolean {
|
||||
if (node is UField) {
|
||||
analyze(node, state)
|
||||
return true
|
||||
}
|
||||
else return false
|
||||
}
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
@Throws(ProcessCanceledException::class)
|
||||
private fun getOrCreateEvaluator(declaration: UDeclaration, state: UEvaluationState? = null): UEvaluator {
|
||||
val containingFile = declaration.getContainingUFile()
|
||||
val modificationStamp = containingFile?.psi?.modificationStamp ?: -1L
|
||||
val evaluatorWithStamp = evaluators[declaration]?.get()
|
||||
if (evaluatorWithStamp != null && evaluatorWithStamp.stamp == modificationStamp) {
|
||||
return evaluatorWithStamp.evaluator
|
||||
}
|
||||
|
||||
override fun analyze(declaration: UDeclaration, state: UEvaluationState) = getOrCreateEvaluator(declaration, state)
|
||||
|
||||
override fun getEvaluator(declaration: UDeclaration) = getOrCreateEvaluator(declaration)
|
||||
|
||||
private fun getEvaluator(expression: UExpression): UEvaluator? {
|
||||
var containingElement = expression.uastParent
|
||||
while (containingElement != null) {
|
||||
if (containingElement is UDeclaration) {
|
||||
val evaluator = evaluators[containingElement]?.get()?.evaluator
|
||||
if (evaluator != null) {
|
||||
return evaluator
|
||||
}
|
||||
}
|
||||
containingElement = containingElement.uastParent
|
||||
}
|
||||
return null
|
||||
return createEvaluator(uastContext, extensions).apply {
|
||||
when (declaration) {
|
||||
is UMethod -> this.analyze(declaration, state ?: declaration.createEmptyState())
|
||||
is UField -> this.analyze(declaration, state ?: declaration.createEmptyState())
|
||||
}
|
||||
evaluators[declaration] = SoftReference(UEvaluatorWithStamp(this, modificationStamp))
|
||||
}
|
||||
}
|
||||
|
||||
fun cachedValueOf(expression: UExpression) =
|
||||
(getEvaluator(expression) as? TreeBasedEvaluator)?.getCached(expression)
|
||||
override fun analyze(declaration: UDeclaration, state: UEvaluationState) = getOrCreateEvaluator(declaration, state)
|
||||
|
||||
override fun valueOf(expression: UExpression) =
|
||||
valueOfIfAny(expression) ?: UUndeterminedValue
|
||||
override fun getEvaluator(declaration: UDeclaration) = getOrCreateEvaluator(declaration)
|
||||
|
||||
override fun valueOfIfAny(expression: UExpression) =
|
||||
getEvaluator(expression)?.evaluate(expression)
|
||||
private fun getEvaluator(expression: UExpression): UEvaluator? {
|
||||
var containingElement = expression.uastParent
|
||||
while (containingElement != null) {
|
||||
if (containingElement is UDeclaration) {
|
||||
val evaluator = evaluators[containingElement]?.get()?.evaluator
|
||||
if (evaluator != null) {
|
||||
return evaluator
|
||||
}
|
||||
}
|
||||
containingElement = containingElement.uastParent
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun cachedValueOf(expression: UExpression) =
|
||||
(getEvaluator(expression) as? TreeBasedEvaluator)?.getCached(expression)
|
||||
|
||||
override fun valueOf(expression: UExpression) =
|
||||
valueOfIfAny(expression) ?: UUndeterminedValue
|
||||
|
||||
override fun valueOfIfAny(expression: UExpression) =
|
||||
getEvaluator(expression)?.evaluate(expression)
|
||||
}
|
||||
@@ -22,9 +22,9 @@ import org.jetbrains.uast.values.UValue
|
||||
import org.jetbrains.uast.values.UVariableValue
|
||||
|
||||
class MapBasedEvaluationState(
|
||||
// TODO: Use some immutable map?
|
||||
private val map: Map<UVariable, UValue>,
|
||||
override val boundElement: UElement? = null
|
||||
// TODO: Use some immutable map?
|
||||
private val map: Map<UVariable, UValue>,
|
||||
override val boundElement: UElement? = null
|
||||
) : UEvaluationState {
|
||||
override val variables: Set<UVariable>
|
||||
get() = map.keys
|
||||
@@ -39,24 +39,24 @@ class MapBasedEvaluationState(
|
||||
}
|
||||
else {
|
||||
MapBasedEvaluationState(
|
||||
previous = this,
|
||||
variable = variable,
|
||||
value = variableValue,
|
||||
boundElement = at
|
||||
previous = this,
|
||||
variable = variable,
|
||||
value = variableValue,
|
||||
boundElement = at
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun merge(otherState: UEvaluationState) =
|
||||
if (this == otherState) this else MapBasedEvaluationState(this, otherState)
|
||||
if (this == otherState) this else MapBasedEvaluationState(this, otherState)
|
||||
|
||||
constructor(boundElement: UElement) : this(mapOf(), boundElement)
|
||||
|
||||
constructor(previous: UEvaluationState, variable: UVariable, value: UValue, boundElement: UElement? = null) :
|
||||
this(delegatingMap(previous, variable, value), boundElement)
|
||||
this(delegatingMap(previous, variable, value), boundElement)
|
||||
|
||||
constructor(first: UEvaluationState, second: UEvaluationState) :
|
||||
this(mergingMap(first, second))
|
||||
this(mergingMap(first, second))
|
||||
|
||||
override fun equals(other: Any?) = other is MapBasedEvaluationState && map == other.map
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,51 +21,51 @@ import org.jetbrains.uast.values.UValue
|
||||
import java.lang.ref.SoftReference
|
||||
|
||||
interface UEvaluationContext {
|
||||
val uastContext: UastContext
|
||||
val uastContext: UastContext
|
||||
|
||||
val extensions: List<UEvaluatorExtension>
|
||||
val extensions: List<UEvaluatorExtension>
|
||||
|
||||
fun analyzeAll(file: UFile, state: UEvaluationState = file.createEmptyState()): UEvaluationContext
|
||||
fun analyzeAll(file: UFile, state: UEvaluationState = file.createEmptyState()): UEvaluationContext
|
||||
|
||||
fun analyze(declaration: UDeclaration, state: UEvaluationState = declaration.createEmptyState()): UEvaluator
|
||||
fun analyze(declaration: UDeclaration, state: UEvaluationState = declaration.createEmptyState()): UEvaluator
|
||||
|
||||
fun valueOf(expression: UExpression): UValue
|
||||
fun valueOf(expression: UExpression): UValue
|
||||
|
||||
fun valueOfIfAny(expression: UExpression): UValue?
|
||||
fun valueOfIfAny(expression: UExpression): UValue?
|
||||
|
||||
fun getEvaluator(declaration: UDeclaration): UEvaluator
|
||||
fun getEvaluator(declaration: UDeclaration): UEvaluator
|
||||
}
|
||||
|
||||
fun UFile.analyzeAll(context: UastContext = getUastContext(), extensions: List<UEvaluatorExtension> = emptyList()): UEvaluationContext =
|
||||
MapBasedEvaluationContext(context, extensions).analyzeAll(this)
|
||||
MapBasedEvaluationContext(context, extensions).analyzeAll(this)
|
||||
|
||||
@JvmOverloads
|
||||
fun UExpression?.uValueOf(extensions: List<UEvaluatorExtension> = emptyList()): UValue? {
|
||||
if (this == null) return null
|
||||
val declaration = getContainingAnalyzableDeclaration() ?: return null
|
||||
val context = declaration.getEvaluationContextWithCaching(extensions)
|
||||
context.analyze(declaration)
|
||||
return context.valueOf(this)
|
||||
if (this == null) return null
|
||||
val declaration = getContainingAnalyzableDeclaration() ?: return null
|
||||
val context = declaration.getEvaluationContextWithCaching(extensions)
|
||||
context.analyze(declaration)
|
||||
return context.valueOf(this)
|
||||
}
|
||||
|
||||
fun UExpression?.uValueOf(vararg extensions: UEvaluatorExtension): UValue? = uValueOf(extensions.asList())
|
||||
|
||||
private fun UElement.getContainingAnalyzableDeclaration() = withContainingElements.filterIsInstance<UDeclaration>().firstOrNull {
|
||||
it is UMethod ||
|
||||
it is UField // TODO: think about field analysis (should we use class as analyzable declaration)
|
||||
it is UMethod ||
|
||||
it is UField // TODO: think about field analysis (should we use class as analyzable declaration)
|
||||
}
|
||||
|
||||
fun UDeclaration.getEvaluationContextWithCaching(extensions: List<UEvaluatorExtension> = emptyList()): UEvaluationContext {
|
||||
return containingFile?.let { file ->
|
||||
val cachedContext = file.getUserData(EVALUATION_CONTEXT_KEY)?.get()
|
||||
if (cachedContext != null && cachedContext.extensions == extensions)
|
||||
cachedContext
|
||||
else
|
||||
MapBasedEvaluationContext(getUastContext(), extensions).apply {
|
||||
file.putUserData(EVALUATION_CONTEXT_KEY, SoftReference(this))
|
||||
}
|
||||
return containingFile?.let { file ->
|
||||
val cachedContext = file.getUserData(EVALUATION_CONTEXT_KEY)?.get()
|
||||
if (cachedContext != null && cachedContext.extensions == extensions)
|
||||
cachedContext
|
||||
else
|
||||
MapBasedEvaluationContext(getUastContext(), extensions).apply {
|
||||
file.putUserData(EVALUATION_CONTEXT_KEY, SoftReference(this))
|
||||
}
|
||||
|
||||
} ?: MapBasedEvaluationContext(getUastContext(), extensions)
|
||||
} ?: MapBasedEvaluationContext(getUastContext(), extensions)
|
||||
}
|
||||
|
||||
val EVALUATION_CONTEXT_KEY = Key<SoftReference<out UEvaluationContext>>("uast.EvaluationContext")
|
||||
|
||||
@@ -18,18 +18,18 @@ package org.jetbrains.uast.evaluation
|
||||
import org.jetbrains.uast.values.UValue
|
||||
|
||||
data class UEvaluationInfo(val value: UValue, val state: UEvaluationState) {
|
||||
fun merge(otherInfo: UEvaluationInfo): UEvaluationInfo {
|
||||
// info with 'UNothingValue' is just ignored, if other is not UNothingValue
|
||||
if (!reachable && otherInfo.reachable) return otherInfo
|
||||
if (!otherInfo.reachable && reachable) return this
|
||||
// Regular merge
|
||||
val mergedValue = value.merge(otherInfo.value)
|
||||
val mergedState = state.merge(otherInfo.state)
|
||||
return UEvaluationInfo(mergedValue, mergedState)
|
||||
}
|
||||
fun merge(otherInfo: UEvaluationInfo): UEvaluationInfo {
|
||||
// info with 'UNothingValue' is just ignored, if other is not UNothingValue
|
||||
if (!reachable && otherInfo.reachable) return otherInfo
|
||||
if (!otherInfo.reachable && reachable) return this
|
||||
// Regular merge
|
||||
val mergedValue = value.merge(otherInfo.value)
|
||||
val mergedState = state.merge(otherInfo.state)
|
||||
return UEvaluationInfo(mergedValue, mergedState)
|
||||
}
|
||||
|
||||
fun copy(value: UValue) = if (value != this.value) UEvaluationInfo(value, state) else this
|
||||
fun copy(value: UValue) = if (value != this.value) UEvaluationInfo(value, state) else this
|
||||
|
||||
val reachable: Boolean
|
||||
get() = value.reachable
|
||||
val reachable: Boolean
|
||||
get() = value.reachable
|
||||
}
|
||||
@@ -22,17 +22,17 @@ import org.jetbrains.uast.values.UValue
|
||||
// Role: stores current values for all variables (and may be something else)
|
||||
// Immutable
|
||||
interface UEvaluationState {
|
||||
val boundElement: UElement?
|
||||
val boundElement: UElement?
|
||||
|
||||
val variables: Set<UVariable>
|
||||
val variables: Set<UVariable>
|
||||
|
||||
operator fun get(variable: UVariable): UValue
|
||||
operator fun get(variable: UVariable): UValue
|
||||
|
||||
// Creates new evaluation state with state[variable] = value and boundElement = at
|
||||
fun assign(variable: UVariable, value: UValue, at: UElement): UEvaluationState
|
||||
// Creates new evaluation state with state[variable] = value and boundElement = at
|
||||
fun assign(variable: UVariable, value: UValue, at: UElement): UEvaluationState
|
||||
|
||||
// Merged two states
|
||||
fun merge(otherState: UEvaluationState): UEvaluationState
|
||||
// Merged two states
|
||||
fun merge(otherState: UEvaluationState): UEvaluationState
|
||||
}
|
||||
|
||||
fun UElement.createEmptyState(): UEvaluationState = MapBasedEvaluationState(this)
|
||||
@@ -24,27 +24,27 @@ import org.jetbrains.uast.values.UValue
|
||||
// Role: at the current state, evaluate expression(s)
|
||||
interface UEvaluator {
|
||||
|
||||
val context: UastContext
|
||||
val context: UastContext
|
||||
|
||||
val languageExtensions: List<UEvaluatorExtension>
|
||||
get() {
|
||||
val rootArea = Extensions.getRootArea()
|
||||
if (!rootArea.hasExtensionPoint(UEvaluatorExtension.EXTENSION_POINT_NAME.name)) return listOf()
|
||||
return rootArea.getExtensionPoint(UEvaluatorExtension.EXTENSION_POINT_NAME).extensions.toList()
|
||||
}
|
||||
val languageExtensions: List<UEvaluatorExtension>
|
||||
get() {
|
||||
val rootArea = Extensions.getRootArea()
|
||||
if (!rootArea.hasExtensionPoint(UEvaluatorExtension.EXTENSION_POINT_NAME.name)) return listOf()
|
||||
return rootArea.getExtensionPoint(UEvaluatorExtension.EXTENSION_POINT_NAME).extensions.toList()
|
||||
}
|
||||
|
||||
fun PsiElement.languageExtension() = languageExtensions.firstOrNull { it.language == language }
|
||||
fun PsiElement.languageExtension() = languageExtensions.firstOrNull { it.language == language }
|
||||
|
||||
fun UElement.languageExtension() = psi?.languageExtension()
|
||||
fun UElement.languageExtension() = psi?.languageExtension()
|
||||
|
||||
fun analyze(method: UMethod, state: UEvaluationState = method.createEmptyState())
|
||||
fun analyze(method: UMethod, state: UEvaluationState = method.createEmptyState())
|
||||
|
||||
fun analyze(field: UField, state: UEvaluationState = field.createEmptyState())
|
||||
fun analyze(field: UField, state: UEvaluationState = field.createEmptyState())
|
||||
|
||||
fun evaluate(expression: UExpression, state: UEvaluationState? = null): UValue
|
||||
fun evaluate(expression: UExpression, state: UEvaluationState? = null): UValue
|
||||
|
||||
fun getDependents(dependency: UDependency): Set<UValue>
|
||||
fun getDependents(dependency: UDependency): Set<UValue>
|
||||
}
|
||||
|
||||
fun createEvaluator(context: UastContext, extensions: List<UEvaluatorExtension>): UEvaluator =
|
||||
TreeBasedEvaluator(context, extensions)
|
||||
TreeBasedEvaluator(context, extensions)
|
||||
|
||||
@@ -23,48 +23,48 @@ import org.jetbrains.uast.values.UValue
|
||||
|
||||
interface UEvaluatorExtension {
|
||||
|
||||
companion object {
|
||||
val EXTENSION_POINT_NAME: ExtensionPointName<UEvaluatorExtension> =
|
||||
ExtensionPointName.create<UEvaluatorExtension>("org.jetbrains.uast.evaluation.UEvaluatorExtension")
|
||||
}
|
||||
companion object {
|
||||
val EXTENSION_POINT_NAME: ExtensionPointName<UEvaluatorExtension> =
|
||||
ExtensionPointName.create<UEvaluatorExtension>("org.jetbrains.uast.evaluation.UEvaluatorExtension")
|
||||
}
|
||||
|
||||
infix fun UValue.to(state: UEvaluationState) = UEvaluationInfo(this, state)
|
||||
infix fun UValue.to(state: UEvaluationState) = UEvaluationInfo(this, state)
|
||||
|
||||
val language: Language
|
||||
val language: Language
|
||||
|
||||
fun evaluatePostfix(
|
||||
operator: UastPostfixOperator,
|
||||
operandValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo
|
||||
fun evaluatePostfix(
|
||||
operator: UastPostfixOperator,
|
||||
operandValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo
|
||||
|
||||
fun evaluatePrefix(
|
||||
operator: UastPrefixOperator,
|
||||
operandValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo
|
||||
fun evaluatePrefix(
|
||||
operator: UastPrefixOperator,
|
||||
operandValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo
|
||||
|
||||
fun evaluateBinary(
|
||||
binaryExpression: UBinaryExpression,
|
||||
leftValue: UValue,
|
||||
rightValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo
|
||||
fun evaluateBinary(
|
||||
binaryExpression: UBinaryExpression,
|
||||
leftValue: UValue,
|
||||
rightValue: UValue,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo
|
||||
|
||||
fun evaluateQualified(
|
||||
accessType: UastQualifiedExpressionAccessType,
|
||||
receiverInfo: UEvaluationInfo,
|
||||
selectorInfo: UEvaluationInfo
|
||||
): UEvaluationInfo
|
||||
fun evaluateQualified(
|
||||
accessType: UastQualifiedExpressionAccessType,
|
||||
receiverInfo: UEvaluationInfo,
|
||||
selectorInfo: UEvaluationInfo
|
||||
): UEvaluationInfo
|
||||
|
||||
fun evaluateMethodCall(
|
||||
target: PsiMethod,
|
||||
argumentValues: List<UValue>,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo
|
||||
fun evaluateMethodCall(
|
||||
target: PsiMethod,
|
||||
argumentValues: List<UValue>,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo
|
||||
|
||||
fun evaluateVariable(
|
||||
variable: UVariable,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo
|
||||
fun evaluateVariable(
|
||||
variable: UVariable,
|
||||
state: UEvaluationState
|
||||
): UEvaluationInfo
|
||||
}
|
||||
@@ -24,29 +24,29 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents `receiver[index0, ..., indexN]` expression.
|
||||
*/
|
||||
interface UArrayAccessExpression : UExpression {
|
||||
/**
|
||||
* Returns the receiver expression.
|
||||
*/
|
||||
val receiver: UExpression
|
||||
/**
|
||||
* Returns the receiver expression.
|
||||
*/
|
||||
val receiver: UExpression
|
||||
|
||||
/**
|
||||
* Returns the list of index expressions.
|
||||
*/
|
||||
val indices: List<UExpression>
|
||||
/**
|
||||
* Returns the list of index expressions.
|
||||
*/
|
||||
val indices: List<UExpression>
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitArrayAccessExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
receiver.accept(visitor)
|
||||
indices.acceptList(visitor)
|
||||
visitor.afterVisitArrayAccessExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitArrayAccessExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
receiver.accept(visitor)
|
||||
indices.acceptList(visitor)
|
||||
visitor.afterVisitArrayAccessExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitArrayAccessExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitArrayAccessExpression(this, data)
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun asRenderString() = receiver.asRenderString() +
|
||||
indices.joinToString(prefix = "[", postfix = "]") { it.asRenderString() }
|
||||
override fun asRenderString() = receiver.asRenderString() +
|
||||
indices.joinToString(prefix = "[", postfix = "]") { it.asRenderString() }
|
||||
}
|
||||
@@ -25,41 +25,41 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a binary expression (value1 op value2), eg. `2 + "A"`.
|
||||
*/
|
||||
interface UBinaryExpression : UPolyadicExpression {
|
||||
/**
|
||||
* Returns the left operand.
|
||||
*/
|
||||
val leftOperand: UExpression
|
||||
/**
|
||||
* Returns the left operand.
|
||||
*/
|
||||
val leftOperand: UExpression
|
||||
|
||||
/**
|
||||
* Returns the right operand.
|
||||
*/
|
||||
val rightOperand: UExpression
|
||||
/**
|
||||
* Returns the right operand.
|
||||
*/
|
||||
val rightOperand: UExpression
|
||||
|
||||
/**
|
||||
* Returns the operator identifier.
|
||||
*/
|
||||
val operatorIdentifier: UIdentifier?
|
||||
/**
|
||||
* Returns the operator identifier.
|
||||
*/
|
||||
val operatorIdentifier: UIdentifier?
|
||||
|
||||
/**
|
||||
* Resolve the operator method.
|
||||
*
|
||||
* @return the resolved method, or null if the method can't be resolved, or if the expression is not a method call.
|
||||
*/
|
||||
fun resolveOperator(): PsiMethod?
|
||||
/**
|
||||
* Resolve the operator method.
|
||||
*
|
||||
* @return the resolved method, or null if the method can't be resolved, or if the expression is not a method call.
|
||||
*/
|
||||
fun resolveOperator(): PsiMethod?
|
||||
|
||||
override val operands: List<UExpression>
|
||||
get() = listOf(leftOperand, rightOperand)
|
||||
override val operands: List<UExpression>
|
||||
get() = listOf(leftOperand, rightOperand)
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitBinaryExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
leftOperand.accept(visitor)
|
||||
rightOperand.accept(visitor)
|
||||
visitor.afterVisitBinaryExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitBinaryExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
leftOperand.accept(visitor)
|
||||
rightOperand.accept(visitor)
|
||||
visitor.afterVisitBinaryExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitBinaryExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitBinaryExpression(this, data)
|
||||
|
||||
override fun asLogString() = log("operator = $operator")
|
||||
override fun asLogString() = log("operator = $operator")
|
||||
}
|
||||
@@ -26,38 +26,38 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a binary expression with type (value op type), e.g. ("A" instanceof String).
|
||||
*/
|
||||
interface UBinaryExpressionWithType : UExpression {
|
||||
/**
|
||||
* Returns the operand expression.
|
||||
*/
|
||||
val operand: UExpression
|
||||
/**
|
||||
* Returns the operand expression.
|
||||
*/
|
||||
val operand: UExpression
|
||||
|
||||
/**
|
||||
* Returns the operation kind.
|
||||
*/
|
||||
val operationKind: UastBinaryExpressionWithTypeKind
|
||||
/**
|
||||
* Returns the operation kind.
|
||||
*/
|
||||
val operationKind: UastBinaryExpressionWithTypeKind
|
||||
|
||||
/**
|
||||
* Returns the type reference of this expression.
|
||||
*/
|
||||
val typeReference: UTypeReferenceExpression?
|
||||
/**
|
||||
* Returns the type reference of this expression.
|
||||
*/
|
||||
val typeReference: UTypeReferenceExpression?
|
||||
|
||||
/**
|
||||
* Returns the type.
|
||||
*/
|
||||
val type: PsiType
|
||||
/**
|
||||
* Returns the type.
|
||||
*/
|
||||
val type: PsiType
|
||||
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun asRenderString() = "${operand.asRenderString()} ${operationKind.name} ${type.name}"
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitBinaryExpressionWithType(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
operand.accept(visitor)
|
||||
typeReference?.accept(visitor)
|
||||
visitor.afterVisitBinaryExpressionWithType(this)
|
||||
}
|
||||
override fun asRenderString() = "${operand.asRenderString()} ${operationKind.name} ${type.name}"
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitBinaryExpressionWithType(this, data)
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitBinaryExpressionWithType(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
operand.accept(visitor)
|
||||
typeReference?.accept(visitor)
|
||||
visitor.afterVisitBinaryExpressionWithType(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitBinaryExpressionWithType(this, data)
|
||||
}
|
||||
@@ -24,26 +24,26 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents the code block expression: `{ /* code */ }`.
|
||||
*/
|
||||
interface UBlockExpression : UExpression {
|
||||
/**
|
||||
* Returns the list of block expressions.
|
||||
*/
|
||||
val expressions: List<UExpression>
|
||||
/**
|
||||
* Returns the list of block expressions.
|
||||
*/
|
||||
val expressions: List<UExpression>
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitBlockExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expressions.acceptList(visitor)
|
||||
visitor.afterVisitBlockExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitBlockExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expressions.acceptList(visitor)
|
||||
visitor.afterVisitBlockExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitBlockExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitBlockExpression(this, data)
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
appendln("{")
|
||||
expressions.forEach { appendln(it.asRenderString().withMargin) }
|
||||
append("}")
|
||||
}
|
||||
override fun asRenderString() = buildString {
|
||||
appendln("{")
|
||||
expressions.forEach { appendln(it.asRenderString().withMargin) }
|
||||
append("}")
|
||||
}
|
||||
}
|
||||
@@ -26,16 +26,16 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
*/
|
||||
interface UBreakExpression : UJumpExpression {
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitBreakExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitBreakExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitBreakExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitBreakExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitBreakExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitBreakExpression(this, data)
|
||||
|
||||
override fun asLogString() = log("label = $label")
|
||||
override fun asLogString() = log("label = $label")
|
||||
|
||||
override fun asRenderString() = label?.let { "break@$it" } ?: "break"
|
||||
override fun asRenderString() = label?.let { "break@$it" } ?: "break"
|
||||
}
|
||||
@@ -27,90 +27,90 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a call expression (method/constructor call, array initializer).
|
||||
*/
|
||||
interface UCallExpression : UExpression, UResolvable {
|
||||
/**
|
||||
* Returns the call kind.
|
||||
*/
|
||||
val kind: UastCallKind
|
||||
/**
|
||||
* Returns the call kind.
|
||||
*/
|
||||
val kind: UastCallKind
|
||||
|
||||
/**
|
||||
* Returns the called method name, or null if the call is not a method call.
|
||||
* This property should return the actual resolved function name.
|
||||
*/
|
||||
val methodName: String?
|
||||
/**
|
||||
* Returns the called method name, or null if the call is not a method call.
|
||||
* This property should return the actual resolved function name.
|
||||
*/
|
||||
val methodName: String?
|
||||
|
||||
/**
|
||||
* Returns the expression receiver.
|
||||
* For example, for call `a.b.[c()]` the receiver is `a.b`.
|
||||
*/
|
||||
val receiver: UExpression?
|
||||
/**
|
||||
* Returns the expression receiver.
|
||||
* For example, for call `a.b.[c()]` the receiver is `a.b`.
|
||||
*/
|
||||
val receiver: UExpression?
|
||||
|
||||
/**
|
||||
* Returns the receiver type, or null if the call has not a receiver.
|
||||
*/
|
||||
val receiverType: PsiType?
|
||||
/**
|
||||
* Returns the receiver type, or null if the call has not a receiver.
|
||||
*/
|
||||
val receiverType: PsiType?
|
||||
|
||||
/**
|
||||
* Returns the function reference expression if the call is a non-constructor method call, null otherwise.
|
||||
*/
|
||||
val methodIdentifier: UIdentifier?
|
||||
/**
|
||||
* Returns the function reference expression if the call is a non-constructor method call, null otherwise.
|
||||
*/
|
||||
val methodIdentifier: UIdentifier?
|
||||
|
||||
/**
|
||||
* Returns the class reference if the call is a constructor call, null otherwise.
|
||||
*/
|
||||
val classReference: UReferenceExpression?
|
||||
/**
|
||||
* Returns the class reference if the call is a constructor call, null otherwise.
|
||||
*/
|
||||
val classReference: UReferenceExpression?
|
||||
|
||||
/**
|
||||
* Returns the value argument count.
|
||||
*
|
||||
* Retrieving the argument count could be faster than getting the [valueArguments.size],
|
||||
* because there is no need to create actual [UExpression] instances.
|
||||
*/
|
||||
val valueArgumentCount: Int
|
||||
/**
|
||||
* Returns the value argument count.
|
||||
*
|
||||
* Retrieving the argument count could be faster than getting the [valueArguments.size],
|
||||
* because there is no need to create actual [UExpression] instances.
|
||||
*/
|
||||
val valueArgumentCount: Int
|
||||
|
||||
/**
|
||||
* Returns the list of value arguments.
|
||||
*/
|
||||
val valueArguments: List<UExpression>
|
||||
/**
|
||||
* Returns the list of value arguments.
|
||||
*/
|
||||
val valueArguments: List<UExpression>
|
||||
|
||||
/**
|
||||
* Returns the type argument count.
|
||||
*/
|
||||
val typeArgumentCount: Int
|
||||
/**
|
||||
* Returns the type argument count.
|
||||
*/
|
||||
val typeArgumentCount: Int
|
||||
|
||||
/**
|
||||
* Returns the type arguments for the call.
|
||||
*/
|
||||
val typeArguments: List<PsiType>
|
||||
/**
|
||||
* Returns the type arguments for the call.
|
||||
*/
|
||||
val typeArguments: List<PsiType>
|
||||
|
||||
/**
|
||||
* Returns the return type of the called function, or null if the call is not a function call.
|
||||
*/
|
||||
val returnType: PsiType?
|
||||
/**
|
||||
* Returns the return type of the called function, or null if the call is not a function call.
|
||||
*/
|
||||
val returnType: PsiType?
|
||||
|
||||
/**
|
||||
* Resolve the called method.
|
||||
*
|
||||
* @return the [PsiMethod], or null if the method was not resolved.
|
||||
* Note that the [PsiMethod] is an unwrapped [PsiMethod], not a [UMethod].
|
||||
*/
|
||||
override fun resolve(): PsiMethod?
|
||||
/**
|
||||
* Resolve the called method.
|
||||
*
|
||||
* @return the [PsiMethod], or null if the method was not resolved.
|
||||
* Note that the [PsiMethod] is an unwrapped [PsiMethod], not a [UMethod].
|
||||
*/
|
||||
override fun resolve(): PsiMethod?
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitCallExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
methodIdentifier?.accept(visitor)
|
||||
classReference?.accept(visitor)
|
||||
valueArguments.acceptList(visitor)
|
||||
visitor.afterVisitCallExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitCallExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
methodIdentifier?.accept(visitor)
|
||||
classReference?.accept(visitor)
|
||||
valueArguments.acceptList(visitor)
|
||||
visitor.afterVisitCallExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitCallExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitCallExpression(this, data)
|
||||
|
||||
override fun asLogString() = log("kind = $kind, argCount = $valueArgumentCount)")
|
||||
override fun asLogString() = log("kind = $kind, argCount = $valueArgumentCount)")
|
||||
|
||||
override fun asRenderString(): String {
|
||||
val ref = classReference?.asRenderString() ?: methodName ?: methodIdentifier?.asRenderString() ?: "<noref>"
|
||||
return ref + "(" + valueArguments.joinToString { it.asRenderString() } + ")"
|
||||
}
|
||||
override fun asRenderString(): String {
|
||||
val ref = classReference?.asRenderString() ?: methodName ?: methodIdentifier?.asRenderString() ?: "<noref>"
|
||||
return ref + "(" + valueArguments.joinToString { it.asRenderString() } + ")"
|
||||
}
|
||||
}
|
||||
+31
-31
@@ -26,42 +26,42 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a callable reference expression, e.g. `Clazz::methodName`.
|
||||
*/
|
||||
interface UCallableReferenceExpression : UReferenceExpression {
|
||||
/**
|
||||
* Returns the qualifier expression.
|
||||
* Can be null if the [qualifierType] is known.
|
||||
*/
|
||||
val qualifierExpression: UExpression?
|
||||
/**
|
||||
* Returns the qualifier expression.
|
||||
* Can be null if the [qualifierType] is known.
|
||||
*/
|
||||
val qualifierExpression: UExpression?
|
||||
|
||||
/**
|
||||
* Returns the qualifier type.
|
||||
* Can be null if the qualifier is an expression.
|
||||
*/
|
||||
val qualifierType: PsiType?
|
||||
/**
|
||||
* Returns the qualifier type.
|
||||
* Can be null if the qualifier is an expression.
|
||||
*/
|
||||
val qualifierType: PsiType?
|
||||
|
||||
/**
|
||||
* Returns the callable name.
|
||||
*/
|
||||
val callableName: String
|
||||
/**
|
||||
* Returns the callable name.
|
||||
*/
|
||||
val callableName: String
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitCallableReferenceExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
qualifierExpression?.accept(visitor)
|
||||
visitor.afterVisitCallableReferenceExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitCallableReferenceExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
qualifierExpression?.accept(visitor)
|
||||
visitor.afterVisitCallableReferenceExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitCallableReferenceExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitCallableReferenceExpression(this, data)
|
||||
|
||||
override fun asLogString() = log("name = $callableName")
|
||||
override fun asLogString() = log("name = $callableName")
|
||||
|
||||
override fun asRenderString() = buildString {
|
||||
qualifierExpression?.let {
|
||||
append(it.asRenderString())
|
||||
} ?: qualifierType?.let {
|
||||
append(it.name)
|
||||
}
|
||||
append("::")
|
||||
append(callableName)
|
||||
override fun asRenderString() = buildString {
|
||||
qualifierExpression?.let {
|
||||
append(it.asRenderString())
|
||||
} ?: qualifierType?.let {
|
||||
append(it.name)
|
||||
}
|
||||
append("::")
|
||||
append(callableName)
|
||||
}
|
||||
}
|
||||
@@ -26,28 +26,28 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents the class literal expression, e.g. `Clazz.class`.
|
||||
*/
|
||||
interface UClassLiteralExpression : UExpression {
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun asRenderString() = (type?.name) ?: "(${expression?.asRenderString() ?: "<no expression>"})" + "::class"
|
||||
override fun asRenderString() = (type?.name) ?: "(${expression?.asRenderString() ?: "<no expression>"})" + "::class"
|
||||
|
||||
/**
|
||||
* Returns the type referenced by this class literal, or null if the type can't be determined in a compile-time.
|
||||
*/
|
||||
val type: PsiType?
|
||||
/**
|
||||
* Returns the type referenced by this class literal, or null if the type can't be determined in a compile-time.
|
||||
*/
|
||||
val type: PsiType?
|
||||
|
||||
/**
|
||||
* Returns an expression for this class literal expression.
|
||||
* Might be null if the [type] is specified.
|
||||
*/
|
||||
val expression: UExpression?
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitClassLiteralExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expression?.accept(visitor)
|
||||
visitor.afterVisitClassLiteralExpression(this)
|
||||
}
|
||||
/**
|
||||
* Returns an expression for this class literal expression.
|
||||
* Might be null if the [type] is specified.
|
||||
*/
|
||||
val expression: UExpression?
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitClassLiteralExpression(this, data)
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitClassLiteralExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expression?.accept(visitor)
|
||||
visitor.afterVisitClassLiteralExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitClassLiteralExpression(this, data)
|
||||
}
|
||||
@@ -26,16 +26,16 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
*/
|
||||
interface UContinueExpression : UJumpExpression {
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitContinueExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitContinueExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitContinueExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitContinueExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitContinueExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitContinueExpression(this, data)
|
||||
|
||||
override fun asLogString() = log("label = $label")
|
||||
override fun asLogString() = log("label = $label")
|
||||
|
||||
override fun asRenderString() = label?.let { "continue@$it" } ?: "continue"
|
||||
override fun asRenderString() = label?.let { "continue@$it" } ?: "continue"
|
||||
}
|
||||
@@ -25,22 +25,22 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Example in Java: `int a = 4, b = 3`.
|
||||
*/
|
||||
interface UDeclarationsExpression : UExpression {
|
||||
/**
|
||||
* Returns the list of declarations inside this [UDeclarationsExpression].
|
||||
*/
|
||||
val declarations: List<UDeclaration>
|
||||
/**
|
||||
* Returns the list of declarations inside this [UDeclarationsExpression].
|
||||
*/
|
||||
val declarations: List<UDeclaration>
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitDeclarationsExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
declarations.acceptList(visitor)
|
||||
visitor.afterVisitDeclarationsExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitDeclarationsExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
declarations.acceptList(visitor)
|
||||
visitor.afterVisitDeclarationsExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitDeclarationsExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitDeclarationsExpression(this, data)
|
||||
|
||||
override fun asRenderString() = declarations.joinToString(LINE_SEPARATOR) { it.asRenderString() }
|
||||
override fun asRenderString() = declarations.joinToString(LINE_SEPARATOR) { it.asRenderString() }
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
}
|
||||
@@ -24,29 +24,29 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a generic list of expressions.
|
||||
*/
|
||||
interface UExpressionList : UExpression {
|
||||
/**
|
||||
* Returns the list of expressions.
|
||||
*/
|
||||
val expressions: List<UExpression>
|
||||
/**
|
||||
* Returns the list of expressions.
|
||||
*/
|
||||
val expressions: List<UExpression>
|
||||
|
||||
/**
|
||||
* Returns the list kind.
|
||||
*/
|
||||
val kind: UastSpecialExpressionKind
|
||||
/**
|
||||
* Returns the list kind.
|
||||
*/
|
||||
val kind: UastSpecialExpressionKind
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitExpressionList(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expressions.acceptList(visitor)
|
||||
visitor.afterVisitExpressionList(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitExpressionList(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expressions.acceptList(visitor)
|
||||
visitor.afterVisitExpressionList(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitExpressionList(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitExpressionList(this, data)
|
||||
|
||||
fun firstOrNull(): UExpression? = expressions.firstOrNull()
|
||||
fun firstOrNull(): UExpression? = expressions.firstOrNull()
|
||||
|
||||
override fun asLogString() = log(kind.name)
|
||||
override fun asLogString() = log(kind.name)
|
||||
|
||||
override fun asRenderString() = kind.name + " " + expressions.joinToString(" : ") { it.asRenderString() }
|
||||
override fun asRenderString() = kind.name + " " + expressions.joinToString(" : ") { it.asRenderString() }
|
||||
}
|
||||
@@ -19,8 +19,8 @@ package org.jetbrains.uast
|
||||
* Represents jump expression (break / continue) with label
|
||||
*/
|
||||
interface UJumpExpression : UExpression {
|
||||
/**
|
||||
* Returns the expression label, or null if the label is not specified.
|
||||
*/
|
||||
val label: String?
|
||||
/**
|
||||
* Returns the expression label, or null if the label is not specified.
|
||||
*/
|
||||
val label: String?
|
||||
}
|
||||
|
||||
@@ -24,29 +24,29 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents an expression with the label specified.
|
||||
*/
|
||||
interface ULabeledExpression : UExpression, ULabeled {
|
||||
/**
|
||||
* Returns the expression label.
|
||||
*/
|
||||
override val label: String
|
||||
/**
|
||||
* Returns the expression label.
|
||||
*/
|
||||
override val label: String
|
||||
|
||||
/**
|
||||
* Returns the expression itself.
|
||||
*/
|
||||
val expression: UExpression
|
||||
/**
|
||||
* Returns the expression itself.
|
||||
*/
|
||||
val expression: UExpression
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitLabeledExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expression.accept(visitor)
|
||||
visitor.afterVisitLabeledExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitLabeledExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expression.accept(visitor)
|
||||
visitor.afterVisitLabeledExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitLabeledExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitLabeledExpression(this, data)
|
||||
|
||||
override fun evaluate() = expression.evaluate()
|
||||
override fun evaluate() = expression.evaluate()
|
||||
|
||||
override fun asLogString() = log("label = $label")
|
||||
override fun asLogString() = log("label = $label")
|
||||
|
||||
override fun asRenderString() = "$label@ ${expression.asRenderString()}"
|
||||
override fun asRenderString() = "$label@ ${expression.asRenderString()}"
|
||||
}
|
||||
@@ -25,40 +25,40 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents the lambda expression.
|
||||
*/
|
||||
interface ULambdaExpression : UExpression {
|
||||
/**
|
||||
* Returns the list of lambda value parameters.
|
||||
*/
|
||||
val valueParameters: List<UParameter>
|
||||
/**
|
||||
* Returns the list of lambda value parameters.
|
||||
*/
|
||||
val valueParameters: List<UParameter>
|
||||
|
||||
/**
|
||||
* Returns the lambda body expression.
|
||||
*/
|
||||
val body: UExpression
|
||||
/**
|
||||
* Returns the lambda body expression.
|
||||
*/
|
||||
val body: UExpression
|
||||
|
||||
/**
|
||||
* Returns SAM type the lambda expression corresponds to or null when no SAM type could be found
|
||||
*/
|
||||
val functionalInterfaceType: PsiType?
|
||||
/**
|
||||
* Returns SAM type the lambda expression corresponds to or null when no SAM type could be found
|
||||
*/
|
||||
val functionalInterfaceType: PsiType?
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitLambdaExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
valueParameters.acceptList(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitLambdaExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitLambdaExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
valueParameters.acceptList(visitor)
|
||||
body.accept(visitor)
|
||||
visitor.afterVisitLambdaExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitLambdaExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitLambdaExpression(this, data)
|
||||
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun asRenderString(): String {
|
||||
val renderedValueParameters = if (valueParameters.isEmpty())
|
||||
""
|
||||
else
|
||||
valueParameters.joinToString { it.asRenderString() } + " ->" + LINE_SEPARATOR
|
||||
override fun asLogString() = log()
|
||||
|
||||
return "{ " + renderedValueParameters + body.asRenderString().withMargin + LINE_SEPARATOR + "}"
|
||||
}
|
||||
override fun asRenderString(): String {
|
||||
val renderedValueParameters = if (valueParameters.isEmpty())
|
||||
""
|
||||
else
|
||||
valueParameters.joinToString { it.asRenderString() } + " ->" + LINE_SEPARATOR
|
||||
|
||||
return "{ " + renderedValueParameters + body.asRenderString().withMargin + LINE_SEPARATOR + "}"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,51 +24,51 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a literal expression.
|
||||
*/
|
||||
interface ULiteralExpression : UExpression {
|
||||
/**
|
||||
* Returns the literal expression value.
|
||||
* This is basically a String, Number or null if the literal is a `null` literal.
|
||||
*/
|
||||
val value: Any?
|
||||
/**
|
||||
* Returns the literal expression value.
|
||||
* This is basically a String, Number or null if the literal is a `null` literal.
|
||||
*/
|
||||
val value: Any?
|
||||
|
||||
/**
|
||||
* Returns true if the literal is a `null`-literal, false otherwise.
|
||||
*/
|
||||
val isNull: Boolean
|
||||
get() = value == null
|
||||
/**
|
||||
* Returns true if the literal is a `null`-literal, false otherwise.
|
||||
*/
|
||||
val isNull: Boolean
|
||||
get() = value == null
|
||||
|
||||
/**
|
||||
* Returns true if the literal is a [String] literal, false otherwise.
|
||||
*/
|
||||
val isString: Boolean
|
||||
get() = evaluate() is String
|
||||
/**
|
||||
* Returns true if the literal is a [String] literal, false otherwise.
|
||||
*/
|
||||
val isString: Boolean
|
||||
get() = evaluate() is String
|
||||
|
||||
/**
|
||||
* Returns true if the literal is a [Boolean] literal, false otherwise.
|
||||
*/
|
||||
val isBoolean: Boolean
|
||||
get() = evaluate() is Boolean
|
||||
/**
|
||||
* Returns true if the literal is a [Boolean] literal, false otherwise.
|
||||
*/
|
||||
val isBoolean: Boolean
|
||||
get() = evaluate() is Boolean
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitLiteralExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitLiteralExpression(this)
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitLiteralExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitLiteralExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitLiteralExpression(this, data)
|
||||
|
||||
override fun asRenderString(): String {
|
||||
val value = value
|
||||
return when (value) {
|
||||
null -> "null"
|
||||
is Char -> "'$value'"
|
||||
is String -> '"' + value.replace("\\", "\\\\")
|
||||
.replace("\r", "\\r").replace("\n", "\\n")
|
||||
.replace("\t", "\\t").replace("\b", "\\b")
|
||||
.replace("\"", "\\\"") + '"'
|
||||
else -> value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitLiteralExpression(this, data)
|
||||
|
||||
override fun asRenderString(): String {
|
||||
val value = value
|
||||
return when (value) {
|
||||
null -> "null"
|
||||
is Char -> "'$value'"
|
||||
is String -> '"' + value.replace("\\", "\\\\")
|
||||
.replace("\r", "\\r").replace("\n", "\\n")
|
||||
.replace("\t", "\\t").replace("\b", "\\b")
|
||||
.replace("\"", "\\\"") + '"'
|
||||
else -> value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
override fun asLogString() = log("value = ${asRenderString()}")
|
||||
override fun asLogString() = log("value = ${asRenderString()}")
|
||||
}
|
||||
|
||||
@@ -19,20 +19,20 @@ import org.jetbrains.uast.internal.acceptList
|
||||
import org.jetbrains.uast.internal.log
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
interface UNamedExpression: UExpression {
|
||||
val name: String?
|
||||
val expression: UExpression
|
||||
interface UNamedExpression : UExpression {
|
||||
val name: String?
|
||||
val expression: UExpression
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitElement(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expression.accept(visitor)
|
||||
visitor.afterVisitElement(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitElement(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expression.accept(visitor)
|
||||
visitor.afterVisitElement(this)
|
||||
}
|
||||
|
||||
override fun asLogString() = log("name = $name")
|
||||
override fun asLogString() = log("name = $name")
|
||||
|
||||
override fun asRenderString() = name + " = " + expression.asRenderString()
|
||||
override fun asRenderString() = name + " = " + expression.asRenderString()
|
||||
|
||||
override fun evaluate() = expression.evaluate()
|
||||
override fun evaluate() = expression.evaluate()
|
||||
}
|
||||
|
||||
@@ -25,42 +25,42 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents an object literal expression, e.g. `new Runnable() {}` in Java.
|
||||
*/
|
||||
interface UObjectLiteralExpression : UCallExpression {
|
||||
/**
|
||||
* Returns the class declaration.
|
||||
*/
|
||||
val declaration: UClass
|
||||
/**
|
||||
* Returns the class declaration.
|
||||
*/
|
||||
val declaration: UClass
|
||||
|
||||
override val methodIdentifier: UIdentifier?
|
||||
get() = null
|
||||
|
||||
override val kind: UastCallKind
|
||||
get() = UastCallKind.CONSTRUCTOR_CALL
|
||||
override val methodIdentifier: UIdentifier?
|
||||
get() = null
|
||||
|
||||
override val methodName: String?
|
||||
get() = null
|
||||
override val kind: UastCallKind
|
||||
get() = UastCallKind.CONSTRUCTOR_CALL
|
||||
|
||||
override val receiver: UExpression?
|
||||
get() = null
|
||||
|
||||
override val receiverType: PsiType?
|
||||
get() = null
|
||||
override val methodName: String?
|
||||
get() = null
|
||||
|
||||
override val returnType: PsiType?
|
||||
get() = null
|
||||
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitObjectLiteralExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
valueArguments.acceptList(visitor)
|
||||
declaration.accept(visitor)
|
||||
visitor.afterVisitObjectLiteralExpression(this)
|
||||
}
|
||||
override val receiver: UExpression?
|
||||
get() = null
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitObjectLiteralExpression(this, data)
|
||||
override val receiverType: PsiType?
|
||||
get() = null
|
||||
|
||||
override fun asLogString() = log()
|
||||
override val returnType: PsiType?
|
||||
get() = null
|
||||
|
||||
override fun asRenderString() = "anonymous " + declaration.text
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitObjectLiteralExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
valueArguments.acceptList(visitor)
|
||||
declaration.accept(visitor)
|
||||
visitor.afterVisitObjectLiteralExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitObjectLiteralExpression(this, data)
|
||||
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun asRenderString() = "anonymous " + declaration.text
|
||||
}
|
||||
@@ -24,24 +24,24 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a parenthesized expression, e.g. `(23 + 3)`.
|
||||
*/
|
||||
interface UParenthesizedExpression : UExpression {
|
||||
/**
|
||||
* Returns an expression inside the parenthesis.
|
||||
*/
|
||||
val expression: UExpression
|
||||
/**
|
||||
* Returns an expression inside the parenthesis.
|
||||
*/
|
||||
val expression: UExpression
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitParenthesizedExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expression.accept(visitor)
|
||||
visitor.afterVisitParenthesizedExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitParenthesizedExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
expression.accept(visitor)
|
||||
visitor.afterVisitParenthesizedExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitParenthesizedExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitParenthesizedExpression(this, data)
|
||||
|
||||
override fun evaluate() = expression.evaluate()
|
||||
override fun evaluate() = expression.evaluate()
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun asRenderString() = '(' + expression.asRenderString() + ')'
|
||||
override fun asRenderString() = '(' + expression.asRenderString() + ')'
|
||||
}
|
||||
@@ -26,28 +26,28 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
*/
|
||||
interface UPolyadicExpression : UExpression {
|
||||
|
||||
/**
|
||||
* Returns a list of expression operands.
|
||||
*/
|
||||
val operands: List<UExpression>
|
||||
/**
|
||||
* Returns a list of expression operands.
|
||||
*/
|
||||
val operands: List<UExpression>
|
||||
|
||||
/**
|
||||
* Returns the operator.
|
||||
*/
|
||||
val operator: UastBinaryOperator
|
||||
/**
|
||||
* Returns the operator.
|
||||
*/
|
||||
val operator: UastBinaryOperator
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitPolyadicExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
operands.acceptList(visitor)
|
||||
visitor.afterVisitPolyadicExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitPolyadicExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
operands.acceptList(visitor)
|
||||
visitor.afterVisitPolyadicExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitPolyadicExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitPolyadicExpression(this, data)
|
||||
|
||||
override fun asLogString() = log("operator = $operator")
|
||||
override fun asLogString() = log("operator = $operator")
|
||||
|
||||
override fun asRenderString() =
|
||||
operands.joinToString(separator = " ${operator.text} ", transform = UExpression::asRenderString)
|
||||
override fun asRenderString() =
|
||||
operands.joinToString(separator = " ${operator.text} ", transform = UExpression::asRenderString)
|
||||
}
|
||||
+23
-23
@@ -24,33 +24,33 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents the qualified expression (receiver.selector).
|
||||
*/
|
||||
interface UQualifiedReferenceExpression : UReferenceExpression {
|
||||
/**
|
||||
* Returns the expression receiver.
|
||||
*/
|
||||
val receiver: UExpression
|
||||
/**
|
||||
* Returns the expression receiver.
|
||||
*/
|
||||
val receiver: UExpression
|
||||
|
||||
/**
|
||||
* Returns the expression selector.
|
||||
*/
|
||||
val selector: UExpression
|
||||
/**
|
||||
* Returns the expression selector.
|
||||
*/
|
||||
val selector: UExpression
|
||||
|
||||
/**
|
||||
* Returns the access type (simple, safe access, etc.).
|
||||
*/
|
||||
val accessType: UastQualifiedExpressionAccessType
|
||||
/**
|
||||
* Returns the access type (simple, safe access, etc.).
|
||||
*/
|
||||
val accessType: UastQualifiedExpressionAccessType
|
||||
|
||||
override fun asRenderString() = receiver.asRenderString() + accessType.name + selector.asRenderString()
|
||||
override fun asRenderString() = receiver.asRenderString() + accessType.name + selector.asRenderString()
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitQualifiedReferenceExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
receiver.accept(visitor)
|
||||
selector.accept(visitor)
|
||||
visitor.afterVisitQualifiedReferenceExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitQualifiedReferenceExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
receiver.accept(visitor)
|
||||
selector.accept(visitor)
|
||||
visitor.afterVisitQualifiedReferenceExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitQualifiedReferenceExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitQualifiedReferenceExpression(this, data)
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
}
|
||||
@@ -20,12 +20,12 @@ import org.jetbrains.uast.internal.log
|
||||
import org.jetbrains.uast.visitor.UastTypedVisitor
|
||||
|
||||
interface UReferenceExpression : UExpression, UResolvable {
|
||||
/**
|
||||
* Returns the resolved name for this reference, or null if the reference can't be resolved.
|
||||
*/
|
||||
val resolvedName: String?
|
||||
/**
|
||||
* Returns the resolved name for this reference, or null if the reference can't be resolved.
|
||||
*/
|
||||
val resolvedName: String?
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitReferenceExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) = visitor.visitReferenceExpression(this, data)
|
||||
}
|
||||
@@ -25,22 +25,22 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a `return` expression.
|
||||
*/
|
||||
interface UReturnExpression : UExpression {
|
||||
/**
|
||||
* Returns the `return` value.
|
||||
*/
|
||||
val returnExpression: UExpression?
|
||||
/**
|
||||
* Returns the `return` value.
|
||||
*/
|
||||
val returnExpression: UExpression?
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitReturnExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
returnExpression?.accept(visitor)
|
||||
visitor.afterVisitReturnExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitReturnExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
returnExpression?.accept(visitor)
|
||||
visitor.afterVisitReturnExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitReturnExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitReturnExpression(this, data)
|
||||
|
||||
override fun asRenderString() = returnExpression.let { if (it == null) "return" else "return " + it.asRenderString() }
|
||||
override fun asRenderString() = returnExpression.let { if (it == null) "return" else "return " + it.asRenderString() }
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
}
|
||||
+14
-14
@@ -24,21 +24,21 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a simple reference expression (a non-qualified identifier).
|
||||
*/
|
||||
interface USimpleNameReferenceExpression : UReferenceExpression {
|
||||
/**
|
||||
* Returns the identifier name.
|
||||
*/
|
||||
val identifier: String
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitSimpleNameReferenceExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitSimpleNameReferenceExpression(this)
|
||||
}
|
||||
/**
|
||||
* Returns the identifier name.
|
||||
*/
|
||||
val identifier: String
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitSimpleNameReferenceExpression(this, data)
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitSimpleNameReferenceExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitSimpleNameReferenceExpression(this)
|
||||
}
|
||||
|
||||
override fun asLogString() = log("identifier = $identifier")
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitSimpleNameReferenceExpression(this, data)
|
||||
|
||||
override fun asRenderString() = identifier
|
||||
override fun asLogString() = log("identifier = $identifier")
|
||||
|
||||
override fun asRenderString() = identifier
|
||||
}
|
||||
@@ -25,16 +25,16 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Qualified `super` is not supported at the moment.
|
||||
*/
|
||||
interface USuperExpression : UInstanceExpression {
|
||||
override fun asLogString() = log("label = $label")
|
||||
override fun asLogString() = log("label = $label")
|
||||
|
||||
override fun asRenderString() = "super"
|
||||
override fun asRenderString() = "super"
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitSuperExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitSuperExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitSuperExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitSuperExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitSuperExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitSuperExpression(this, data)
|
||||
}
|
||||
@@ -25,16 +25,16 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Qualified `this` is not supported at the moment.
|
||||
*/
|
||||
interface UThisExpression : UInstanceExpression {
|
||||
override fun asLogString() = log("label = $label")
|
||||
override fun asLogString() = log("label = $label")
|
||||
|
||||
override fun asRenderString() = "this"
|
||||
override fun asRenderString() = "this"
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitThisExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitThisExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitThisExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitThisExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitThisExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitThisExpression(this, data)
|
||||
}
|
||||
@@ -25,22 +25,22 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* Represents a `throw` expression.
|
||||
*/
|
||||
interface UThrowExpression : UExpression {
|
||||
/**
|
||||
* Returns ths thrown expression.
|
||||
*/
|
||||
val thrownExpression: UExpression
|
||||
/**
|
||||
* Returns ths thrown expression.
|
||||
*/
|
||||
val thrownExpression: UExpression
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitThrowExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
thrownExpression.accept(visitor)
|
||||
visitor.afterVisitThrowExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitThrowExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
thrownExpression.accept(visitor)
|
||||
visitor.afterVisitThrowExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitThrowExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitThrowExpression(this, data)
|
||||
|
||||
override fun asRenderString() = "throw " + thrownExpression.asRenderString()
|
||||
override fun asRenderString() = "throw " + thrownExpression.asRenderString()
|
||||
|
||||
override fun asLogString() = log()
|
||||
override fun asLogString() = log()
|
||||
}
|
||||
@@ -23,26 +23,26 @@ import org.jetbrains.uast.visitor.UastTypedVisitor
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
interface UTypeReferenceExpression : UExpression {
|
||||
/**
|
||||
* Returns the resolved type for this reference.
|
||||
*/
|
||||
val type: PsiType
|
||||
/**
|
||||
* Returns the resolved type for this reference.
|
||||
*/
|
||||
val type: PsiType
|
||||
|
||||
/**
|
||||
* Returns the qualified name of the class type, or null if the [type] is not a class type.
|
||||
*/
|
||||
fun getQualifiedName() = PsiTypesUtil.getPsiClass(type)?.qualifiedName
|
||||
/**
|
||||
* Returns the qualified name of the class type, or null if the [type] is not a class type.
|
||||
*/
|
||||
fun getQualifiedName() = PsiTypesUtil.getPsiClass(type)?.qualifiedName
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitTypeReferenceExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitTypeReferenceExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitTypeReferenceExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitTypeReferenceExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitTypeReferenceExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitTypeReferenceExpression(this, data)
|
||||
|
||||
override fun asLogString() = log("name = ${type.name}")
|
||||
override fun asLogString() = log("name = ${type.name}")
|
||||
|
||||
override fun asRenderString(): String = type.name
|
||||
override fun asRenderString(): String = type.name
|
||||
}
|
||||
@@ -22,71 +22,71 @@ import org.jetbrains.uast.visitor.UastTypedVisitor
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
interface UUnaryExpression : UExpression {
|
||||
/**
|
||||
* Returns the expression operand.
|
||||
*/
|
||||
val operand: UExpression
|
||||
/**
|
||||
* Returns the expression operand.
|
||||
*/
|
||||
val operand: UExpression
|
||||
|
||||
/**
|
||||
* Returns the expression operator.
|
||||
*/
|
||||
val operator: UastOperator
|
||||
/**
|
||||
* Returns the expression operator.
|
||||
*/
|
||||
val operator: UastOperator
|
||||
|
||||
/**
|
||||
* Returns the operator identifier.
|
||||
*/
|
||||
val operatorIdentifier: UIdentifier?
|
||||
/**
|
||||
* Returns the operator identifier.
|
||||
*/
|
||||
val operatorIdentifier: UIdentifier?
|
||||
|
||||
/**
|
||||
* Resolve the operator method.
|
||||
*
|
||||
* @return the resolved method, or null if the method can't be resolved, or if the expression is not a method call.
|
||||
*/
|
||||
fun resolveOperator(): PsiMethod?
|
||||
/**
|
||||
* Resolve the operator method.
|
||||
*
|
||||
* @return the resolved method, or null if the method can't be resolved, or if the expression is not a method call.
|
||||
*/
|
||||
fun resolveOperator(): PsiMethod?
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitUnaryExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
operand.accept(visitor)
|
||||
visitor.afterVisitUnaryExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitUnaryExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
operand.accept(visitor)
|
||||
visitor.afterVisitUnaryExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitUnaryExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitUnaryExpression(this, data)
|
||||
}
|
||||
|
||||
interface UPrefixExpression : UUnaryExpression {
|
||||
override val operator: UastPrefixOperator
|
||||
override val operator: UastPrefixOperator
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitPrefixExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
operand.accept(visitor)
|
||||
visitor.afterVisitPrefixExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitPrefixExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
operand.accept(visitor)
|
||||
visitor.afterVisitPrefixExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitPrefixExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitPrefixExpression(this, data)
|
||||
|
||||
override fun asLogString() = log("operator = $operator")
|
||||
override fun asLogString() = log("operator = $operator")
|
||||
|
||||
override fun asRenderString() = operator.text + operand.asRenderString()
|
||||
override fun asRenderString() = operator.text + operand.asRenderString()
|
||||
}
|
||||
|
||||
interface UPostfixExpression : UUnaryExpression {
|
||||
override val operator: UastPostfixOperator
|
||||
override val operator: UastPostfixOperator
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitPostfixExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
operand.accept(visitor)
|
||||
visitor.afterVisitPostfixExpression(this)
|
||||
}
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitPostfixExpression(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
operand.accept(visitor)
|
||||
visitor.afterVisitPostfixExpression(this)
|
||||
}
|
||||
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitPostfixExpression(this, data)
|
||||
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D) =
|
||||
visitor.visitPostfixExpression(this, data)
|
||||
|
||||
override fun asLogString() = log("operator = $operator")
|
||||
override fun asLogString() = log("operator = $operator")
|
||||
|
||||
override fun asRenderString() = operand.asRenderString() + operator.text
|
||||
override fun asRenderString() = operand.asRenderString() + operator.text
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:JvmName("UastLiteralUtils")
|
||||
|
||||
package org.jetbrains.uast
|
||||
|
||||
import com.intellij.psi.PsiLanguageInjectionHost
|
||||
@@ -60,7 +61,7 @@ fun UElement.isStringLiteral(): Boolean = this is ULiteralExpression && this.isS
|
||||
* @return literal text if the receiver is a valid [String] literal, null otherwise.
|
||||
*/
|
||||
fun UElement.getValueIfStringLiteral(): String? =
|
||||
if (isStringLiteral()) (this as ULiteralExpression).value as String else null
|
||||
if (isStringLiteral()) (this as ULiteralExpression).value as String else null
|
||||
|
||||
/**
|
||||
* Checks if the [UElement] is a [Number] literal (Integer, Long, Float, Double, etc.).
|
||||
@@ -75,12 +76,12 @@ fun UElement.isNumberLiteral(): Boolean = this is ULiteralExpression && this.val
|
||||
* @return true if the receiver is an integral literal, false otherwise.
|
||||
*/
|
||||
fun UElement.isIntegralLiteral(): Boolean = this is ULiteralExpression && when (value) {
|
||||
is Int -> true
|
||||
is Long -> true
|
||||
is Short -> true
|
||||
is Char -> true
|
||||
is Byte -> true
|
||||
else -> false
|
||||
is Int -> true
|
||||
is Long -> true
|
||||
is Short -> true
|
||||
is Char -> true
|
||||
is Byte -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,18 +91,18 @@ fun UElement.isIntegralLiteral(): Boolean = this is ULiteralExpression && when (
|
||||
* 0 if the receiver literal expression is not a integral one.
|
||||
*/
|
||||
fun ULiteralExpression.getLongValue(): Long = value.let {
|
||||
when (it) {
|
||||
is Long -> it
|
||||
is Int -> it.toLong()
|
||||
is Short -> it.toLong()
|
||||
is Char -> it.toLong()
|
||||
is Byte -> it.toLong()
|
||||
else -> 0
|
||||
}
|
||||
when (it) {
|
||||
is Long -> it
|
||||
is Int -> it.toLong()
|
||||
is Short -> it.toLong()
|
||||
is Char -> it.toLong()
|
||||
is Byte -> it.toLong()
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return corresponding [PsiLanguageInjectionHost] for this literal expression if it exists.
|
||||
*/
|
||||
val ULiteralExpression.psiLanguageInjectionHost
|
||||
get() = this.psi?.let { PsiTreeUtil.getParentOfType(it, PsiLanguageInjectionHost::class.java, false) }
|
||||
get() = this.psi?.let { PsiTreeUtil.getParentOfType(it, PsiLanguageInjectionHost::class.java, false) }
|
||||
@@ -19,13 +19,13 @@ import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
fun List<UElement>.acceptList(visitor: UastVisitor) {
|
||||
for (element in this) {
|
||||
element.accept(visitor)
|
||||
}
|
||||
for (element in this) {
|
||||
element.accept(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
inline fun <reified T : UElement> T.log(text: String = ""): String {
|
||||
val className = T::class.java.simpleName
|
||||
return if (text.isEmpty()) className else "$className ($text)"
|
||||
val className = T::class.java.simpleName
|
||||
return if (text.isEmpty()) className else "$className ($text)"
|
||||
}
|
||||
@@ -22,24 +22,24 @@ import com.intellij.psi.PsiType
|
||||
internal val LINE_SEPARATOR = System.getProperty("line.separator") ?: "\n"
|
||||
|
||||
val String.withMargin: String
|
||||
get() = lines().joinToString(LINE_SEPARATOR) { " " + it }
|
||||
get() = lines().joinToString(LINE_SEPARATOR) { " " + it }
|
||||
|
||||
internal operator fun String.times(n: Int) = this.repeat(n)
|
||||
|
||||
internal fun List<UElement>.asLogString() = joinToString(LINE_SEPARATOR) { it.asLogString().withMargin }
|
||||
|
||||
internal tailrec fun UExpression.unwrapParenthesis(): UExpression = when (this) {
|
||||
is UParenthesizedExpression -> expression.unwrapParenthesis()
|
||||
else -> this
|
||||
is UParenthesizedExpression -> expression.unwrapParenthesis()
|
||||
else -> this
|
||||
}
|
||||
|
||||
internal fun <T> lz(f: () -> T) = lazy(LazyThreadSafetyMode.NONE, f)
|
||||
|
||||
internal val PsiType.name: String
|
||||
get() = getCanonicalText(false)
|
||||
get() = getCanonicalText(false)
|
||||
|
||||
|
||||
internal fun PsiModifierListOwner.renderModifiers(): String {
|
||||
val modifiers = PsiModifier.MODIFIERS.filter { hasModifierProperty(it) }.joinToString(" ")
|
||||
return if (modifiers.isEmpty()) "" else modifiers + " "
|
||||
val modifiers = PsiModifier.MODIFIERS.filter { hasModifierProperty(it) }.joinToString(" ")
|
||||
return if (modifiers.isEmpty()) "" else modifiers + " "
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:JvmName("UastBinaryExpressionWithTypeUtils")
|
||||
|
||||
package org.jetbrains.uast
|
||||
|
||||
/**
|
||||
@@ -21,17 +22,17 @@ package org.jetbrains.uast
|
||||
* Examples: type casts, instance checks.
|
||||
*/
|
||||
open class UastBinaryExpressionWithTypeKind(val name: String) {
|
||||
open class TypeCast(name: String) : UastBinaryExpressionWithTypeKind(name)
|
||||
open class InstanceCheck(name: String) : UastBinaryExpressionWithTypeKind(name)
|
||||
open class TypeCast(name: String) : UastBinaryExpressionWithTypeKind(name)
|
||||
open class InstanceCheck(name: String) : UastBinaryExpressionWithTypeKind(name)
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val TYPE_CAST = TypeCast("as")
|
||||
companion object {
|
||||
@JvmField
|
||||
val TYPE_CAST = TypeCast("as")
|
||||
|
||||
@JvmField
|
||||
val INSTANCE_CHECK = InstanceCheck("is")
|
||||
@JvmField
|
||||
val INSTANCE_CHECK = InstanceCheck("is")
|
||||
|
||||
@JvmField
|
||||
val UNKNOWN = UastBinaryExpressionWithTypeKind("<unknown>")
|
||||
}
|
||||
@JvmField
|
||||
val UNKNOWN = UastBinaryExpressionWithTypeKind("<unknown>")
|
||||
}
|
||||
}
|
||||
@@ -18,116 +18,116 @@ package org.jetbrains.uast
|
||||
/**
|
||||
* Kinds of operators in [UBinaryExpression].
|
||||
*/
|
||||
open class UastBinaryOperator(override val text: String): UastOperator {
|
||||
class LogicalOperator(text: String): UastBinaryOperator(text)
|
||||
class ComparisonOperator(text: String): UastBinaryOperator(text)
|
||||
class ArithmeticOperator(text: String): UastBinaryOperator(text)
|
||||
class BitwiseOperator(text: String): UastBinaryOperator(text)
|
||||
class AssignOperator(text: String): UastBinaryOperator(text)
|
||||
open class UastBinaryOperator(override val text: String) : UastOperator {
|
||||
class LogicalOperator(text: String) : UastBinaryOperator(text)
|
||||
class ComparisonOperator(text: String) : UastBinaryOperator(text)
|
||||
class ArithmeticOperator(text: String) : UastBinaryOperator(text)
|
||||
class BitwiseOperator(text: String) : UastBinaryOperator(text)
|
||||
class AssignOperator(text: String) : UastBinaryOperator(text)
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val ASSIGN = AssignOperator("=")
|
||||
companion object {
|
||||
@JvmField
|
||||
val ASSIGN = AssignOperator("=")
|
||||
|
||||
@JvmField
|
||||
val PLUS = ArithmeticOperator("+")
|
||||
@JvmField
|
||||
val PLUS = ArithmeticOperator("+")
|
||||
|
||||
@JvmField
|
||||
val MINUS = ArithmeticOperator("-")
|
||||
@JvmField
|
||||
val MINUS = ArithmeticOperator("-")
|
||||
|
||||
@JvmField
|
||||
val MULTIPLY = ArithmeticOperator("*")
|
||||
@JvmField
|
||||
val MULTIPLY = ArithmeticOperator("*")
|
||||
|
||||
@JvmField
|
||||
val DIV = ArithmeticOperator("/")
|
||||
@JvmField
|
||||
val DIV = ArithmeticOperator("/")
|
||||
|
||||
@JvmField
|
||||
val MOD = ArithmeticOperator("%")
|
||||
@JvmField
|
||||
val MOD = ArithmeticOperator("%")
|
||||
|
||||
@JvmField
|
||||
val LOGICAL_OR = LogicalOperator("||")
|
||||
@JvmField
|
||||
val LOGICAL_OR = LogicalOperator("||")
|
||||
|
||||
@JvmField
|
||||
val LOGICAL_AND = LogicalOperator("&&")
|
||||
@JvmField
|
||||
val LOGICAL_AND = LogicalOperator("&&")
|
||||
|
||||
@JvmField
|
||||
val BITWISE_OR = BitwiseOperator("|")
|
||||
@JvmField
|
||||
val BITWISE_OR = BitwiseOperator("|")
|
||||
|
||||
@JvmField
|
||||
val BITWISE_AND = BitwiseOperator("&")
|
||||
@JvmField
|
||||
val BITWISE_AND = BitwiseOperator("&")
|
||||
|
||||
@JvmField
|
||||
val BITWISE_XOR = BitwiseOperator("^")
|
||||
@JvmField
|
||||
val BITWISE_XOR = BitwiseOperator("^")
|
||||
|
||||
@JvmField
|
||||
val EQUALS = ComparisonOperator("==")
|
||||
@JvmField
|
||||
val EQUALS = ComparisonOperator("==")
|
||||
|
||||
@JvmField
|
||||
val NOT_EQUALS = ComparisonOperator("!=")
|
||||
@JvmField
|
||||
val NOT_EQUALS = ComparisonOperator("!=")
|
||||
|
||||
@JvmField
|
||||
val IDENTITY_EQUALS = ComparisonOperator("===")
|
||||
@JvmField
|
||||
val IDENTITY_EQUALS = ComparisonOperator("===")
|
||||
|
||||
@JvmField
|
||||
val IDENTITY_NOT_EQUALS = ComparisonOperator("!==")
|
||||
@JvmField
|
||||
val IDENTITY_NOT_EQUALS = ComparisonOperator("!==")
|
||||
|
||||
@JvmField
|
||||
val GREATER = ComparisonOperator(">")
|
||||
@JvmField
|
||||
val GREATER = ComparisonOperator(">")
|
||||
|
||||
@JvmField
|
||||
val GREATER_OR_EQUALS = ComparisonOperator(">=")
|
||||
@JvmField
|
||||
val GREATER_OR_EQUALS = ComparisonOperator(">=")
|
||||
|
||||
@JvmField
|
||||
val LESS = ComparisonOperator("<")
|
||||
@JvmField
|
||||
val LESS = ComparisonOperator("<")
|
||||
|
||||
@JvmField
|
||||
val LESS_OR_EQUALS = ComparisonOperator("<=")
|
||||
@JvmField
|
||||
val LESS_OR_EQUALS = ComparisonOperator("<=")
|
||||
|
||||
@JvmField
|
||||
val SHIFT_LEFT = BitwiseOperator("<<")
|
||||
@JvmField
|
||||
val SHIFT_LEFT = BitwiseOperator("<<")
|
||||
|
||||
@JvmField
|
||||
val SHIFT_RIGHT = BitwiseOperator(">>")
|
||||
@JvmField
|
||||
val SHIFT_RIGHT = BitwiseOperator(">>")
|
||||
|
||||
@JvmField
|
||||
val UNSIGNED_SHIFT_RIGHT = BitwiseOperator(">>>")
|
||||
@JvmField
|
||||
val UNSIGNED_SHIFT_RIGHT = BitwiseOperator(">>>")
|
||||
|
||||
@JvmField
|
||||
val OTHER = UastBinaryOperator("<other>")
|
||||
@JvmField
|
||||
val OTHER = UastBinaryOperator("<other>")
|
||||
|
||||
@JvmField
|
||||
val PLUS_ASSIGN = AssignOperator("+=")
|
||||
@JvmField
|
||||
val PLUS_ASSIGN = AssignOperator("+=")
|
||||
|
||||
@JvmField
|
||||
val MINUS_ASSIGN = AssignOperator("-=")
|
||||
|
||||
@JvmField
|
||||
val MULTIPLY_ASSIGN = AssignOperator("*=")
|
||||
|
||||
@JvmField
|
||||
val DIVIDE_ASSIGN = AssignOperator("/=")
|
||||
@JvmField
|
||||
val MINUS_ASSIGN = AssignOperator("-=")
|
||||
|
||||
@JvmField
|
||||
val REMAINDER_ASSIGN = AssignOperator("%=")
|
||||
|
||||
@JvmField
|
||||
val AND_ASSIGN = AssignOperator("&=")
|
||||
|
||||
@JvmField
|
||||
val XOR_ASSIGN = AssignOperator("^=")
|
||||
|
||||
@JvmField
|
||||
val OR_ASSIGN = AssignOperator("|=")
|
||||
|
||||
@JvmField
|
||||
val SHIFT_LEFT_ASSIGN = AssignOperator("<<=")
|
||||
|
||||
@JvmField
|
||||
val SHIFT_RIGHT_ASSIGN = AssignOperator(">>=")
|
||||
|
||||
@JvmField
|
||||
val UNSIGNED_SHIFT_RIGHT_ASSIGN = AssignOperator(">>>=")
|
||||
}
|
||||
@JvmField
|
||||
val MULTIPLY_ASSIGN = AssignOperator("*=")
|
||||
|
||||
override fun toString() = text
|
||||
@JvmField
|
||||
val DIVIDE_ASSIGN = AssignOperator("/=")
|
||||
|
||||
@JvmField
|
||||
val REMAINDER_ASSIGN = AssignOperator("%=")
|
||||
|
||||
@JvmField
|
||||
val AND_ASSIGN = AssignOperator("&=")
|
||||
|
||||
@JvmField
|
||||
val XOR_ASSIGN = AssignOperator("^=")
|
||||
|
||||
@JvmField
|
||||
val OR_ASSIGN = AssignOperator("|=")
|
||||
|
||||
@JvmField
|
||||
val SHIFT_LEFT_ASSIGN = AssignOperator("<<=")
|
||||
|
||||
@JvmField
|
||||
val SHIFT_RIGHT_ASSIGN = AssignOperator(">>=")
|
||||
|
||||
@JvmField
|
||||
val UNSIGNED_SHIFT_RIGHT_ASSIGN = AssignOperator(">>>=")
|
||||
}
|
||||
|
||||
override fun toString() = text
|
||||
}
|
||||
@@ -19,29 +19,29 @@ package org.jetbrains.uast
|
||||
* Kinds of [UCallExpression].
|
||||
*/
|
||||
open class UastCallKind(val name: String) {
|
||||
companion object {
|
||||
@JvmField
|
||||
val METHOD_CALL = UastCallKind("method_call")
|
||||
companion object {
|
||||
@JvmField
|
||||
val METHOD_CALL = UastCallKind("method_call")
|
||||
|
||||
@JvmField
|
||||
val CONSTRUCTOR_CALL = UastCallKind("constructor_call")
|
||||
|
||||
@JvmField
|
||||
val NEW_ARRAY_WITH_DIMENSIONS = UastCallKind("new_array_with_dimensions")
|
||||
@JvmField
|
||||
val CONSTRUCTOR_CALL = UastCallKind("constructor_call")
|
||||
|
||||
/**
|
||||
* Initializer parts are available in call expression as value arguments.
|
||||
* [NEW_ARRAY_WITH_INITIALIZER] is a top-level initializer. In case of multi-dimensional arrays, inner initializers
|
||||
* have type of [NESTED_ARRAY_INITIALIZER].
|
||||
*/
|
||||
@JvmField
|
||||
val NEW_ARRAY_WITH_INITIALIZER = UastCallKind("new_array_with_initializer")
|
||||
@JvmField
|
||||
val NEW_ARRAY_WITH_DIMENSIONS = UastCallKind("new_array_with_dimensions")
|
||||
|
||||
@JvmField
|
||||
val NESTED_ARRAY_INITIALIZER = UastCallKind("array_initializer")
|
||||
}
|
||||
/**
|
||||
* Initializer parts are available in call expression as value arguments.
|
||||
* [NEW_ARRAY_WITH_INITIALIZER] is a top-level initializer. In case of multi-dimensional arrays, inner initializers
|
||||
* have type of [NESTED_ARRAY_INITIALIZER].
|
||||
*/
|
||||
@JvmField
|
||||
val NEW_ARRAY_WITH_INITIALIZER = UastCallKind("new_array_with_initializer")
|
||||
|
||||
override fun toString(): String{
|
||||
return "UastCallKind(name='$name')"
|
||||
}
|
||||
@JvmField
|
||||
val NESTED_ARRAY_INITIALIZER = UastCallKind("array_initializer")
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "UastCallKind(name='$name')"
|
||||
}
|
||||
}
|
||||
@@ -20,24 +20,24 @@ package org.jetbrains.uast
|
||||
* Kinds of [UClass].
|
||||
*/
|
||||
open class UastClassKind(val text: String) {
|
||||
companion object {
|
||||
@JvmField
|
||||
val CLASS = UastClassKind("class")
|
||||
companion object {
|
||||
@JvmField
|
||||
val CLASS = UastClassKind("class")
|
||||
|
||||
@JvmField
|
||||
val INTERFACE = UastClassKind("interface")
|
||||
@JvmField
|
||||
val INTERFACE = UastClassKind("interface")
|
||||
|
||||
@JvmField
|
||||
val ANNOTATION = UastClassKind("annotation")
|
||||
@JvmField
|
||||
val ANNOTATION = UastClassKind("annotation")
|
||||
|
||||
@JvmField
|
||||
val ENUM = UastClassKind("enum")
|
||||
@JvmField
|
||||
val ENUM = UastClassKind("enum")
|
||||
|
||||
@JvmField
|
||||
val OBJECT = UastClassKind("object")
|
||||
}
|
||||
@JvmField
|
||||
val OBJECT = UastClassKind("object")
|
||||
}
|
||||
|
||||
override fun toString(): String{
|
||||
return "UastClassKind(text='$text')"
|
||||
}
|
||||
override fun toString(): String {
|
||||
return "UastClassKind(text='$text')"
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,8 @@ package org.jetbrains.uast
|
||||
* @see [UastPrefixOperator], [UastPostfixOperator], [UastBinaryOperator]
|
||||
*/
|
||||
interface UastOperator {
|
||||
/**
|
||||
* Returns the operator text to render in [UElement.asRenderString].
|
||||
*/
|
||||
val text: String
|
||||
/**
|
||||
* Returns the operator text to render in [UElement.asRenderString].
|
||||
*/
|
||||
val text: String
|
||||
}
|
||||
@@ -18,17 +18,17 @@ package org.jetbrains.uast
|
||||
/**
|
||||
* [UPostfixExpression] operators.
|
||||
*/
|
||||
open class UastPostfixOperator(override val text: String): UastOperator {
|
||||
companion object {
|
||||
@JvmField
|
||||
val INC = UastPostfixOperator("++")
|
||||
open class UastPostfixOperator(override val text: String) : UastOperator {
|
||||
companion object {
|
||||
@JvmField
|
||||
val INC = UastPostfixOperator("++")
|
||||
|
||||
@JvmField
|
||||
val DEC = UastPostfixOperator("--")
|
||||
@JvmField
|
||||
val DEC = UastPostfixOperator("--")
|
||||
|
||||
@JvmField
|
||||
val UNKNOWN = UastPostfixOperator("<unknown>")
|
||||
}
|
||||
@JvmField
|
||||
val UNKNOWN = UastPostfixOperator("<unknown>")
|
||||
}
|
||||
|
||||
override fun toString() = text
|
||||
override fun toString() = text
|
||||
}
|
||||
|
||||
@@ -18,29 +18,29 @@ package org.jetbrains.uast
|
||||
/**
|
||||
* [UPrefixExpression] operators.
|
||||
*/
|
||||
class UastPrefixOperator(override val text: String): UastOperator {
|
||||
companion object {
|
||||
@JvmField
|
||||
val INC = UastPrefixOperator("++")
|
||||
class UastPrefixOperator(override val text: String) : UastOperator {
|
||||
companion object {
|
||||
@JvmField
|
||||
val INC = UastPrefixOperator("++")
|
||||
|
||||
@JvmField
|
||||
val DEC = UastPrefixOperator("--")
|
||||
@JvmField
|
||||
val DEC = UastPrefixOperator("--")
|
||||
|
||||
@JvmField
|
||||
val UNARY_MINUS = UastPrefixOperator("-")
|
||||
@JvmField
|
||||
val UNARY_MINUS = UastPrefixOperator("-")
|
||||
|
||||
@JvmField
|
||||
val UNARY_PLUS = UastPrefixOperator("+")
|
||||
@JvmField
|
||||
val UNARY_PLUS = UastPrefixOperator("+")
|
||||
|
||||
@JvmField
|
||||
val LOGICAL_NOT = UastPrefixOperator("!")
|
||||
@JvmField
|
||||
val LOGICAL_NOT = UastPrefixOperator("!")
|
||||
|
||||
@JvmField
|
||||
val BITWISE_NOT = UastPrefixOperator("~")
|
||||
@JvmField
|
||||
val BITWISE_NOT = UastPrefixOperator("~")
|
||||
|
||||
@JvmField
|
||||
val UNKNOWN = UastPrefixOperator("<unknown>")
|
||||
}
|
||||
@JvmField
|
||||
val UNKNOWN = UastPrefixOperator("<unknown>")
|
||||
}
|
||||
|
||||
override fun toString() = text
|
||||
override fun toString() = text
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ package org.jetbrains.uast
|
||||
* Additional type examples: Kotlin safe call (?.).
|
||||
*/
|
||||
open class UastQualifiedExpressionAccessType(val name: String) {
|
||||
companion object {
|
||||
@JvmField
|
||||
val SIMPLE = UastQualifiedExpressionAccessType(".")
|
||||
}
|
||||
companion object {
|
||||
@JvmField
|
||||
val SIMPLE = UastQualifiedExpressionAccessType(".")
|
||||
}
|
||||
|
||||
override fun toString(): String{
|
||||
return "UastQualifiedExpressionAccessType(name='$name')"
|
||||
}
|
||||
override fun toString(): String {
|
||||
return "UastQualifiedExpressionAccessType(name='$name')"
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.uast
|
||||
* Kinds of [UExpressionList].
|
||||
*/
|
||||
open class UastSpecialExpressionKind(val name: String) {
|
||||
override fun toString(): String{
|
||||
return "UastSpecialExpressionKind(name='$name')"
|
||||
}
|
||||
override fun toString(): String {
|
||||
return "UastSpecialExpressionKind(name='$name')"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,21 +20,21 @@ import com.intellij.psi.PsiModifier
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
|
||||
enum class UastVisibility(val text: String) {
|
||||
PUBLIC("public"),
|
||||
PRIVATE("private"),
|
||||
PROTECTED("protected"),
|
||||
PACKAGE_LOCAL("packageLocal"),
|
||||
LOCAL("local");
|
||||
PUBLIC("public"),
|
||||
PRIVATE("private"),
|
||||
PROTECTED("protected"),
|
||||
PACKAGE_LOCAL("packageLocal"),
|
||||
LOCAL("local");
|
||||
|
||||
override fun toString() = text
|
||||
|
||||
companion object {
|
||||
operator fun get(declaration: PsiModifierListOwner): UastVisibility {
|
||||
if (declaration.hasModifierProperty(PsiModifier.PUBLIC)) return UastVisibility.PUBLIC
|
||||
if (declaration.hasModifierProperty(PsiModifier.PROTECTED)) return UastVisibility.PROTECTED
|
||||
if (declaration.hasModifierProperty(PsiModifier.PRIVATE)) return UastVisibility.PRIVATE
|
||||
if (declaration is PsiLocalVariable) return UastVisibility.LOCAL
|
||||
return UastVisibility.PACKAGE_LOCAL
|
||||
}
|
||||
override fun toString() = text
|
||||
|
||||
companion object {
|
||||
operator fun get(declaration: PsiModifierListOwner): UastVisibility {
|
||||
if (declaration.hasModifierProperty(PsiModifier.PUBLIC)) return UastVisibility.PUBLIC
|
||||
if (declaration.hasModifierProperty(PsiModifier.PROTECTED)) return UastVisibility.PROTECTED
|
||||
if (declaration.hasModifierProperty(PsiModifier.PRIVATE)) return UastVisibility.PRIVATE
|
||||
if (declaration is PsiLocalVariable) return UastVisibility.LOCAL
|
||||
return UastVisibility.PACKAGE_LOCAL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,6 @@ import com.intellij.psi.impl.light.LightParameter
|
||||
import org.jetbrains.uast.UastErrorType
|
||||
|
||||
class UastPsiParameterNotResolved(
|
||||
declarationScope: PsiElement,
|
||||
language: Language
|
||||
declarationScope: PsiElement,
|
||||
language: Language
|
||||
) : LightParameter("error", UastErrorType, declarationScope, language)
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("UastUtils")
|
||||
|
||||
package org.jetbrains.uast
|
||||
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
@@ -35,46 +36,47 @@ import org.jetbrains.uast.visitor.UastVisitor
|
||||
* @return containing qualified expression if the call is a child of the qualified expression, call element otherwise.
|
||||
*/
|
||||
fun UExpression.getQualifiedParentOrThis(): UExpression {
|
||||
fun findParent(current: UExpression?, previous: UExpression): UExpression? = when (current) {
|
||||
is UQualifiedReferenceExpression -> {
|
||||
if (current.selector == previous)
|
||||
findParent(current.uastParent as? UExpression, current) ?: current
|
||||
else
|
||||
previous
|
||||
}
|
||||
is UParenthesizedExpression -> findParent(current.expression, previous) ?: previous
|
||||
else -> null
|
||||
fun findParent(current: UExpression?, previous: UExpression): UExpression? = when (current) {
|
||||
is UQualifiedReferenceExpression -> {
|
||||
if (current.selector == previous)
|
||||
findParent(current.uastParent as? UExpression, current) ?: current
|
||||
else
|
||||
previous
|
||||
}
|
||||
is UParenthesizedExpression -> findParent(current.expression, previous) ?: previous
|
||||
else -> null
|
||||
}
|
||||
|
||||
return findParent(uastParent as? UExpression, this) ?: this
|
||||
return findParent(uastParent as? UExpression, this) ?: this
|
||||
}
|
||||
|
||||
|
||||
fun UExpression.asQualifiedPath(): List<String>? {
|
||||
if (this is USimpleNameReferenceExpression) {
|
||||
return listOf(this.identifier)
|
||||
} else if (this !is UQualifiedReferenceExpression) {
|
||||
return null
|
||||
}
|
||||
if (this is USimpleNameReferenceExpression) {
|
||||
return listOf(this.identifier)
|
||||
}
|
||||
else if (this !is UQualifiedReferenceExpression) {
|
||||
return null
|
||||
}
|
||||
|
||||
var error = false
|
||||
val list = mutableListOf<String>()
|
||||
fun addIdentifiers(expr: UQualifiedReferenceExpression) {
|
||||
val receiver = expr.receiver.unwrapParenthesis()
|
||||
val selector = expr.selector as? USimpleNameReferenceExpression ?: run { error = true; return }
|
||||
when (receiver) {
|
||||
is UQualifiedReferenceExpression -> addIdentifiers(receiver)
|
||||
is USimpleNameReferenceExpression -> list += receiver.identifier
|
||||
else -> {
|
||||
error = true
|
||||
return
|
||||
}
|
||||
}
|
||||
list += selector.identifier
|
||||
var error = false
|
||||
val list = mutableListOf<String>()
|
||||
fun addIdentifiers(expr: UQualifiedReferenceExpression) {
|
||||
val receiver = expr.receiver.unwrapParenthesis()
|
||||
val selector = expr.selector as? USimpleNameReferenceExpression ?: run { error = true; return }
|
||||
when (receiver) {
|
||||
is UQualifiedReferenceExpression -> addIdentifiers(receiver)
|
||||
is USimpleNameReferenceExpression -> list += receiver.identifier
|
||||
else -> {
|
||||
error = true
|
||||
return
|
||||
}
|
||||
}
|
||||
list += selector.identifier
|
||||
}
|
||||
|
||||
addIdentifiers(this)
|
||||
return if (error) null else list
|
||||
addIdentifiers(this)
|
||||
return if (error) null else list
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,27 +89,29 @@ fun UExpression.asQualifiedPath(): List<String>? {
|
||||
* @return list of qualified expressions, or the empty list if the received expression is not a qualified expression.
|
||||
*/
|
||||
fun UExpression?.getQualifiedChain(): List<UExpression> {
|
||||
fun collect(expr: UQualifiedReferenceExpression, chains: MutableList<UExpression>) {
|
||||
val receiver = expr.receiver.unwrapParenthesis()
|
||||
if (receiver is UQualifiedReferenceExpression) {
|
||||
collect(receiver, chains)
|
||||
} else {
|
||||
chains += receiver
|
||||
}
|
||||
|
||||
val selector = expr.selector.unwrapParenthesis()
|
||||
if (selector is UQualifiedReferenceExpression) {
|
||||
collect(selector, chains)
|
||||
} else {
|
||||
chains += selector
|
||||
}
|
||||
fun collect(expr: UQualifiedReferenceExpression, chains: MutableList<UExpression>) {
|
||||
val receiver = expr.receiver.unwrapParenthesis()
|
||||
if (receiver is UQualifiedReferenceExpression) {
|
||||
collect(receiver, chains)
|
||||
}
|
||||
else {
|
||||
chains += receiver
|
||||
}
|
||||
|
||||
if (this == null) return emptyList()
|
||||
val qualifiedExpression = this as? UQualifiedReferenceExpression ?: return listOf(this)
|
||||
val chains = mutableListOf<UExpression>()
|
||||
collect(qualifiedExpression, chains)
|
||||
return chains
|
||||
val selector = expr.selector.unwrapParenthesis()
|
||||
if (selector is UQualifiedReferenceExpression) {
|
||||
collect(selector, chains)
|
||||
}
|
||||
else {
|
||||
chains += selector
|
||||
}
|
||||
}
|
||||
|
||||
if (this == null) return emptyList()
|
||||
val qualifiedExpression = this as? UQualifiedReferenceExpression ?: return listOf(this)
|
||||
val chains = mutableListOf<UExpression>()
|
||||
collect(qualifiedExpression, chains)
|
||||
return chains
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,13 +127,13 @@ fun UExpression?.getQualifiedChain(): List<UExpression> {
|
||||
* Outermost qualified (return value): a.b.c(asd).g
|
||||
*/
|
||||
fun UExpression.getOutermostQualified(): UQualifiedReferenceExpression? {
|
||||
tailrec fun getOutermostQualified(current: UElement?, previous: UExpression): UQualifiedReferenceExpression? = when (current) {
|
||||
is UQualifiedReferenceExpression -> getOutermostQualified(current.uastParent, current)
|
||||
is UParenthesizedExpression -> getOutermostQualified(current.uastParent, previous)
|
||||
else -> if (previous is UQualifiedReferenceExpression) previous else null
|
||||
}
|
||||
tailrec fun getOutermostQualified(current: UElement?, previous: UExpression): UQualifiedReferenceExpression? = when (current) {
|
||||
is UQualifiedReferenceExpression -> getOutermostQualified(current.uastParent, current)
|
||||
is UParenthesizedExpression -> getOutermostQualified(current.uastParent, previous)
|
||||
else -> if (previous is UQualifiedReferenceExpression) previous else null
|
||||
}
|
||||
|
||||
return getOutermostQualified(this.uastParent, this)
|
||||
return getOutermostQualified(this.uastParent, this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,9 +143,9 @@ fun UExpression.getOutermostQualified(): UQualifiedReferenceExpression? {
|
||||
* @return true, if the received expression is a qualified chain of identifiers, and the trailing part of such chain is [fqName].
|
||||
*/
|
||||
fun UExpression.matchesQualified(fqName: String): Boolean {
|
||||
val identifiers = this.asQualifiedPath() ?: return false
|
||||
val passedIdentifiers = fqName.trim('.').split('.')
|
||||
return identifiers == passedIdentifiers
|
||||
val identifiers = this.asQualifiedPath() ?: return false
|
||||
val passedIdentifiers = fqName.trim('.').split('.')
|
||||
return identifiers == passedIdentifiers
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,13 +155,13 @@ fun UExpression.matchesQualified(fqName: String): Boolean {
|
||||
* @return true, if the received expression is a qualified chain of identifiers, and the leading part of such chain is [fqName].
|
||||
*/
|
||||
fun UExpression.startsWithQualified(fqName: String): Boolean {
|
||||
val identifiers = this.asQualifiedPath() ?: return false
|
||||
val passedIdentifiers = fqName.trim('.').split('.')
|
||||
if (identifiers.size < passedIdentifiers.size) return false
|
||||
passedIdentifiers.forEachIndexed { i, passedIdentifier ->
|
||||
if (passedIdentifier != identifiers[i]) return false
|
||||
}
|
||||
return true
|
||||
val identifiers = this.asQualifiedPath() ?: return false
|
||||
val passedIdentifiers = fqName.trim('.').split('.')
|
||||
if (identifiers.size < passedIdentifiers.size) return false
|
||||
passedIdentifiers.forEachIndexed { i, passedIdentifier ->
|
||||
if (passedIdentifier != identifiers[i]) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,34 +171,34 @@ fun UExpression.startsWithQualified(fqName: String): Boolean {
|
||||
* @return true, if the received expression is a qualified chain of identifiers, and the trailing part of such chain is [fqName].
|
||||
*/
|
||||
fun UExpression.endsWithQualified(fqName: String): Boolean {
|
||||
val identifiers = this.asQualifiedPath()?.asReversed() ?: return false
|
||||
val passedIdentifiers = fqName.trim('.').split('.').asReversed()
|
||||
if (identifiers.size < passedIdentifiers.size) return false
|
||||
passedIdentifiers.forEachIndexed { i, passedIdentifier ->
|
||||
if (passedIdentifier != identifiers[i]) return false
|
||||
}
|
||||
return true
|
||||
val identifiers = this.asQualifiedPath()?.asReversed() ?: return false
|
||||
val passedIdentifiers = fqName.trim('.').split('.').asReversed()
|
||||
if (identifiers.size < passedIdentifiers.size) return false
|
||||
passedIdentifiers.forEachIndexed { i, passedIdentifier ->
|
||||
if (passedIdentifier != identifiers[i]) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun UElement.asRecursiveLogString(render: (UElement) -> String = { it.asLogString() }): String {
|
||||
val stringBuilder = StringBuilder()
|
||||
val indent = " "
|
||||
val stringBuilder = StringBuilder()
|
||||
val indent = " "
|
||||
|
||||
accept(object : UastVisitor {
|
||||
private var level = 0
|
||||
accept(object : UastVisitor {
|
||||
private var level = 0
|
||||
|
||||
override fun visitElement(node: UElement): Boolean {
|
||||
stringBuilder.append(indent.repeat(level))
|
||||
stringBuilder.appendln(render(node))
|
||||
level++
|
||||
return false
|
||||
}
|
||||
override fun visitElement(node: UElement): Boolean {
|
||||
stringBuilder.append(indent.repeat(level))
|
||||
stringBuilder.appendln(render(node))
|
||||
level++
|
||||
return false
|
||||
}
|
||||
|
||||
override fun afterVisitElement(node: UElement) {
|
||||
super.afterVisitElement(node)
|
||||
level--
|
||||
}
|
||||
})
|
||||
return stringBuilder.toString()
|
||||
override fun afterVisitElement(node: UElement) {
|
||||
super.afterVisitElement(node)
|
||||
level--
|
||||
}
|
||||
})
|
||||
return stringBuilder.toString()
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
@file:JvmName("UastExpressionUtils")
|
||||
|
||||
package org.jetbrains.uast.util
|
||||
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
@@ -22,28 +22,28 @@ import org.jetbrains.uast.UResolvable
|
||||
// that we cannot or do not want to evaluate
|
||||
class UCallResultValue(val resolvable: UResolvable, val arguments: List<UValue>) : UValueBase(), UDependency {
|
||||
|
||||
private val argumentsHashCode = arguments.hashCode()
|
||||
private val argumentsHashCode = arguments.hashCode()
|
||||
|
||||
override fun merge(other: UValue): UValue = when (other) {
|
||||
this -> this
|
||||
is UCallResultValue -> {
|
||||
if (resolvable == other.resolvable) {
|
||||
UCallResultValue(resolvable, arguments.map { UUndeterminedValue })
|
||||
}
|
||||
else {
|
||||
UPhiValue.create(this, other)
|
||||
}
|
||||
}
|
||||
else -> UPhiValue.create(this, other)
|
||||
override fun merge(other: UValue): UValue = when (other) {
|
||||
this -> this
|
||||
is UCallResultValue -> {
|
||||
if (resolvable == other.resolvable) {
|
||||
UCallResultValue(resolvable, arguments.map { UUndeterminedValue })
|
||||
}
|
||||
else {
|
||||
UPhiValue.create(this, other)
|
||||
}
|
||||
}
|
||||
else -> UPhiValue.create(this, other)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is UCallResultValue && resolvable == other.resolvable &&
|
||||
argumentsHashCode == other.argumentsHashCode && arguments == other.arguments
|
||||
override fun equals(other: Any?) =
|
||||
other is UCallResultValue && resolvable == other.resolvable &&
|
||||
argumentsHashCode == other.argumentsHashCode && arguments == other.arguments
|
||||
|
||||
override fun hashCode() = resolvable.hashCode() * 19 + argumentsHashCode
|
||||
override fun hashCode() = resolvable.hashCode() * 19 + argumentsHashCode
|
||||
|
||||
override fun toString(): String {
|
||||
return "external ${(resolvable as? UElement)?.asRenderString() ?: "???"}(${arguments.joinToString()})"
|
||||
}
|
||||
override fun toString(): String {
|
||||
return "external ${(resolvable as? UElement)?.asRenderString() ?: "???"}(${arguments.joinToString()})"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,407 +20,409 @@ import com.intellij.psi.PsiType
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
interface UConstant : UValue {
|
||||
val value: Any?
|
||||
val value: Any?
|
||||
|
||||
val source: UExpression?
|
||||
val source: UExpression?
|
||||
|
||||
// Used for string concatenation
|
||||
fun asString(): String
|
||||
// Used for string concatenation
|
||||
fun asString(): String
|
||||
|
||||
// Used for logging / debugging purposes
|
||||
override fun toString(): String
|
||||
// Used for logging / debugging purposes
|
||||
override fun toString(): String
|
||||
}
|
||||
|
||||
abstract class UAbstractConstant : UValueBase(), UConstant {
|
||||
override fun valueEquals(other: UValue) = when (other) {
|
||||
this -> UBooleanConstant.True
|
||||
is UConstant -> UBooleanConstant.False
|
||||
else -> super.valueEquals(other)
|
||||
}
|
||||
override fun valueEquals(other: UValue) = when (other) {
|
||||
this -> UBooleanConstant.True
|
||||
is UConstant -> UBooleanConstant.False
|
||||
else -> super.valueEquals(other)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?) = other is UAbstractConstant && value == other.value
|
||||
override fun equals(other: Any?) = other is UAbstractConstant && value == other.value
|
||||
|
||||
override fun hashCode() = value?.hashCode() ?: 0
|
||||
override fun hashCode() = value?.hashCode() ?: 0
|
||||
|
||||
override fun toString() = "$value"
|
||||
override fun toString() = "$value"
|
||||
|
||||
override fun asString() = toString()
|
||||
override fun asString() = toString()
|
||||
}
|
||||
|
||||
enum class UNumericType(val prefix: String = "") {
|
||||
BYTE("(byte)"),
|
||||
SHORT("(short)"),
|
||||
INT(),
|
||||
LONG("(long)"),
|
||||
FLOAT("(float)"),
|
||||
DOUBLE();
|
||||
BYTE("(byte)"),
|
||||
SHORT("(short)"),
|
||||
INT(),
|
||||
LONG("(long)"),
|
||||
FLOAT("(float)"),
|
||||
DOUBLE();
|
||||
|
||||
fun merge(other: UNumericType): UNumericType {
|
||||
if (this == DOUBLE || other == DOUBLE) return DOUBLE
|
||||
if (this == FLOAT || other == FLOAT) return FLOAT
|
||||
if (this == LONG || other == LONG) return LONG
|
||||
return INT
|
||||
}
|
||||
fun merge(other: UNumericType): UNumericType {
|
||||
if (this == DOUBLE || other == DOUBLE) return DOUBLE
|
||||
if (this == FLOAT || other == FLOAT) return FLOAT
|
||||
if (this == LONG || other == LONG) return LONG
|
||||
return INT
|
||||
}
|
||||
}
|
||||
|
||||
abstract class UNumericConstant(val type: UNumericType, override val source: ULiteralExpression?) : UAbstractConstant() {
|
||||
override abstract val value: Number
|
||||
override abstract val value: Number
|
||||
|
||||
override fun toString() = "${type.prefix}$value"
|
||||
override fun toString() = "${type.prefix}$value"
|
||||
|
||||
override fun asString() = "$value"
|
||||
override fun asString() = "$value"
|
||||
}
|
||||
|
||||
private fun PsiType.toNumeric(): UNumericType = when (this) {
|
||||
PsiType.LONG -> UNumericType.LONG
|
||||
PsiType.INT -> UNumericType.INT
|
||||
PsiType.SHORT -> UNumericType.SHORT
|
||||
PsiType.BYTE -> UNumericType.BYTE
|
||||
PsiType.DOUBLE -> UNumericType.DOUBLE
|
||||
PsiType.FLOAT -> UNumericType.FLOAT
|
||||
else -> throw AssertionError("Conversion is impossible for type $canonicalText")
|
||||
PsiType.LONG -> UNumericType.LONG
|
||||
PsiType.INT -> UNumericType.INT
|
||||
PsiType.SHORT -> UNumericType.SHORT
|
||||
PsiType.BYTE -> UNumericType.BYTE
|
||||
PsiType.DOUBLE -> UNumericType.DOUBLE
|
||||
PsiType.FLOAT -> UNumericType.FLOAT
|
||||
else -> throw AssertionError("Conversion is impossible for type $canonicalText")
|
||||
}
|
||||
|
||||
private fun Int.asType(type: UNumericType): Int = when (type) {
|
||||
UNumericType.BYTE -> toByte().toInt()
|
||||
UNumericType.SHORT -> toShort().toInt()
|
||||
else -> this
|
||||
UNumericType.BYTE -> toByte().toInt()
|
||||
UNumericType.SHORT -> toShort().toInt()
|
||||
else -> this
|
||||
}
|
||||
|
||||
class UIntConstant(
|
||||
rawValue: Int, type: UNumericType = UNumericType.INT, override val source: ULiteralExpression? = null
|
||||
rawValue: Int, type: UNumericType = UNumericType.INT, override val source: ULiteralExpression? = null
|
||||
) : UNumericConstant(type, source) {
|
||||
|
||||
init {
|
||||
when (type) {
|
||||
UNumericType.INT, UNumericType.SHORT, UNumericType.BYTE -> {}
|
||||
else -> throw AssertionError("Incorrect UIntConstant type: $type")
|
||||
}
|
||||
init {
|
||||
when (type) {
|
||||
UNumericType.INT, UNumericType.SHORT, UNumericType.BYTE -> {
|
||||
}
|
||||
else -> throw AssertionError("Incorrect UIntConstant type: $type")
|
||||
}
|
||||
}
|
||||
|
||||
override val value: Int = rawValue.asType(type)
|
||||
override val value: Int = rawValue.asType(type)
|
||||
|
||||
constructor(value: Int, type: PsiType): this(value, type.toNumeric())
|
||||
constructor(value: Int, type: PsiType) : this(value, type.toNumeric())
|
||||
|
||||
override fun plus(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value + other.value, type.merge(other.type))
|
||||
is ULongConstant -> other + this
|
||||
is UFloatConstant -> other + this
|
||||
else -> super.plus(other)
|
||||
}
|
||||
override fun plus(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value + other.value, type.merge(other.type))
|
||||
is ULongConstant -> other + this
|
||||
is UFloatConstant -> other + this
|
||||
else -> super.plus(other)
|
||||
}
|
||||
|
||||
override fun times(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value * other.value, type.merge(other.type))
|
||||
is ULongConstant -> other * this
|
||||
is UFloatConstant -> other * this
|
||||
else -> super.times(other)
|
||||
}
|
||||
override fun times(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value * other.value, type.merge(other.type))
|
||||
is ULongConstant -> other * this
|
||||
is UFloatConstant -> other * this
|
||||
else -> super.times(other)
|
||||
}
|
||||
|
||||
override fun div(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value / other.value, type.merge(other.type))
|
||||
is ULongConstant -> ULongConstant(value / other.value)
|
||||
is UFloatConstant -> UFloatConstant.create(value / other.value, type.merge(other.type))
|
||||
else -> super.div(other)
|
||||
}
|
||||
override fun div(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value / other.value, type.merge(other.type))
|
||||
is ULongConstant -> ULongConstant(value / other.value)
|
||||
is UFloatConstant -> UFloatConstant.create(value / other.value, type.merge(other.type))
|
||||
else -> super.div(other)
|
||||
}
|
||||
|
||||
override fun mod(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value % other.value, type.merge(other.type))
|
||||
is ULongConstant -> ULongConstant(value % other.value)
|
||||
is UFloatConstant -> UFloatConstant.create(value % other.value, type.merge(other.type))
|
||||
else -> super.mod(other)
|
||||
}
|
||||
override fun mod(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value % other.value, type.merge(other.type))
|
||||
is ULongConstant -> ULongConstant(value % other.value)
|
||||
is UFloatConstant -> UFloatConstant.create(value % other.value, type.merge(other.type))
|
||||
else -> super.mod(other)
|
||||
}
|
||||
|
||||
override fun unaryMinus() = UIntConstant(-value, type)
|
||||
override fun unaryMinus() = UIntConstant(-value, type)
|
||||
|
||||
override fun greater(other: UValue) = when (other) {
|
||||
is UIntConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is ULongConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is UFloatConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
else -> super.greater(other)
|
||||
}
|
||||
override fun greater(other: UValue) = when (other) {
|
||||
is UIntConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is ULongConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is UFloatConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
else -> super.greater(other)
|
||||
}
|
||||
|
||||
override fun inc() = UIntConstant(value + 1, type)
|
||||
override fun inc() = UIntConstant(value + 1, type)
|
||||
|
||||
override fun dec() = UIntConstant(value - 1, type)
|
||||
override fun dec() = UIntConstant(value - 1, type)
|
||||
|
||||
override fun bitwiseAnd(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value and other.value, type.merge(other.type))
|
||||
else -> super.bitwiseAnd(other)
|
||||
}
|
||||
override fun bitwiseAnd(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value and other.value, type.merge(other.type))
|
||||
else -> super.bitwiseAnd(other)
|
||||
}
|
||||
|
||||
override fun bitwiseOr(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value or other.value, type.merge(other.type))
|
||||
else -> super.bitwiseOr(other)
|
||||
}
|
||||
override fun bitwiseOr(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value or other.value, type.merge(other.type))
|
||||
else -> super.bitwiseOr(other)
|
||||
}
|
||||
|
||||
override fun bitwiseXor(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value xor other.value, type.merge(other.type))
|
||||
else -> super.bitwiseXor(other)
|
||||
}
|
||||
override fun bitwiseXor(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value xor other.value, type.merge(other.type))
|
||||
else -> super.bitwiseXor(other)
|
||||
}
|
||||
|
||||
override fun shl(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value shl other.value, type.merge(other.type))
|
||||
else -> super.shl(other)
|
||||
}
|
||||
override fun shl(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value shl other.value, type.merge(other.type))
|
||||
else -> super.shl(other)
|
||||
}
|
||||
|
||||
override fun shr(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value shr other.value, type.merge(other.type))
|
||||
else -> super.shr(other)
|
||||
}
|
||||
override fun shr(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value shr other.value, type.merge(other.type))
|
||||
else -> super.shr(other)
|
||||
}
|
||||
|
||||
override fun ushr(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value ushr other.value, type.merge(other.type))
|
||||
else -> super.ushr(other)
|
||||
}
|
||||
override fun ushr(other: UValue) = when (other) {
|
||||
is UIntConstant -> UIntConstant(value ushr other.value, type.merge(other.type))
|
||||
else -> super.ushr(other)
|
||||
}
|
||||
}
|
||||
|
||||
class ULongConstant(override val value: Long, source: ULiteralExpression? = null) : UNumericConstant(UNumericType.LONG, source) {
|
||||
override fun plus(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value + other.value)
|
||||
is UIntConstant -> ULongConstant(value + other.value)
|
||||
is UFloatConstant -> other + this
|
||||
else -> super.plus(other)
|
||||
}
|
||||
override fun plus(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value + other.value)
|
||||
is UIntConstant -> ULongConstant(value + other.value)
|
||||
is UFloatConstant -> other + this
|
||||
else -> super.plus(other)
|
||||
}
|
||||
|
||||
override fun times(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value * other.value)
|
||||
is UIntConstant -> ULongConstant(value * other.value)
|
||||
is UFloatConstant -> other * this
|
||||
else -> super.times(other)
|
||||
}
|
||||
override fun times(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value * other.value)
|
||||
is UIntConstant -> ULongConstant(value * other.value)
|
||||
is UFloatConstant -> other * this
|
||||
else -> super.times(other)
|
||||
}
|
||||
|
||||
override fun div(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value / other.value)
|
||||
is UIntConstant -> ULongConstant(value / other.value)
|
||||
is UFloatConstant -> UFloatConstant.create(value / other.value, type.merge(other.type))
|
||||
else -> super.div(other)
|
||||
}
|
||||
override fun div(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value / other.value)
|
||||
is UIntConstant -> ULongConstant(value / other.value)
|
||||
is UFloatConstant -> UFloatConstant.create(value / other.value, type.merge(other.type))
|
||||
else -> super.div(other)
|
||||
}
|
||||
|
||||
override fun mod(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value % other.value)
|
||||
is UIntConstant -> ULongConstant(value % other.value)
|
||||
is UFloatConstant -> UFloatConstant.create(value % other.value, type.merge(other.type))
|
||||
else -> super.mod(other)
|
||||
}
|
||||
override fun mod(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value % other.value)
|
||||
is UIntConstant -> ULongConstant(value % other.value)
|
||||
is UFloatConstant -> UFloatConstant.create(value % other.value, type.merge(other.type))
|
||||
else -> super.mod(other)
|
||||
}
|
||||
|
||||
override fun unaryMinus() = ULongConstant(-value)
|
||||
override fun unaryMinus() = ULongConstant(-value)
|
||||
|
||||
override fun greater(other: UValue) = when (other) {
|
||||
is ULongConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is UIntConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is UFloatConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
else -> super.greater(other)
|
||||
}
|
||||
override fun greater(other: UValue) = when (other) {
|
||||
is ULongConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is UIntConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is UFloatConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
else -> super.greater(other)
|
||||
}
|
||||
|
||||
override fun inc() = ULongConstant(value + 1)
|
||||
override fun inc() = ULongConstant(value + 1)
|
||||
|
||||
override fun dec() = ULongConstant(value - 1)
|
||||
override fun dec() = ULongConstant(value - 1)
|
||||
|
||||
override fun bitwiseAnd(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value and other.value)
|
||||
else -> super.bitwiseAnd(other)
|
||||
}
|
||||
override fun bitwiseAnd(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value and other.value)
|
||||
else -> super.bitwiseAnd(other)
|
||||
}
|
||||
|
||||
override fun bitwiseOr(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value or other.value)
|
||||
else -> super.bitwiseOr(other)
|
||||
}
|
||||
override fun bitwiseOr(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value or other.value)
|
||||
else -> super.bitwiseOr(other)
|
||||
}
|
||||
|
||||
override fun bitwiseXor(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value xor other.value)
|
||||
else -> super.bitwiseXor(other)
|
||||
}
|
||||
override fun bitwiseXor(other: UValue) = when (other) {
|
||||
is ULongConstant -> ULongConstant(value xor other.value)
|
||||
else -> super.bitwiseXor(other)
|
||||
}
|
||||
|
||||
override fun shl(other: UValue) = when (other) {
|
||||
is UIntConstant -> ULongConstant(value shl other.value)
|
||||
else -> super.shl(other)
|
||||
}
|
||||
override fun shl(other: UValue) = when (other) {
|
||||
is UIntConstant -> ULongConstant(value shl other.value)
|
||||
else -> super.shl(other)
|
||||
}
|
||||
|
||||
override fun shr(other: UValue) = when (other) {
|
||||
is UIntConstant -> ULongConstant(value shr other.value)
|
||||
else -> super.shr(other)
|
||||
}
|
||||
override fun shr(other: UValue) = when (other) {
|
||||
is UIntConstant -> ULongConstant(value shr other.value)
|
||||
else -> super.shr(other)
|
||||
}
|
||||
|
||||
override fun ushr(other: UValue) = when (other) {
|
||||
is UIntConstant -> ULongConstant(value ushr other.value)
|
||||
else -> super.ushr(other)
|
||||
}
|
||||
override fun ushr(other: UValue) = when (other) {
|
||||
is UIntConstant -> ULongConstant(value ushr other.value)
|
||||
else -> super.ushr(other)
|
||||
}
|
||||
}
|
||||
|
||||
open class UFloatConstant protected constructor(
|
||||
override val value: Double, type: UNumericType = UNumericType.DOUBLE, source: ULiteralExpression? = null
|
||||
override val value: Double, type: UNumericType = UNumericType.DOUBLE, source: ULiteralExpression? = null
|
||||
) : UNumericConstant(type, source) {
|
||||
|
||||
override fun plus(other: UValue) = when (other) {
|
||||
is ULongConstant -> create(value + other.value, type.merge(other.type))
|
||||
is UIntConstant -> create(value + other.value, type.merge(other.type))
|
||||
is UFloatConstant -> create(value + other.value, type.merge(other.type))
|
||||
else -> super.plus(other)
|
||||
}
|
||||
override fun plus(other: UValue) = when (other) {
|
||||
is ULongConstant -> create(value + other.value, type.merge(other.type))
|
||||
is UIntConstant -> create(value + other.value, type.merge(other.type))
|
||||
is UFloatConstant -> create(value + other.value, type.merge(other.type))
|
||||
else -> super.plus(other)
|
||||
}
|
||||
|
||||
override fun times(other: UValue) = when (other) {
|
||||
is ULongConstant -> create(value * other.value, type.merge(other.type))
|
||||
is UIntConstant -> create(value * other.value, type.merge(other.type))
|
||||
is UFloatConstant -> create(value * other.value, type.merge(other.type))
|
||||
else -> super.times(other)
|
||||
}
|
||||
override fun times(other: UValue) = when (other) {
|
||||
is ULongConstant -> create(value * other.value, type.merge(other.type))
|
||||
is UIntConstant -> create(value * other.value, type.merge(other.type))
|
||||
is UFloatConstant -> create(value * other.value, type.merge(other.type))
|
||||
else -> super.times(other)
|
||||
}
|
||||
|
||||
override fun div(other: UValue) = when (other) {
|
||||
is ULongConstant -> create(value / other.value, type.merge(other.type))
|
||||
is UIntConstant -> create(value / other.value, type.merge(other.type))
|
||||
is UFloatConstant -> create(value / other.value, type.merge(other.type))
|
||||
else -> super.div(other)
|
||||
}
|
||||
override fun div(other: UValue) = when (other) {
|
||||
is ULongConstant -> create(value / other.value, type.merge(other.type))
|
||||
is UIntConstant -> create(value / other.value, type.merge(other.type))
|
||||
is UFloatConstant -> create(value / other.value, type.merge(other.type))
|
||||
else -> super.div(other)
|
||||
}
|
||||
|
||||
override fun mod(other: UValue) = when (other) {
|
||||
is ULongConstant -> create(value % other.value, type.merge(other.type))
|
||||
is UIntConstant -> create(value % other.value, type.merge(other.type))
|
||||
is UFloatConstant -> create(value % other.value, type.merge(other.type))
|
||||
else -> super.mod(other)
|
||||
}
|
||||
override fun mod(other: UValue) = when (other) {
|
||||
is ULongConstant -> create(value % other.value, type.merge(other.type))
|
||||
is UIntConstant -> create(value % other.value, type.merge(other.type))
|
||||
is UFloatConstant -> create(value % other.value, type.merge(other.type))
|
||||
else -> super.mod(other)
|
||||
}
|
||||
|
||||
override fun greater(other: UValue) = when (other) {
|
||||
is ULongConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is UIntConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is UFloatConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
else -> super.greater(other)
|
||||
}
|
||||
override fun greater(other: UValue) = when (other) {
|
||||
is ULongConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is UIntConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
is UFloatConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
else -> super.greater(other)
|
||||
}
|
||||
|
||||
override fun unaryMinus() = create(-value, type)
|
||||
override fun unaryMinus() = create(-value, type)
|
||||
|
||||
override fun inc() = create(value + 1, type)
|
||||
override fun inc() = create(value + 1, type)
|
||||
|
||||
override fun dec() = create(value - 1, type)
|
||||
override fun dec() = create(value - 1, type)
|
||||
|
||||
companion object {
|
||||
fun create(value: Double, type: UNumericType = UNumericType.DOUBLE, source: ULiteralExpression? = null) =
|
||||
when (type) {
|
||||
UNumericType.DOUBLE, UNumericType.FLOAT -> {
|
||||
if (value.isNaN()) UNaNConstant.valueOf(type)
|
||||
else UFloatConstant(value, type, source)
|
||||
}
|
||||
else -> throw AssertionError("Incorrect UFloatConstant type: $type")
|
||||
}
|
||||
companion object {
|
||||
fun create(value: Double, type: UNumericType = UNumericType.DOUBLE, source: ULiteralExpression? = null) =
|
||||
when (type) {
|
||||
UNumericType.DOUBLE, UNumericType.FLOAT -> {
|
||||
if (value.isNaN()) UNaNConstant.valueOf(type)
|
||||
else UFloatConstant(value, type, source)
|
||||
}
|
||||
else -> throw AssertionError("Incorrect UFloatConstant type: $type")
|
||||
}
|
||||
|
||||
fun create(value: Double, type: PsiType) = create(value, type.toNumeric())
|
||||
}
|
||||
fun create(value: Double, type: PsiType) = create(value, type.toNumeric())
|
||||
}
|
||||
}
|
||||
|
||||
sealed class UNaNConstant(type: UNumericType = UNumericType.DOUBLE) : UFloatConstant(kotlin.Double.NaN, type) {
|
||||
object Float : UNaNConstant(UNumericType.FLOAT)
|
||||
object Float : UNaNConstant(UNumericType.FLOAT)
|
||||
|
||||
object Double : UNaNConstant(UNumericType.DOUBLE)
|
||||
object Double : UNaNConstant(UNumericType.DOUBLE)
|
||||
|
||||
override fun greater(other: UValue) = UBooleanConstant.False
|
||||
override fun greater(other: UValue) = UBooleanConstant.False
|
||||
|
||||
override fun less(other: UValue) = UBooleanConstant.False
|
||||
override fun less(other: UValue) = UBooleanConstant.False
|
||||
|
||||
override fun greaterOrEquals(other: UValue) = UBooleanConstant.False
|
||||
override fun greaterOrEquals(other: UValue) = UBooleanConstant.False
|
||||
|
||||
override fun lessOrEquals(other: UValue) = UBooleanConstant.False
|
||||
override fun lessOrEquals(other: UValue) = UBooleanConstant.False
|
||||
|
||||
override fun valueEquals(other: UValue) = UBooleanConstant.False
|
||||
override fun valueEquals(other: UValue) = UBooleanConstant.False
|
||||
|
||||
companion object {
|
||||
fun valueOf(type: UNumericType) = when (type) {
|
||||
UNumericType.DOUBLE -> Double
|
||||
UNumericType.FLOAT -> Float
|
||||
else -> throw AssertionError("NaN exists only for Float / Double, but not for $type")
|
||||
}
|
||||
companion object {
|
||||
fun valueOf(type: UNumericType) = when (type) {
|
||||
UNumericType.DOUBLE -> Double
|
||||
UNumericType.FLOAT -> Float
|
||||
else -> throw AssertionError("NaN exists only for Float / Double, but not for $type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UCharConstant(override val value: Char, override val source: ULiteralExpression? = null) : UAbstractConstant() {
|
||||
override fun plus(other: UValue) = when (other) {
|
||||
is UIntConstant -> UCharConstant(value + other.value)
|
||||
is UCharConstant -> UCharConstant(value + other.value.toInt())
|
||||
else -> super.plus(other)
|
||||
}
|
||||
override fun plus(other: UValue) = when (other) {
|
||||
is UIntConstant -> UCharConstant(value + other.value)
|
||||
is UCharConstant -> UCharConstant(value + other.value.toInt())
|
||||
else -> super.plus(other)
|
||||
}
|
||||
|
||||
override fun minus(other: UValue) = when (other) {
|
||||
is UIntConstant -> UCharConstant(value - other.value)
|
||||
is UCharConstant -> UIntConstant(value - other.value)
|
||||
else -> super.plus(other)
|
||||
}
|
||||
override fun minus(other: UValue) = when (other) {
|
||||
is UIntConstant -> UCharConstant(value - other.value)
|
||||
is UCharConstant -> UIntConstant(value - other.value)
|
||||
else -> super.plus(other)
|
||||
}
|
||||
|
||||
override fun greater(other: UValue) = when (other) {
|
||||
is UCharConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
else -> super.greater(other)
|
||||
}
|
||||
override fun greater(other: UValue) = when (other) {
|
||||
is UCharConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
else -> super.greater(other)
|
||||
}
|
||||
|
||||
override fun inc() = this + UIntConstant(1)
|
||||
override fun inc() = this + UIntConstant(1)
|
||||
|
||||
override fun dec() = this - UIntConstant(1)
|
||||
override fun dec() = this - UIntConstant(1)
|
||||
|
||||
override fun toString() = "\'$value\'"
|
||||
override fun toString() = "\'$value\'"
|
||||
|
||||
override fun asString() = "$value"
|
||||
override fun asString() = "$value"
|
||||
}
|
||||
|
||||
sealed class UBooleanConstant(override val value: Boolean) : UAbstractConstant() {
|
||||
override val source = null
|
||||
override val source = null
|
||||
|
||||
object True : UBooleanConstant(true) {
|
||||
override fun not() = False
|
||||
object True : UBooleanConstant(true) {
|
||||
override fun not() = False
|
||||
|
||||
override fun and(other: UValue) = other as? UBooleanConstant ?: super.and(other)
|
||||
override fun and(other: UValue) = other as? UBooleanConstant ?: super.and(other)
|
||||
|
||||
override fun or(other: UValue) = True
|
||||
}
|
||||
override fun or(other: UValue) = True
|
||||
}
|
||||
|
||||
object False : UBooleanConstant(false) {
|
||||
override fun not() = True
|
||||
object False : UBooleanConstant(false) {
|
||||
override fun not() = True
|
||||
|
||||
override fun and(other: UValue) = False
|
||||
override fun and(other: UValue) = False
|
||||
|
||||
override fun or(other: UValue) = other as? UBooleanConstant ?: super.or(other)
|
||||
}
|
||||
override fun or(other: UValue) = other as? UBooleanConstant ?: super.or(other)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun valueOf(value: Boolean) = if (value) True else False
|
||||
}
|
||||
companion object {
|
||||
fun valueOf(value: Boolean) = if (value) True else False
|
||||
}
|
||||
}
|
||||
|
||||
class UStringConstant(override val value: String, override val source: ULiteralExpression? = null) : UAbstractConstant() {
|
||||
|
||||
override fun plus(other: UValue) = when (other) {
|
||||
is UConstant -> UStringConstant(value + other.asString())
|
||||
else -> super.plus(other)
|
||||
}
|
||||
override fun plus(other: UValue) = when (other) {
|
||||
is UConstant -> UStringConstant(value + other.asString())
|
||||
else -> super.plus(other)
|
||||
}
|
||||
|
||||
override fun greater(other: UValue) = when (other) {
|
||||
is UStringConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
else -> super.greater(other)
|
||||
}
|
||||
override fun greater(other: UValue) = when (other) {
|
||||
is UStringConstant -> UBooleanConstant.valueOf(value > other.value)
|
||||
else -> super.greater(other)
|
||||
}
|
||||
|
||||
override fun asString() = value
|
||||
override fun asString() = value
|
||||
|
||||
override fun toString() = "\"$value\""
|
||||
override fun toString() = "\"$value\""
|
||||
}
|
||||
|
||||
class UEnumEntryValueConstant(override val value: PsiEnumConstant, override val source: USimpleNameReferenceExpression? = null) : UAbstractConstant() {
|
||||
override fun equals(other: Any?) =
|
||||
other is UEnumEntryValueConstant &&
|
||||
value.nameIdentifier.text == other.value.nameIdentifier.text &&
|
||||
value.containingClass?.qualifiedName == other.value.containingClass?.qualifiedName
|
||||
class UEnumEntryValueConstant(override val value: PsiEnumConstant,
|
||||
override val source: USimpleNameReferenceExpression? = null) : UAbstractConstant() {
|
||||
override fun equals(other: Any?) =
|
||||
other is UEnumEntryValueConstant &&
|
||||
value.nameIdentifier.text == other.value.nameIdentifier.text &&
|
||||
value.containingClass?.qualifiedName == other.value.containingClass?.qualifiedName
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 19
|
||||
result = result * 13 + value.nameIdentifier.text.hashCode()
|
||||
result = result * 13 + (value.containingClass?.qualifiedName?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
override fun hashCode(): Int {
|
||||
var result = 19
|
||||
result = result * 13 + value.nameIdentifier.text.hashCode()
|
||||
result = result * 13 + (value.containingClass?.qualifiedName?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString() = value.name?.let { "$it (enum entry)" }?: "<unnamed enum entry>"
|
||||
override fun toString() = value.name?.let { "$it (enum entry)" } ?: "<unnamed enum entry>"
|
||||
|
||||
override fun asString() = value.name ?: ""
|
||||
override fun asString() = value.name ?: ""
|
||||
}
|
||||
|
||||
class UClassConstant(override val value: PsiType, override val source: UClassLiteralExpression? = null) : UAbstractConstant() {
|
||||
override fun toString() = value.name
|
||||
override fun toString() = value.name
|
||||
}
|
||||
|
||||
object UNullConstant : UAbstractConstant() {
|
||||
override val value = null
|
||||
override val source = null
|
||||
override val value = null
|
||||
override val source = null
|
||||
}
|
||||
|
||||
@@ -16,124 +16,124 @@
|
||||
package org.jetbrains.uast.values
|
||||
|
||||
open class UDependentValue protected constructor(
|
||||
val value: UValue,
|
||||
override val dependencies: Set<UDependency> = emptySet()
|
||||
val value: UValue,
|
||||
override val dependencies: Set<UDependency> = emptySet()
|
||||
) : UValueBase() {
|
||||
|
||||
private fun UValue.unwrap() = (this as? UDependentValue)?.unwrap() ?: this
|
||||
private fun UValue.unwrap() = (this as? UDependentValue)?.unwrap() ?: this
|
||||
|
||||
private fun unwrap(): UValue = value.unwrap()
|
||||
private fun unwrap(): UValue = value.unwrap()
|
||||
|
||||
private val dependenciesWithThis: Set<UDependency>
|
||||
get() = (this as? UDependency)?.let { dependencies + it } ?: dependencies
|
||||
private val dependenciesWithThis: Set<UDependency>
|
||||
get() = (this as? UDependency)?.let { dependencies + it } ?: dependencies
|
||||
|
||||
private fun wrapBinary(result: UValue, arg: UValue): UValue {
|
||||
val wrappedDependencies = (arg as? UDependentValue)?.dependenciesWithThis ?: emptySet()
|
||||
val resultDependencies = dependenciesWithThis + wrappedDependencies
|
||||
return create(result, resultDependencies)
|
||||
private fun wrapBinary(result: UValue, arg: UValue): UValue {
|
||||
val wrappedDependencies = (arg as? UDependentValue)?.dependenciesWithThis ?: emptySet()
|
||||
val resultDependencies = dependenciesWithThis + wrappedDependencies
|
||||
return create(result, resultDependencies)
|
||||
}
|
||||
|
||||
private fun wrapUnary(result: UValue) = create(result, dependenciesWithThis)
|
||||
|
||||
override fun plus(other: UValue) = wrapBinary(unwrap() + other.unwrap(), other)
|
||||
|
||||
override fun minus(other: UValue) = wrapBinary(unwrap() - other.unwrap(), other)
|
||||
|
||||
override fun times(other: UValue) = wrapBinary(unwrap() * other.unwrap(), other)
|
||||
|
||||
override fun div(other: UValue) = wrapBinary(unwrap() / other.unwrap(), other)
|
||||
|
||||
internal fun inverseDiv(other: UValue) = wrapBinary(other.unwrap() / unwrap(), other)
|
||||
|
||||
override fun mod(other: UValue) = wrapBinary(unwrap() % other.unwrap(), other)
|
||||
|
||||
internal fun inverseMod(other: UValue) = wrapBinary(other.unwrap() % unwrap(), other)
|
||||
|
||||
override fun unaryMinus() = wrapUnary(-unwrap())
|
||||
|
||||
override fun valueEquals(other: UValue) = wrapBinary(unwrap() valueEquals other.unwrap(), other)
|
||||
|
||||
override fun valueNotEquals(other: UValue) = wrapBinary(unwrap() valueNotEquals other.unwrap(), other)
|
||||
|
||||
override fun not() = wrapUnary(!unwrap())
|
||||
|
||||
override fun greater(other: UValue) = wrapBinary(unwrap() greater other.unwrap(), other)
|
||||
|
||||
override fun less(other: UValue) = wrapBinary(other.unwrap() greater unwrap(), other)
|
||||
|
||||
override fun inc() = wrapUnary(unwrap().inc())
|
||||
|
||||
override fun dec() = wrapUnary(unwrap().dec())
|
||||
|
||||
override fun and(other: UValue) = wrapBinary(unwrap() and other.unwrap(), other)
|
||||
|
||||
override fun or(other: UValue) = wrapBinary(unwrap() or other.unwrap(), other)
|
||||
|
||||
override fun bitwiseAnd(other: UValue) = wrapBinary(unwrap() bitwiseAnd other.unwrap(), other)
|
||||
|
||||
override fun bitwiseOr(other: UValue) = wrapBinary(unwrap() bitwiseOr other.unwrap(), other)
|
||||
|
||||
override fun bitwiseXor(other: UValue) = wrapBinary(unwrap() bitwiseXor other.unwrap(), other)
|
||||
|
||||
override fun shl(other: UValue) = wrapBinary(unwrap() shl other.unwrap(), other)
|
||||
|
||||
internal fun inverseShiftLeft(other: UValue) = wrapBinary(other.unwrap() shl unwrap(), other)
|
||||
|
||||
override fun shr(other: UValue) = wrapBinary(unwrap() shr other.unwrap(), other)
|
||||
|
||||
internal fun inverseShiftRight(other: UValue) = wrapBinary(other.unwrap() shr unwrap(), other)
|
||||
|
||||
override fun ushr(other: UValue) = wrapBinary(unwrap() ushr other.unwrap(), other)
|
||||
|
||||
internal fun inverseShiftRightUnsigned(other: UValue) =
|
||||
wrapBinary(other.unwrap() ushr unwrap(), other)
|
||||
|
||||
override fun merge(other: UValue) = when (other) {
|
||||
this -> this
|
||||
value -> this
|
||||
is UVariableValue -> other.merge(this)
|
||||
is UDependentValue -> {
|
||||
val allDependencies = dependencies + other.dependencies
|
||||
if (value != other.value) UDependentValue(value.merge(other.value), allDependencies)
|
||||
else UDependentValue(value, allDependencies)
|
||||
}
|
||||
else -> UPhiValue.create(this, other)
|
||||
}
|
||||
|
||||
private fun wrapUnary(result: UValue) = create(result, dependenciesWithThis)
|
||||
override fun toConstant() = value.toConstant()
|
||||
|
||||
override fun plus(other: UValue) = wrapBinary(unwrap() + other.unwrap(), other)
|
||||
open internal fun copy(dependencies: Set<UDependency>) =
|
||||
if (dependencies == this.dependencies) this else create(value, dependencies)
|
||||
|
||||
override fun minus(other: UValue) = wrapBinary(unwrap() - other.unwrap(), other)
|
||||
override fun coerceConstant(constant: UConstant): UValue =
|
||||
if (toConstant() == constant) this
|
||||
else create(value.coerceConstant(constant), dependencies)
|
||||
|
||||
override fun times(other: UValue) = wrapBinary(unwrap() * other.unwrap(), other)
|
||||
override fun equals(other: Any?) =
|
||||
other is UDependentValue
|
||||
&& javaClass == other.javaClass
|
||||
&& value == other.value
|
||||
&& dependencies == other.dependencies
|
||||
|
||||
override fun div(other: UValue) = wrapBinary(unwrap() / other.unwrap(), other)
|
||||
override fun hashCode(): Int {
|
||||
var result = 31
|
||||
result = result * 19 + value.hashCode()
|
||||
result = result * 19 + dependencies.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
internal fun inverseDiv(other: UValue) = wrapBinary(other.unwrap() / unwrap(), other)
|
||||
override fun toString() =
|
||||
if (dependencies.isNotEmpty())
|
||||
"$value" + dependencies.joinToString(prefix = " (depending on: ", postfix = ")", separator = ", ")
|
||||
else
|
||||
"$value"
|
||||
|
||||
override fun mod(other: UValue) = wrapBinary(unwrap() % other.unwrap(), other)
|
||||
companion object {
|
||||
fun create(value: UValue, dependencies: Set<UDependency>): UValue =
|
||||
if (dependencies.isNotEmpty()) UDependentValue(value, dependencies)
|
||||
else value
|
||||
|
||||
internal fun inverseMod(other: UValue) = wrapBinary(other.unwrap() % unwrap(), other)
|
||||
|
||||
override fun unaryMinus() = wrapUnary(-unwrap())
|
||||
|
||||
override fun valueEquals(other: UValue) = wrapBinary(unwrap() valueEquals other.unwrap(), other)
|
||||
|
||||
override fun valueNotEquals(other: UValue) = wrapBinary(unwrap() valueNotEquals other.unwrap(), other)
|
||||
|
||||
override fun not() = wrapUnary(!unwrap())
|
||||
|
||||
override fun greater(other: UValue) = wrapBinary(unwrap() greater other.unwrap(), other)
|
||||
|
||||
override fun less(other: UValue) = wrapBinary(other.unwrap() greater unwrap(), other)
|
||||
|
||||
override fun inc() = wrapUnary(unwrap().inc())
|
||||
|
||||
override fun dec() = wrapUnary(unwrap().dec())
|
||||
|
||||
override fun and(other: UValue) = wrapBinary(unwrap() and other.unwrap(), other)
|
||||
|
||||
override fun or(other: UValue) = wrapBinary(unwrap() or other.unwrap(), other)
|
||||
|
||||
override fun bitwiseAnd(other: UValue) = wrapBinary(unwrap() bitwiseAnd other.unwrap(), other)
|
||||
|
||||
override fun bitwiseOr(other: UValue) = wrapBinary(unwrap() bitwiseOr other.unwrap(), other)
|
||||
|
||||
override fun bitwiseXor(other: UValue) = wrapBinary(unwrap() bitwiseXor other.unwrap(), other)
|
||||
|
||||
override fun shl(other: UValue) = wrapBinary(unwrap() shl other.unwrap(), other)
|
||||
|
||||
internal fun inverseShiftLeft(other: UValue) = wrapBinary(other.unwrap() shl unwrap(), other)
|
||||
|
||||
override fun shr(other: UValue) = wrapBinary(unwrap() shr other.unwrap(), other)
|
||||
|
||||
internal fun inverseShiftRight(other: UValue) = wrapBinary(other.unwrap() shr unwrap(), other)
|
||||
|
||||
override fun ushr(other: UValue) = wrapBinary(unwrap() ushr other.unwrap(), other)
|
||||
|
||||
internal fun inverseShiftRightUnsigned(other: UValue) =
|
||||
wrapBinary(other.unwrap() ushr unwrap(), other)
|
||||
|
||||
override fun merge(other: UValue) = when (other) {
|
||||
this -> this
|
||||
value -> this
|
||||
is UVariableValue -> other.merge(this)
|
||||
is UDependentValue -> {
|
||||
val allDependencies = dependencies + other.dependencies
|
||||
if (value != other.value) UDependentValue(value.merge(other.value), allDependencies)
|
||||
else UDependentValue(value, allDependencies)
|
||||
}
|
||||
else -> UPhiValue.create(this, other)
|
||||
}
|
||||
|
||||
override fun toConstant() = value.toConstant()
|
||||
|
||||
open internal fun copy(dependencies: Set<UDependency>) =
|
||||
if (dependencies == this.dependencies) this else create(value, dependencies)
|
||||
|
||||
override fun coerceConstant(constant: UConstant): UValue =
|
||||
if (toConstant() == constant) this
|
||||
else create(value.coerceConstant(constant), dependencies)
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is UDependentValue
|
||||
&& javaClass == other.javaClass
|
||||
&& value == other.value
|
||||
&& dependencies == other.dependencies
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 31
|
||||
result = result * 19 + value.hashCode()
|
||||
result = result * 19 + dependencies.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString() =
|
||||
if (dependencies.isNotEmpty())
|
||||
"$value" + dependencies.joinToString(prefix = " (depending on: ", postfix = ")", separator = ", ")
|
||||
else
|
||||
"$value"
|
||||
|
||||
companion object {
|
||||
fun create(value: UValue, dependencies: Set<UDependency>): UValue =
|
||||
if (dependencies.isNotEmpty()) UDependentValue(value, dependencies)
|
||||
else value
|
||||
|
||||
internal fun UValue.coerceConstant(constant: UConstant): UValue =
|
||||
(this as? UValueBase)?.coerceConstant(constant) ?: constant
|
||||
}
|
||||
internal fun UValue.coerceConstant(constant: UConstant): UValue =
|
||||
(this as? UValueBase)?.coerceConstant(constant) ?: constant
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,61 +19,61 @@ import org.jetbrains.uast.*
|
||||
|
||||
// Something that never can be reached / created
|
||||
internal class UNothingValue private constructor(
|
||||
val containingLoopOrSwitch: UExpression?,
|
||||
val kind: JumpKind
|
||||
val containingLoopOrSwitch: UExpression?,
|
||||
val kind: JumpKind
|
||||
) : UValueBase() {
|
||||
|
||||
constructor(jump: UJumpExpression) : this(jump.containingLoopOrSwitch(), jump.kind())
|
||||
constructor(jump: UJumpExpression) : this(jump.containingLoopOrSwitch(), jump.kind())
|
||||
|
||||
constructor() : this(null, JumpKind.OTHER)
|
||||
constructor() : this(null, JumpKind.OTHER)
|
||||
|
||||
enum class JumpKind {
|
||||
BREAK,
|
||||
CONTINUE,
|
||||
OTHER;
|
||||
enum class JumpKind {
|
||||
BREAK,
|
||||
CONTINUE,
|
||||
OTHER;
|
||||
}
|
||||
|
||||
override val reachable = false
|
||||
|
||||
override fun merge(other: UValue) = when (other) {
|
||||
is UNothingValue -> {
|
||||
val mergedLoopOrSwitch =
|
||||
if (containingLoopOrSwitch == other.containingLoopOrSwitch) containingLoopOrSwitch
|
||||
else null
|
||||
val mergedKind = if (mergedLoopOrSwitch == null || kind != other.kind) JumpKind.OTHER else kind
|
||||
UNothingValue(mergedLoopOrSwitch, mergedKind)
|
||||
}
|
||||
else -> super.merge(other)
|
||||
}
|
||||
|
||||
override val reachable = false
|
||||
override fun toString() = "Nothing" + when (kind) {
|
||||
JumpKind.BREAK -> "(break)"
|
||||
JumpKind.CONTINUE -> "(continue)"
|
||||
else -> ""
|
||||
}
|
||||
|
||||
override fun merge(other: UValue) = when (other) {
|
||||
is UNothingValue -> {
|
||||
val mergedLoopOrSwitch =
|
||||
if (containingLoopOrSwitch == other.containingLoopOrSwitch) containingLoopOrSwitch
|
||||
else null
|
||||
val mergedKind = if (mergedLoopOrSwitch == null || kind != other.kind) JumpKind.OTHER else kind
|
||||
UNothingValue(mergedLoopOrSwitch, mergedKind)
|
||||
companion object {
|
||||
private fun UJumpExpression.containingLoopOrSwitch(): UExpression? {
|
||||
var containingElement = uastParent
|
||||
while (containingElement != null) {
|
||||
if (this is UBreakExpression && label == null && containingElement is USwitchExpression) {
|
||||
return containingElement
|
||||
}
|
||||
else -> super.merge(other)
|
||||
}
|
||||
|
||||
override fun toString() = "Nothing" + when (kind) {
|
||||
JumpKind.BREAK -> "(break)"
|
||||
JumpKind.CONTINUE -> "(continue)"
|
||||
else -> ""
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun UJumpExpression.containingLoopOrSwitch(): UExpression? {
|
||||
var containingElement = uastParent
|
||||
while (containingElement != null) {
|
||||
if (this is UBreakExpression && label == null && containingElement is USwitchExpression) {
|
||||
return containingElement
|
||||
}
|
||||
if (containingElement is ULoopExpression) {
|
||||
val containingLabeled = containingElement.uastParent as? ULabeledExpression
|
||||
if (label == null || label == containingLabeled?.label) {
|
||||
return containingElement
|
||||
}
|
||||
}
|
||||
containingElement = containingElement.uastParent
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun UExpression.kind(): JumpKind = when (this) {
|
||||
is UBreakExpression -> JumpKind.BREAK
|
||||
is UContinueExpression -> JumpKind.CONTINUE
|
||||
else -> JumpKind.OTHER
|
||||
if (containingElement is ULoopExpression) {
|
||||
val containingLabeled = containingElement.uastParent as? ULabeledExpression
|
||||
if (label == null || label == containingLabeled?.label) {
|
||||
return containingElement
|
||||
}
|
||||
}
|
||||
containingElement = containingElement.uastParent
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun UExpression.kind(): JumpKind = when (this) {
|
||||
is UBreakExpression -> JumpKind.BREAK
|
||||
is UContinueExpression -> JumpKind.CONTINUE
|
||||
else -> JumpKind.OTHER
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,53 +16,53 @@
|
||||
package org.jetbrains.uast.values
|
||||
|
||||
interface UOperand {
|
||||
operator fun plus(other: UValue): UValue
|
||||
operator fun plus(other: UValue): UValue
|
||||
|
||||
operator fun minus(other: UValue): UValue
|
||||
operator fun minus(other: UValue): UValue
|
||||
|
||||
operator fun times(other: UValue): UValue
|
||||
operator fun times(other: UValue): UValue
|
||||
|
||||
operator fun div(other: UValue): UValue
|
||||
operator fun div(other: UValue): UValue
|
||||
|
||||
operator fun mod(other: UValue): UValue
|
||||
operator fun mod(other: UValue): UValue
|
||||
|
||||
operator fun unaryMinus(): UValue
|
||||
operator fun unaryMinus(): UValue
|
||||
|
||||
operator fun not(): UValue
|
||||
operator fun not(): UValue
|
||||
|
||||
infix fun valueEquals(other: UValue): UValue
|
||||
infix fun valueEquals(other: UValue): UValue
|
||||
|
||||
infix fun valueNotEquals(other: UValue): UValue
|
||||
infix fun valueNotEquals(other: UValue): UValue
|
||||
|
||||
infix fun identityEquals(other: UValue): UValue
|
||||
infix fun identityEquals(other: UValue): UValue
|
||||
|
||||
infix fun identityNotEquals(other: UValue): UValue
|
||||
infix fun identityNotEquals(other: UValue): UValue
|
||||
|
||||
infix fun greater(other: UValue): UValue
|
||||
infix fun greater(other: UValue): UValue
|
||||
|
||||
infix fun less(other: UValue): UValue
|
||||
infix fun less(other: UValue): UValue
|
||||
|
||||
infix fun greaterOrEquals(other: UValue): UValue
|
||||
infix fun greaterOrEquals(other: UValue): UValue
|
||||
|
||||
infix fun lessOrEquals(other: UValue): UValue
|
||||
infix fun lessOrEquals(other: UValue): UValue
|
||||
|
||||
fun inc(): UValue
|
||||
fun inc(): UValue
|
||||
|
||||
fun dec(): UValue
|
||||
fun dec(): UValue
|
||||
|
||||
infix fun and(other: UValue): UValue
|
||||
infix fun and(other: UValue): UValue
|
||||
|
||||
infix fun or(other: UValue): UValue
|
||||
infix fun or(other: UValue): UValue
|
||||
|
||||
infix fun bitwiseAnd(other: UValue): UValue
|
||||
infix fun bitwiseAnd(other: UValue): UValue
|
||||
|
||||
infix fun bitwiseOr(other: UValue): UValue
|
||||
infix fun bitwiseOr(other: UValue): UValue
|
||||
|
||||
infix fun bitwiseXor(other: UValue): UValue
|
||||
infix fun bitwiseXor(other: UValue): UValue
|
||||
|
||||
infix fun shl(other: UValue): UValue
|
||||
infix fun shl(other: UValue): UValue
|
||||
|
||||
infix fun shr(other: UValue): UValue
|
||||
infix fun shr(other: UValue): UValue
|
||||
|
||||
infix fun ushr(other: UValue): UValue
|
||||
infix fun ushr(other: UValue): UValue
|
||||
}
|
||||
@@ -15,31 +15,31 @@
|
||||
*/
|
||||
package org.jetbrains.uast.values
|
||||
|
||||
class UPhiValue private constructor(val values: Set<UValue>): UValueBase() {
|
||||
class UPhiValue private constructor(val values: Set<UValue>) : UValueBase() {
|
||||
|
||||
override val dependencies: Set<UDependency> = values.flatMapTo(linkedSetOf()) { it.dependencies }
|
||||
override val dependencies: Set<UDependency> = values.flatMapTo(linkedSetOf()) { it.dependencies }
|
||||
|
||||
override fun equals(other: Any?) = other is UPhiValue && values == other.values
|
||||
override fun equals(other: Any?) = other is UPhiValue && values == other.values
|
||||
|
||||
override fun hashCode() = values.hashCode()
|
||||
override fun hashCode() = values.hashCode()
|
||||
|
||||
override fun toString() = values.joinToString(prefix = "Phi(", postfix = ")", separator = ", ")
|
||||
override fun toString() = values.joinToString(prefix = "Phi(", postfix = ")", separator = ", ")
|
||||
|
||||
companion object {
|
||||
private val PHI_LIMIT = 4
|
||||
companion object {
|
||||
private val PHI_LIMIT = 4
|
||||
|
||||
fun create(values: Iterable<UValue>): UValue {
|
||||
val flattenedValues = values.flatMapTo(linkedSetOf<UValue>()) { (it as? UPhiValue)?.values ?: listOf(it) }
|
||||
if (flattenedValues.size <= 1) {
|
||||
throw AssertionError("UPhiValue should contain two or more values: $flattenedValues")
|
||||
}
|
||||
if (flattenedValues.size > PHI_LIMIT || UUndeterminedValue in flattenedValues) {
|
||||
return UUndeterminedValue
|
||||
}
|
||||
return UPhiValue(flattenedValues)
|
||||
}
|
||||
|
||||
fun create(vararg values: UValue) = create(values.asIterable())
|
||||
fun create(values: Iterable<UValue>): UValue {
|
||||
val flattenedValues = values.flatMapTo(linkedSetOf<UValue>()) { (it as? UPhiValue)?.values ?: listOf(it) }
|
||||
if (flattenedValues.size <= 1) {
|
||||
throw AssertionError("UPhiValue should contain two or more values: $flattenedValues")
|
||||
}
|
||||
if (flattenedValues.size > PHI_LIMIT || UUndeterminedValue in flattenedValues) {
|
||||
return UUndeterminedValue
|
||||
}
|
||||
return UPhiValue(flattenedValues)
|
||||
}
|
||||
|
||||
fun create(vararg values: UValue) = create(values.asIterable())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.jetbrains.uast.values
|
||||
|
||||
// Something with value that cannot be evaluated
|
||||
object UUndeterminedValue : UValueBase() {
|
||||
override fun toString() = "Undetermined"
|
||||
override fun toString() = "Undetermined"
|
||||
}
|
||||
|
||||
fun UValue.ifUndetermined(block: () -> UValue) = if (this == UUndeterminedValue) block() else this
|
||||
|
||||
@@ -17,30 +17,30 @@ package org.jetbrains.uast.values
|
||||
|
||||
interface UValue : UOperand {
|
||||
|
||||
fun merge(other: UValue): UValue
|
||||
fun merge(other: UValue): UValue
|
||||
|
||||
val dependencies: Set<UDependency>
|
||||
get() = emptySet()
|
||||
val dependencies: Set<UDependency>
|
||||
get() = emptySet()
|
||||
|
||||
fun toConstant(): UConstant?
|
||||
fun toConstant(): UConstant?
|
||||
|
||||
val reachable: Boolean
|
||||
val reachable: Boolean
|
||||
|
||||
companion object {
|
||||
val UNREACHABLE: UValue = UNothingValue()
|
||||
}
|
||||
companion object {
|
||||
val UNREACHABLE: UValue = UNothingValue()
|
||||
}
|
||||
}
|
||||
|
||||
fun UValue.toPossibleConstants(): Set<UConstant> {
|
||||
val results = mutableSetOf<UConstant>()
|
||||
toPossibleConstants(results)
|
||||
return results
|
||||
val results = mutableSetOf<UConstant>()
|
||||
toPossibleConstants(results)
|
||||
return results
|
||||
}
|
||||
|
||||
private fun UValue.toPossibleConstants(result: MutableSet<UConstant>) {
|
||||
when (this) {
|
||||
is UDependentValue -> value.toPossibleConstants(result)
|
||||
is UPhiValue -> values.forEach { it.toPossibleConstants(result) }
|
||||
else -> toConstant()?.let { result.add(it) }
|
||||
}
|
||||
when (this) {
|
||||
is UDependentValue -> value.toPossibleConstants(result)
|
||||
is UPhiValue -> values.forEach { it.toPossibleConstants(result) }
|
||||
else -> toConstant()?.let { result.add(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,85 +17,85 @@ package org.jetbrains.uast.values
|
||||
|
||||
abstract class UValueBase : UValue {
|
||||
|
||||
override operator fun plus(other: UValue): UValue =
|
||||
if (other is UDependentValue) other + this else UUndeterminedValue
|
||||
override operator fun plus(other: UValue): UValue =
|
||||
if (other is UDependentValue) other + this else UUndeterminedValue
|
||||
|
||||
override operator fun minus(other: UValue): UValue = this + (-other)
|
||||
override operator fun minus(other: UValue): UValue = this + (-other)
|
||||
|
||||
override operator fun times(other: UValue): UValue =
|
||||
if (other is UDependentValue) other * this else UUndeterminedValue
|
||||
override operator fun times(other: UValue): UValue =
|
||||
if (other is UDependentValue) other * this else UUndeterminedValue
|
||||
|
||||
override operator fun div(other: UValue): UValue =
|
||||
(other as? UDependentValue)?.inverseDiv(this) ?: UUndeterminedValue
|
||||
override operator fun div(other: UValue): UValue =
|
||||
(other as? UDependentValue)?.inverseDiv(this) ?: UUndeterminedValue
|
||||
|
||||
override operator fun mod(other: UValue): UValue =
|
||||
(other as? UDependentValue)?.inverseMod(this) ?: UUndeterminedValue
|
||||
override operator fun mod(other: UValue): UValue =
|
||||
(other as? UDependentValue)?.inverseMod(this) ?: UUndeterminedValue
|
||||
|
||||
override fun unaryMinus(): UValue = UUndeterminedValue
|
||||
override fun unaryMinus(): UValue = UUndeterminedValue
|
||||
|
||||
override fun valueEquals(other: UValue): UValue =
|
||||
if (other is UDependentValue || other is UNaNConstant) other.valueEquals(this) else UUndeterminedValue
|
||||
override fun valueEquals(other: UValue): UValue =
|
||||
if (other is UDependentValue || other is UNaNConstant) other.valueEquals(this) else UUndeterminedValue
|
||||
|
||||
override fun valueNotEquals(other: UValue): UValue = !this.valueEquals(other)
|
||||
override fun valueNotEquals(other: UValue): UValue = !this.valueEquals(other)
|
||||
|
||||
override fun identityEquals(other: UValue): UValue = valueEquals(other)
|
||||
override fun identityEquals(other: UValue): UValue = valueEquals(other)
|
||||
|
||||
override fun identityNotEquals(other: UValue): UValue = !this.identityEquals(other)
|
||||
override fun identityNotEquals(other: UValue): UValue = !this.identityEquals(other)
|
||||
|
||||
override fun not(): UValue = UUndeterminedValue
|
||||
override fun not(): UValue = UUndeterminedValue
|
||||
|
||||
override fun greater(other: UValue): UValue =
|
||||
if (other is UDependentValue || other is UNaNConstant) other.less(this) else UUndeterminedValue
|
||||
override fun greater(other: UValue): UValue =
|
||||
if (other is UDependentValue || other is UNaNConstant) other.less(this) else UUndeterminedValue
|
||||
|
||||
override fun less(other: UValue): UValue = other.greater(this)
|
||||
override fun less(other: UValue): UValue = other.greater(this)
|
||||
|
||||
override fun greaterOrEquals(other: UValue) = this.greater(other) or this.valueEquals(other)
|
||||
override fun greaterOrEquals(other: UValue) = this.greater(other) or this.valueEquals(other)
|
||||
|
||||
override fun lessOrEquals(other: UValue) = this.less(other) or this.valueEquals(other)
|
||||
override fun lessOrEquals(other: UValue) = this.less(other) or this.valueEquals(other)
|
||||
|
||||
override fun inc(): UValue = UUndeterminedValue
|
||||
override fun inc(): UValue = UUndeterminedValue
|
||||
|
||||
override fun dec(): UValue = UUndeterminedValue
|
||||
override fun dec(): UValue = UUndeterminedValue
|
||||
|
||||
override fun and(other: UValue): UValue =
|
||||
if (other is UDependentValue || other == UBooleanConstant.False) other and this else UUndeterminedValue
|
||||
override fun and(other: UValue): UValue =
|
||||
if (other is UDependentValue || other == UBooleanConstant.False) other and this else UUndeterminedValue
|
||||
|
||||
override fun or(other: UValue): UValue =
|
||||
if (other is UDependentValue || other == UBooleanConstant.True) other or this else UUndeterminedValue
|
||||
override fun or(other: UValue): UValue =
|
||||
if (other is UDependentValue || other == UBooleanConstant.True) other or this else UUndeterminedValue
|
||||
|
||||
override fun bitwiseAnd(other: UValue): UValue =
|
||||
if (other is UDependentValue) other bitwiseAnd this else UUndeterminedValue
|
||||
override fun bitwiseAnd(other: UValue): UValue =
|
||||
if (other is UDependentValue) other bitwiseAnd this else UUndeterminedValue
|
||||
|
||||
override fun bitwiseOr(other: UValue): UValue =
|
||||
if (other is UDependentValue) other bitwiseOr this else UUndeterminedValue
|
||||
override fun bitwiseOr(other: UValue): UValue =
|
||||
if (other is UDependentValue) other bitwiseOr this else UUndeterminedValue
|
||||
|
||||
override fun bitwiseXor(other: UValue): UValue =
|
||||
if (other is UDependentValue) other bitwiseXor this else UUndeterminedValue
|
||||
override fun bitwiseXor(other: UValue): UValue =
|
||||
if (other is UDependentValue) other bitwiseXor this else UUndeterminedValue
|
||||
|
||||
override fun shl(other: UValue): UValue =
|
||||
(other as? UDependentValue)?.inverseShiftLeft(this) ?: UUndeterminedValue
|
||||
override fun shl(other: UValue): UValue =
|
||||
(other as? UDependentValue)?.inverseShiftLeft(this) ?: UUndeterminedValue
|
||||
|
||||
override fun shr(other: UValue): UValue =
|
||||
(other as? UDependentValue)?.inverseShiftRight(this) ?: UUndeterminedValue
|
||||
override fun shr(other: UValue): UValue =
|
||||
(other as? UDependentValue)?.inverseShiftRight(this) ?: UUndeterminedValue
|
||||
|
||||
override fun ushr(other: UValue): UValue =
|
||||
(other as? UDependentValue)?.inverseShiftRightUnsigned(this) ?: UUndeterminedValue
|
||||
override fun ushr(other: UValue): UValue =
|
||||
(other as? UDependentValue)?.inverseShiftRightUnsigned(this) ?: UUndeterminedValue
|
||||
|
||||
override fun merge(other: UValue): UValue = when (other) {
|
||||
this -> this
|
||||
is UDependentValue -> other.merge(this)
|
||||
is UCallResultValue -> other.merge(this)
|
||||
else -> UPhiValue.create(this, other)
|
||||
}
|
||||
override fun merge(other: UValue): UValue = when (other) {
|
||||
this -> this
|
||||
is UDependentValue -> other.merge(this)
|
||||
is UCallResultValue -> other.merge(this)
|
||||
else -> UPhiValue.create(this, other)
|
||||
}
|
||||
|
||||
override val dependencies: Set<UDependency>
|
||||
get() = emptySet()
|
||||
override val dependencies: Set<UDependency>
|
||||
get() = emptySet()
|
||||
|
||||
override fun toConstant(): UConstant? = this as? UConstant
|
||||
override fun toConstant(): UConstant? = this as? UConstant
|
||||
|
||||
internal open fun coerceConstant(constant: UConstant): UValue = constant
|
||||
internal open fun coerceConstant(constant: UConstant): UValue = constant
|
||||
|
||||
override val reachable = true
|
||||
override val reachable = true
|
||||
|
||||
override abstract fun toString(): String
|
||||
override abstract fun toString(): String
|
||||
}
|
||||
@@ -19,86 +19,86 @@ import com.intellij.psi.PsiType
|
||||
import org.jetbrains.uast.UVariable
|
||||
|
||||
class UVariableValue private constructor(
|
||||
val variable: UVariable,
|
||||
value: UValue,
|
||||
dependencies: Set<UDependency>
|
||||
val variable: UVariable,
|
||||
value: UValue,
|
||||
dependencies: Set<UDependency>
|
||||
) : UDependentValue(value, dependencies), UDependency {
|
||||
|
||||
override fun identityEquals(other: UValue): UValue =
|
||||
if (this == other) super.valueEquals(other)
|
||||
else when (variable.psi.type) {
|
||||
PsiType.BYTE, PsiType.FLOAT, PsiType.DOUBLE, PsiType.LONG,
|
||||
PsiType.SHORT, PsiType.INT, PsiType.CHAR, PsiType.BOOLEAN -> super.valueEquals(other)
|
||||
override fun identityEquals(other: UValue): UValue =
|
||||
if (this == other) super.valueEquals(other)
|
||||
else when (variable.psi.type) {
|
||||
PsiType.BYTE, PsiType.FLOAT, PsiType.DOUBLE, PsiType.LONG,
|
||||
PsiType.SHORT, PsiType.INT, PsiType.CHAR, PsiType.BOOLEAN -> super.valueEquals(other)
|
||||
|
||||
else -> UUndeterminedValue
|
||||
}
|
||||
else -> UUndeterminedValue
|
||||
}
|
||||
|
||||
override fun merge(other: UValue) = when (other) {
|
||||
this -> this
|
||||
value -> this
|
||||
is UDependentValue -> {
|
||||
val allDependencies = dependencies + other.dependencies
|
||||
when {
|
||||
other !is UVariableValue || variable != other.variable -> UPhiValue.create(this, other)
|
||||
value != other.value -> create(variable, value.merge(other.value), allDependencies)
|
||||
else -> create(variable, value, allDependencies)
|
||||
}
|
||||
override fun merge(other: UValue) = when (other) {
|
||||
this -> this
|
||||
value -> this
|
||||
is UDependentValue -> {
|
||||
val allDependencies = dependencies + other.dependencies
|
||||
when {
|
||||
other !is UVariableValue || variable != other.variable -> UPhiValue.create(this, other)
|
||||
value != other.value -> create(variable, value.merge(other.value), allDependencies)
|
||||
else -> create(variable, value, allDependencies)
|
||||
}
|
||||
}
|
||||
else -> UPhiValue.create(this, other)
|
||||
}
|
||||
|
||||
override fun copy(dependencies: Set<UDependency>) =
|
||||
if (dependencies == this.dependencies) this else create(variable, value, dependencies)
|
||||
|
||||
override fun coerceConstant(constant: UConstant): UValue =
|
||||
if (constant == toConstant()) this
|
||||
else create(variable, value.coerceConstant(constant), dependencies)
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is UVariableValue
|
||||
&& variable == other.variable
|
||||
&& value == other.value
|
||||
&& dependencies == other.dependencies
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 31
|
||||
result = result * 19 + variable.hashCode()
|
||||
result = result * 19 + value.hashCode()
|
||||
result = result * 19 + dependencies.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString() = "(var ${variable.name ?: "<unnamed>"} = ${super.toString()})"
|
||||
|
||||
companion object {
|
||||
|
||||
private fun Set<UDependency>.filterNot(variable: UVariable) =
|
||||
filterTo(linkedSetOf()) { it !is UVariableValue || variable != it.variable }
|
||||
|
||||
fun create(variable: UVariable, value: UValue, dependencies: Set<UDependency> = emptySet()): UVariableValue {
|
||||
when (variable.psi.type) {
|
||||
PsiType.BYTE, PsiType.SHORT -> {
|
||||
val constant = value.toConstant()
|
||||
if (constant is UIntConstant && constant.type == UNumericType.INT) {
|
||||
val castConstant = UIntConstant(constant.value, variable.psi.type)
|
||||
return create(variable, value.coerceConstant(castConstant), dependencies)
|
||||
}
|
||||
}
|
||||
else -> UPhiValue.create(this, other)
|
||||
}
|
||||
}
|
||||
val dependenciesWithoutSelf = dependencies.filterNot(variable)
|
||||
return when {
|
||||
value is UVariableValue
|
||||
&& variable == value.variable
|
||||
&& dependenciesWithoutSelf == value.dependencies -> value
|
||||
|
||||
override fun copy(dependencies: Set<UDependency>) =
|
||||
if (dependencies == this.dependencies) this else create(variable, value, dependencies)
|
||||
|
||||
override fun coerceConstant(constant: UConstant): UValue =
|
||||
if (constant == toConstant()) this
|
||||
else create(variable, value.coerceConstant(constant), dependencies)
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is UVariableValue
|
||||
&& variable == other.variable
|
||||
&& value == other.value
|
||||
&& dependencies == other.dependencies
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 31
|
||||
result = result * 19 + variable.hashCode()
|
||||
result = result * 19 + value.hashCode()
|
||||
result = result * 19 + dependencies.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString() = "(var ${variable.name ?: "<unnamed>"} = ${super.toString()})"
|
||||
|
||||
companion object {
|
||||
|
||||
private fun Set<UDependency>.filterNot(variable: UVariable) =
|
||||
filterTo(linkedSetOf()) { it !is UVariableValue || variable != it.variable }
|
||||
|
||||
fun create(variable: UVariable, value: UValue, dependencies: Set<UDependency> = emptySet()): UVariableValue {
|
||||
when (variable.psi.type) {
|
||||
PsiType.BYTE, PsiType.SHORT -> {
|
||||
val constant = value.toConstant()
|
||||
if (constant is UIntConstant && constant.type == UNumericType.INT) {
|
||||
val castConstant = UIntConstant(constant.value, variable.psi.type)
|
||||
return create(variable, value.coerceConstant(castConstant), dependencies)
|
||||
}
|
||||
}
|
||||
}
|
||||
val dependenciesWithoutSelf = dependencies.filterNot(variable)
|
||||
return when {
|
||||
value is UVariableValue
|
||||
&& variable == value.variable
|
||||
&& dependenciesWithoutSelf == value.dependencies -> value
|
||||
|
||||
value is UDependentValue -> {
|
||||
val valueDependencies = value.dependencies.filterNot(variable)
|
||||
val modifiedValue = value.copy(valueDependencies)
|
||||
UVariableValue(variable, modifiedValue, dependenciesWithoutSelf)
|
||||
}
|
||||
|
||||
else -> UVariableValue(variable, value, dependenciesWithoutSelf)
|
||||
}
|
||||
value is UDependentValue -> {
|
||||
val valueDependencies = value.dependencies.filterNot(variable)
|
||||
val modifiedValue = value.copy(valueDependencies)
|
||||
UVariableValue(variable, modifiedValue, dependenciesWithoutSelf)
|
||||
}
|
||||
|
||||
else -> UVariableValue(variable, value, dependenciesWithoutSelf)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,156 +19,156 @@ package org.jetbrains.uast.visitor
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
|
||||
class DelegatingUastVisitor(private val visitors: List<UastVisitor>): UastVisitor {
|
||||
override fun visitElement(node: UElement): Boolean {
|
||||
return visitors.all { it.visitElement(node) }
|
||||
}
|
||||
class DelegatingUastVisitor(private val visitors: List<UastVisitor>) : UastVisitor {
|
||||
override fun visitElement(node: UElement): Boolean {
|
||||
return visitors.all { it.visitElement(node) }
|
||||
}
|
||||
|
||||
override fun visitVariable(node: UVariable): Boolean {
|
||||
return visitors.all { it.visitVariable(node) }
|
||||
}
|
||||
override fun visitVariable(node: UVariable): Boolean {
|
||||
return visitors.all { it.visitVariable(node) }
|
||||
}
|
||||
|
||||
override fun visitMethod(node: UMethod): Boolean {
|
||||
return visitors.all { it.visitMethod(node) }
|
||||
}
|
||||
override fun visitMethod(node: UMethod): Boolean {
|
||||
return visitors.all { it.visitMethod(node) }
|
||||
}
|
||||
|
||||
override fun visitLabeledExpression(node: ULabeledExpression): Boolean {
|
||||
return visitors.all { it.visitLabeledExpression(node) }
|
||||
}
|
||||
override fun visitLabeledExpression(node: ULabeledExpression): Boolean {
|
||||
return visitors.all { it.visitLabeledExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitDeclarationsExpression(node: UDeclarationsExpression): Boolean {
|
||||
return visitors.all { it.visitDeclarationsExpression(node) }
|
||||
}
|
||||
override fun visitDeclarationsExpression(node: UDeclarationsExpression): Boolean {
|
||||
return visitors.all { it.visitDeclarationsExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitBlockExpression(node: UBlockExpression): Boolean {
|
||||
return visitors.all { it.visitBlockExpression(node) }
|
||||
}
|
||||
override fun visitBlockExpression(node: UBlockExpression): Boolean {
|
||||
return visitors.all { it.visitBlockExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitQualifiedReferenceExpression(node: UQualifiedReferenceExpression): Boolean {
|
||||
return visitors.all { it.visitQualifiedReferenceExpression(node) }
|
||||
}
|
||||
override fun visitQualifiedReferenceExpression(node: UQualifiedReferenceExpression): Boolean {
|
||||
return visitors.all { it.visitQualifiedReferenceExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression): Boolean {
|
||||
return visitors.all { it.visitSimpleNameReferenceExpression(node) }
|
||||
}
|
||||
override fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression): Boolean {
|
||||
return visitors.all { it.visitSimpleNameReferenceExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitTypeReferenceExpression(node: UTypeReferenceExpression): Boolean {
|
||||
return visitors.all { it.visitTypeReferenceExpression(node) }
|
||||
}
|
||||
override fun visitTypeReferenceExpression(node: UTypeReferenceExpression): Boolean {
|
||||
return visitors.all { it.visitTypeReferenceExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||
return visitors.all { it.visitCallExpression(node) }
|
||||
}
|
||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||
return visitors.all { it.visitCallExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitBinaryExpression(node: UBinaryExpression): Boolean {
|
||||
return visitors.all { it.visitBinaryExpression(node) }
|
||||
}
|
||||
override fun visitBinaryExpression(node: UBinaryExpression): Boolean {
|
||||
return visitors.all { it.visitBinaryExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType): Boolean {
|
||||
return visitors.all { it.visitBinaryExpressionWithType(node) }
|
||||
}
|
||||
override fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType): Boolean {
|
||||
return visitors.all { it.visitBinaryExpressionWithType(node) }
|
||||
}
|
||||
|
||||
override fun visitParenthesizedExpression(node: UParenthesizedExpression): Boolean {
|
||||
return visitors.all { it.visitParenthesizedExpression(node) }
|
||||
}
|
||||
override fun visitParenthesizedExpression(node: UParenthesizedExpression): Boolean {
|
||||
return visitors.all { it.visitParenthesizedExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitUnaryExpression(node: UUnaryExpression): Boolean {
|
||||
return visitors.all { it.visitUnaryExpression(node) }
|
||||
}
|
||||
override fun visitUnaryExpression(node: UUnaryExpression): Boolean {
|
||||
return visitors.all { it.visitUnaryExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitPrefixExpression(node: UPrefixExpression): Boolean {
|
||||
return visitors.all { it.visitPrefixExpression(node) }
|
||||
}
|
||||
override fun visitPrefixExpression(node: UPrefixExpression): Boolean {
|
||||
return visitors.all { it.visitPrefixExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitPostfixExpression(node: UPostfixExpression): Boolean {
|
||||
return visitors.all { it.visitPostfixExpression(node) }
|
||||
}
|
||||
override fun visitPostfixExpression(node: UPostfixExpression): Boolean {
|
||||
return visitors.all { it.visitPostfixExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitExpressionList(node: UExpressionList): Boolean {
|
||||
return visitors.all { it.visitExpressionList(node) }
|
||||
}
|
||||
override fun visitExpressionList(node: UExpressionList): Boolean {
|
||||
return visitors.all { it.visitExpressionList(node) }
|
||||
}
|
||||
|
||||
override fun visitIfExpression(node: UIfExpression): Boolean {
|
||||
return visitors.all { it.visitIfExpression(node) }
|
||||
}
|
||||
override fun visitIfExpression(node: UIfExpression): Boolean {
|
||||
return visitors.all { it.visitIfExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitSwitchExpression(node: USwitchExpression): Boolean {
|
||||
return visitors.all { it.visitSwitchExpression(node) }
|
||||
}
|
||||
override fun visitSwitchExpression(node: USwitchExpression): Boolean {
|
||||
return visitors.all { it.visitSwitchExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitSwitchClauseExpression(node: USwitchClauseExpression): Boolean {
|
||||
return visitors.all { it.visitSwitchClauseExpression(node) }
|
||||
}
|
||||
override fun visitSwitchClauseExpression(node: USwitchClauseExpression): Boolean {
|
||||
return visitors.all { it.visitSwitchClauseExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitWhileExpression(node: UWhileExpression): Boolean {
|
||||
return visitors.all { it.visitWhileExpression(node) }
|
||||
}
|
||||
override fun visitWhileExpression(node: UWhileExpression): Boolean {
|
||||
return visitors.all { it.visitWhileExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitDoWhileExpression(node: UDoWhileExpression): Boolean {
|
||||
return visitors.all { it.visitDoWhileExpression(node) }
|
||||
}
|
||||
override fun visitDoWhileExpression(node: UDoWhileExpression): Boolean {
|
||||
return visitors.all { it.visitDoWhileExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitForExpression(node: UForExpression): Boolean {
|
||||
return visitors.all { it.visitForExpression(node) }
|
||||
}
|
||||
override fun visitForExpression(node: UForExpression): Boolean {
|
||||
return visitors.all { it.visitForExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitForEachExpression(node: UForEachExpression): Boolean {
|
||||
return visitors.all { it.visitForEachExpression(node) }
|
||||
}
|
||||
override fun visitForEachExpression(node: UForEachExpression): Boolean {
|
||||
return visitors.all { it.visitForEachExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitTryExpression(node: UTryExpression): Boolean {
|
||||
return visitors.all { it.visitTryExpression(node) }
|
||||
}
|
||||
override fun visitTryExpression(node: UTryExpression): Boolean {
|
||||
return visitors.all { it.visitTryExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitCatchClause(node: UCatchClause): Boolean {
|
||||
return visitors.all { it.visitCatchClause(node) }
|
||||
}
|
||||
|
||||
override fun visitLiteralExpression(node: ULiteralExpression): Boolean {
|
||||
return visitors.all { it.visitLiteralExpression(node) }
|
||||
}
|
||||
override fun visitCatchClause(node: UCatchClause): Boolean {
|
||||
return visitors.all { it.visitCatchClause(node) }
|
||||
}
|
||||
|
||||
override fun visitThisExpression(node: UThisExpression): Boolean {
|
||||
return visitors.all { it.visitThisExpression(node) }
|
||||
}
|
||||
override fun visitLiteralExpression(node: ULiteralExpression): Boolean {
|
||||
return visitors.all { it.visitLiteralExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitSuperExpression(node: USuperExpression): Boolean {
|
||||
return visitors.all { it.visitSuperExpression(node) }
|
||||
}
|
||||
override fun visitThisExpression(node: UThisExpression): Boolean {
|
||||
return visitors.all { it.visitThisExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitReturnExpression(node: UReturnExpression): Boolean {
|
||||
return visitors.all { it.visitReturnExpression(node) }
|
||||
}
|
||||
override fun visitSuperExpression(node: USuperExpression): Boolean {
|
||||
return visitors.all { it.visitSuperExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitBreakExpression(node: UBreakExpression): Boolean {
|
||||
return visitors.all { it.visitBreakExpression(node) }
|
||||
}
|
||||
override fun visitReturnExpression(node: UReturnExpression): Boolean {
|
||||
return visitors.all { it.visitReturnExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitContinueExpression(node: UContinueExpression): Boolean {
|
||||
return visitors.all { it.visitContinueExpression(node) }
|
||||
}
|
||||
override fun visitBreakExpression(node: UBreakExpression): Boolean {
|
||||
return visitors.all { it.visitBreakExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitThrowExpression(node: UThrowExpression): Boolean {
|
||||
return visitors.all { it.visitThrowExpression(node) }
|
||||
}
|
||||
override fun visitContinueExpression(node: UContinueExpression): Boolean {
|
||||
return visitors.all { it.visitContinueExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitArrayAccessExpression(node: UArrayAccessExpression): Boolean {
|
||||
return visitors.all { it.visitArrayAccessExpression(node) }
|
||||
}
|
||||
override fun visitThrowExpression(node: UThrowExpression): Boolean {
|
||||
return visitors.all { it.visitThrowExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitCallableReferenceExpression(node: UCallableReferenceExpression): Boolean {
|
||||
return visitors.all { it.visitCallableReferenceExpression(node) }
|
||||
}
|
||||
override fun visitArrayAccessExpression(node: UArrayAccessExpression): Boolean {
|
||||
return visitors.all { it.visitArrayAccessExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitClassLiteralExpression(node: UClassLiteralExpression): Boolean {
|
||||
return visitors.all { it.visitClassLiteralExpression(node) }
|
||||
}
|
||||
override fun visitCallableReferenceExpression(node: UCallableReferenceExpression): Boolean {
|
||||
return visitors.all { it.visitCallableReferenceExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitLambdaExpression(node: ULambdaExpression): Boolean {
|
||||
return visitors.all { it.visitLambdaExpression(node) }
|
||||
}
|
||||
override fun visitClassLiteralExpression(node: UClassLiteralExpression): Boolean {
|
||||
return visitors.all { it.visitClassLiteralExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitObjectLiteralExpression(node: UObjectLiteralExpression): Boolean {
|
||||
return visitors.all { it.visitObjectLiteralExpression(node) }
|
||||
}
|
||||
override fun visitLambdaExpression(node: ULambdaExpression): Boolean {
|
||||
return visitors.all { it.visitLambdaExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitObjectLiteralExpression(node: UObjectLiteralExpression): Boolean {
|
||||
return visitors.all { it.visitObjectLiteralExpression(node) }
|
||||
}
|
||||
}
|
||||
@@ -18,67 +18,78 @@ package org.jetbrains.uast.visitor
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
interface UastTypedVisitor<in D, out R> {
|
||||
fun visitElement(node: UElement, data: D): R
|
||||
// Just elements
|
||||
fun visitFile(node: UFile, data: D): R = visitElement(node, data)
|
||||
fun visitImportStatement(node: UImportStatement, data: D): R = visitElement(node, data)
|
||||
fun visitAnnotation(node: UAnnotation, data: D): R = visitElement(node, data)
|
||||
fun visitCatchClause(node: UCatchClause, data: D) = visitElement(node, data)
|
||||
// Declarations
|
||||
fun visitDeclaration(node: UDeclaration, data: D) = visitElement(node, data)
|
||||
fun visitClass(node: UClass, data: D): R = visitDeclaration(node, data)
|
||||
fun visitMethod(node: UMethod, data: D): R = visitDeclaration(node, data)
|
||||
fun visitClassInitializer(node: UClassInitializer, data: D): R = visitDeclaration(node, data)
|
||||
// Variables
|
||||
fun visitVariable(node: UVariable, data: D): R = visitDeclaration(node, data)
|
||||
fun visitParameter(node: UParameter, data: D): R = visitVariable(node, data)
|
||||
fun visitField(node: UField, data: D): R = visitVariable(node, data)
|
||||
fun visitLocalVariable(node: ULocalVariable, data: D): R = visitVariable(node, data)
|
||||
fun visitEnumConstantExpression(node: UEnumConstant, data: D) = visitVariable(node, data)
|
||||
// Expressions
|
||||
fun visitExpression(node: UExpression, data: D) = visitElement(node, data)
|
||||
fun visitLabeledExpression(node: ULabeledExpression, data: D) = visitExpression(node, data)
|
||||
fun visitDeclarationsExpression(node: UDeclarationsExpression, data: D) = visitExpression(node, data)
|
||||
fun visitBlockExpression(node: UBlockExpression, data: D) = visitExpression(node, data)
|
||||
fun visitTypeReferenceExpression(node: UTypeReferenceExpression, data: D) = visitExpression(node, data)
|
||||
fun visitExpressionList(node: UExpressionList, data: D) = visitExpression(node, data)
|
||||
fun visitLiteralExpression(node: ULiteralExpression, data: D) = visitExpression(node, data)
|
||||
fun visitThisExpression(node: UThisExpression, data: D) = visitExpression(node, data)
|
||||
fun visitSuperExpression(node: USuperExpression, data: D) = visitExpression(node, data)
|
||||
fun visitArrayAccessExpression(node: UArrayAccessExpression, data: D) = visitExpression(node, data)
|
||||
fun visitClassLiteralExpression(node: UClassLiteralExpression, data: D) = visitExpression(node, data)
|
||||
fun visitLambdaExpression(node: ULambdaExpression, data: D) = visitExpression(node, data)
|
||||
fun visitPolyadicExpression(node: UPolyadicExpression, data: D) = visitExpression(node, data)
|
||||
// Calls
|
||||
fun visitCallExpression(node: UCallExpression, data: D) = visitExpression(node, data)
|
||||
fun visitObjectLiteralExpression(node: UObjectLiteralExpression, data: D) = visitCallExpression(node, data)
|
||||
// Operations
|
||||
fun visitBinaryExpression(node: UBinaryExpression, data: D) = visitPolyadicExpression(node, data)
|
||||
fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType, data: D) = visitExpression(node, data)
|
||||
fun visitParenthesizedExpression(node: UParenthesizedExpression, data: D) = visitExpression(node, data)
|
||||
// Unary operations
|
||||
fun visitUnaryExpression(node: UUnaryExpression, data: D) = visitExpression(node, data)
|
||||
fun visitPrefixExpression(node: UPrefixExpression, data: D) = visitUnaryExpression(node, data)
|
||||
fun visitPostfixExpression(node: UPostfixExpression, data: D) = visitUnaryExpression(node, data)
|
||||
// References
|
||||
fun visitReferenceExpression(node: UReferenceExpression, data: D) = visitExpression(node, data)
|
||||
fun visitQualifiedReferenceExpression(node: UQualifiedReferenceExpression, data: D) = visitReferenceExpression(node, data)
|
||||
fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression, data: D) = visitReferenceExpression(node, data)
|
||||
fun visitCallableReferenceExpression(node: UCallableReferenceExpression, data: D) = visitReferenceExpression(node, data)
|
||||
// Control structures
|
||||
fun visitIfExpression(node: UIfExpression, data: D) = visitExpression(node, data)
|
||||
fun visitSwitchExpression(node: USwitchExpression, data: D) = visitExpression(node, data)
|
||||
fun visitSwitchClauseExpression(node: USwitchClauseExpression, data: D) = visitExpression(node, data)
|
||||
fun visitTryExpression(node: UTryExpression, data: D) = visitExpression(node, data)
|
||||
// Jumps
|
||||
fun visitReturnExpression(node: UReturnExpression, data: D) = visitExpression(node, data)
|
||||
fun visitBreakExpression(node: UBreakExpression, data: D) = visitExpression(node, data)
|
||||
fun visitContinueExpression(node: UContinueExpression, data: D) = visitExpression(node, data)
|
||||
fun visitThrowExpression(node: UThrowExpression, data: D) = visitExpression(node, data)
|
||||
// Loops
|
||||
fun visitLoopExpression(node: ULoopExpression, data: D) = visitExpression(node, data)
|
||||
fun visitWhileExpression(node: UWhileExpression, data: D) = visitLoopExpression(node, data)
|
||||
fun visitDoWhileExpression(node: UDoWhileExpression, data: D) = visitLoopExpression(node, data)
|
||||
fun visitForExpression(node: UForExpression, data: D) = visitLoopExpression(node, data)
|
||||
fun visitForEachExpression(node: UForEachExpression, data: D) = visitLoopExpression(node, data)
|
||||
fun visitElement(node: UElement, data: D): R
|
||||
// Just elements
|
||||
fun visitFile(node: UFile, data: D): R = visitElement(node, data)
|
||||
|
||||
fun visitImportStatement(node: UImportStatement, data: D): R = visitElement(node, data)
|
||||
fun visitAnnotation(node: UAnnotation, data: D): R = visitElement(node, data)
|
||||
fun visitCatchClause(node: UCatchClause, data: D) = visitElement(node, data)
|
||||
// Declarations
|
||||
fun visitDeclaration(node: UDeclaration, data: D) = visitElement(node, data)
|
||||
|
||||
fun visitClass(node: UClass, data: D): R = visitDeclaration(node, data)
|
||||
fun visitMethod(node: UMethod, data: D): R = visitDeclaration(node, data)
|
||||
fun visitClassInitializer(node: UClassInitializer, data: D): R = visitDeclaration(node, data)
|
||||
// Variables
|
||||
fun visitVariable(node: UVariable, data: D): R = visitDeclaration(node, data)
|
||||
|
||||
fun visitParameter(node: UParameter, data: D): R = visitVariable(node, data)
|
||||
fun visitField(node: UField, data: D): R = visitVariable(node, data)
|
||||
fun visitLocalVariable(node: ULocalVariable, data: D): R = visitVariable(node, data)
|
||||
fun visitEnumConstantExpression(node: UEnumConstant, data: D) = visitVariable(node, data)
|
||||
// Expressions
|
||||
fun visitExpression(node: UExpression, data: D) = visitElement(node, data)
|
||||
|
||||
fun visitLabeledExpression(node: ULabeledExpression, data: D) = visitExpression(node, data)
|
||||
fun visitDeclarationsExpression(node: UDeclarationsExpression, data: D) = visitExpression(node, data)
|
||||
fun visitBlockExpression(node: UBlockExpression, data: D) = visitExpression(node, data)
|
||||
fun visitTypeReferenceExpression(node: UTypeReferenceExpression, data: D) = visitExpression(node, data)
|
||||
fun visitExpressionList(node: UExpressionList, data: D) = visitExpression(node, data)
|
||||
fun visitLiteralExpression(node: ULiteralExpression, data: D) = visitExpression(node, data)
|
||||
fun visitThisExpression(node: UThisExpression, data: D) = visitExpression(node, data)
|
||||
fun visitSuperExpression(node: USuperExpression, data: D) = visitExpression(node, data)
|
||||
fun visitArrayAccessExpression(node: UArrayAccessExpression, data: D) = visitExpression(node, data)
|
||||
fun visitClassLiteralExpression(node: UClassLiteralExpression, data: D) = visitExpression(node, data)
|
||||
fun visitLambdaExpression(node: ULambdaExpression, data: D) = visitExpression(node, data)
|
||||
fun visitPolyadicExpression(node: UPolyadicExpression, data: D) = visitExpression(node, data)
|
||||
// Calls
|
||||
fun visitCallExpression(node: UCallExpression, data: D) = visitExpression(node, data)
|
||||
|
||||
fun visitObjectLiteralExpression(node: UObjectLiteralExpression, data: D) = visitCallExpression(node, data)
|
||||
// Operations
|
||||
fun visitBinaryExpression(node: UBinaryExpression, data: D) = visitPolyadicExpression(node, data)
|
||||
|
||||
fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType, data: D) = visitExpression(node, data)
|
||||
fun visitParenthesizedExpression(node: UParenthesizedExpression, data: D) = visitExpression(node, data)
|
||||
// Unary operations
|
||||
fun visitUnaryExpression(node: UUnaryExpression, data: D) = visitExpression(node, data)
|
||||
|
||||
fun visitPrefixExpression(node: UPrefixExpression, data: D) = visitUnaryExpression(node, data)
|
||||
fun visitPostfixExpression(node: UPostfixExpression, data: D) = visitUnaryExpression(node, data)
|
||||
// References
|
||||
fun visitReferenceExpression(node: UReferenceExpression, data: D) = visitExpression(node, data)
|
||||
|
||||
fun visitQualifiedReferenceExpression(node: UQualifiedReferenceExpression, data: D) = visitReferenceExpression(node, data)
|
||||
fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression, data: D) = visitReferenceExpression(node, data)
|
||||
fun visitCallableReferenceExpression(node: UCallableReferenceExpression, data: D) = visitReferenceExpression(node, data)
|
||||
// Control structures
|
||||
fun visitIfExpression(node: UIfExpression, data: D) = visitExpression(node, data)
|
||||
|
||||
fun visitSwitchExpression(node: USwitchExpression, data: D) = visitExpression(node, data)
|
||||
fun visitSwitchClauseExpression(node: USwitchClauseExpression, data: D) = visitExpression(node, data)
|
||||
fun visitTryExpression(node: UTryExpression, data: D) = visitExpression(node, data)
|
||||
// Jumps
|
||||
fun visitReturnExpression(node: UReturnExpression, data: D) = visitExpression(node, data)
|
||||
|
||||
fun visitBreakExpression(node: UBreakExpression, data: D) = visitExpression(node, data)
|
||||
fun visitContinueExpression(node: UContinueExpression, data: D) = visitExpression(node, data)
|
||||
fun visitThrowExpression(node: UThrowExpression, data: D) = visitExpression(node, data)
|
||||
// Loops
|
||||
fun visitLoopExpression(node: ULoopExpression, data: D) = visitExpression(node, data)
|
||||
|
||||
fun visitWhileExpression(node: UWhileExpression, data: D) = visitLoopExpression(node, data)
|
||||
fun visitDoWhileExpression(node: UDoWhileExpression, data: D) = visitLoopExpression(node, data)
|
||||
fun visitForExpression(node: UForExpression, data: D) = visitLoopExpression(node, data)
|
||||
fun visitForEachExpression(node: UForEachExpression, data: D) = visitLoopExpression(node, data)
|
||||
}
|
||||
@@ -18,117 +18,257 @@ package org.jetbrains.uast.visitor
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
interface UastVisitor {
|
||||
fun visitElement(node: UElement): Boolean
|
||||
|
||||
fun visitFile(node: UFile): Boolean = visitElement(node)
|
||||
fun visitImportStatement(node: UImportStatement): Boolean = visitElement(node)
|
||||
fun visitClass(node: UClass): Boolean = visitElement(node)
|
||||
fun visitInitializer(node: UClassInitializer): Boolean = visitElement(node)
|
||||
fun visitMethod(node: UMethod): Boolean = visitElement(node)
|
||||
fun visitVariable(node: UVariable): Boolean = visitElement(node)
|
||||
fun visitParameter(node: UParameter): Boolean = visitVariable(node)
|
||||
fun visitField(node: UField): Boolean = visitVariable(node)
|
||||
fun visitLocalVariable(node: ULocalVariable): Boolean = visitVariable(node)
|
||||
fun visitEnumConstant(node: UEnumConstant): Boolean = visitField(node)
|
||||
fun visitElement(node: UElement): Boolean
|
||||
|
||||
fun visitAnnotation(node: UAnnotation): Boolean = visitElement(node)
|
||||
fun visitFile(node: UFile): Boolean = visitElement(node)
|
||||
fun visitImportStatement(node: UImportStatement): Boolean = visitElement(node)
|
||||
fun visitClass(node: UClass): Boolean = visitElement(node)
|
||||
fun visitInitializer(node: UClassInitializer): Boolean = visitElement(node)
|
||||
fun visitMethod(node: UMethod): Boolean = visitElement(node)
|
||||
fun visitVariable(node: UVariable): Boolean = visitElement(node)
|
||||
fun visitParameter(node: UParameter): Boolean = visitVariable(node)
|
||||
fun visitField(node: UField): Boolean = visitVariable(node)
|
||||
fun visitLocalVariable(node: ULocalVariable): Boolean = visitVariable(node)
|
||||
fun visitEnumConstant(node: UEnumConstant): Boolean = visitField(node)
|
||||
|
||||
// Expressions
|
||||
fun visitLabeledExpression(node: ULabeledExpression) = visitElement(node)
|
||||
fun visitDeclarationsExpression(node: UDeclarationsExpression) = visitElement(node)
|
||||
fun visitBlockExpression(node: UBlockExpression) = visitElement(node)
|
||||
fun visitQualifiedReferenceExpression(node: UQualifiedReferenceExpression) = visitElement(node)
|
||||
fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression) = visitElement(node)
|
||||
fun visitTypeReferenceExpression(node: UTypeReferenceExpression) = visitElement(node)
|
||||
fun visitCallExpression(node: UCallExpression) = visitElement(node)
|
||||
fun visitBinaryExpression(node: UBinaryExpression) = visitElement(node)
|
||||
fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType) = visitElement(node)
|
||||
fun visitPolyadicExpression(node: UPolyadicExpression) = visitElement(node)
|
||||
fun visitParenthesizedExpression(node: UParenthesizedExpression) = visitElement(node)
|
||||
fun visitUnaryExpression(node: UUnaryExpression) = visitElement(node)
|
||||
fun visitPrefixExpression(node: UPrefixExpression) = visitElement(node)
|
||||
fun visitPostfixExpression(node: UPostfixExpression) = visitElement(node)
|
||||
fun visitExpressionList(node: UExpressionList) = visitElement(node)
|
||||
fun visitIfExpression(node: UIfExpression) = visitElement(node)
|
||||
fun visitSwitchExpression(node: USwitchExpression) = visitElement(node)
|
||||
fun visitSwitchClauseExpression(node: USwitchClauseExpression) = visitElement(node)
|
||||
fun visitWhileExpression(node: UWhileExpression) = visitElement(node)
|
||||
fun visitDoWhileExpression(node: UDoWhileExpression) = visitElement(node)
|
||||
fun visitForExpression(node: UForExpression) = visitElement(node)
|
||||
fun visitForEachExpression(node: UForEachExpression) = visitElement(node)
|
||||
fun visitTryExpression(node: UTryExpression) = visitElement(node)
|
||||
fun visitCatchClause(node: UCatchClause) = visitElement(node)
|
||||
fun visitLiteralExpression(node: ULiteralExpression) = visitElement(node)
|
||||
fun visitThisExpression(node: UThisExpression) = visitElement(node)
|
||||
fun visitSuperExpression(node: USuperExpression) = visitElement(node)
|
||||
fun visitReturnExpression(node: UReturnExpression) = visitElement(node)
|
||||
fun visitBreakExpression(node: UBreakExpression) = visitElement(node)
|
||||
fun visitContinueExpression(node: UContinueExpression) = visitElement(node)
|
||||
fun visitThrowExpression(node: UThrowExpression) = visitElement(node)
|
||||
fun visitArrayAccessExpression(node: UArrayAccessExpression) = visitElement(node)
|
||||
fun visitCallableReferenceExpression(node: UCallableReferenceExpression) = visitElement(node)
|
||||
fun visitClassLiteralExpression(node: UClassLiteralExpression) = visitElement(node)
|
||||
fun visitLambdaExpression(node: ULambdaExpression) = visitElement(node)
|
||||
fun visitObjectLiteralExpression(node: UObjectLiteralExpression) = visitElement(node)
|
||||
fun visitAnnotation(node: UAnnotation): Boolean = visitElement(node)
|
||||
|
||||
// After
|
||||
// Expressions
|
||||
fun visitLabeledExpression(node: ULabeledExpression) = visitElement(node)
|
||||
|
||||
fun afterVisitElement(node: UElement) {}
|
||||
fun visitDeclarationsExpression(node: UDeclarationsExpression) = visitElement(node)
|
||||
fun visitBlockExpression(node: UBlockExpression) = visitElement(node)
|
||||
fun visitQualifiedReferenceExpression(node: UQualifiedReferenceExpression) = visitElement(node)
|
||||
fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression) = visitElement(node)
|
||||
fun visitTypeReferenceExpression(node: UTypeReferenceExpression) = visitElement(node)
|
||||
fun visitCallExpression(node: UCallExpression) = visitElement(node)
|
||||
fun visitBinaryExpression(node: UBinaryExpression) = visitElement(node)
|
||||
fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType) = visitElement(node)
|
||||
fun visitPolyadicExpression(node: UPolyadicExpression) = visitElement(node)
|
||||
fun visitParenthesizedExpression(node: UParenthesizedExpression) = visitElement(node)
|
||||
fun visitUnaryExpression(node: UUnaryExpression) = visitElement(node)
|
||||
fun visitPrefixExpression(node: UPrefixExpression) = visitElement(node)
|
||||
fun visitPostfixExpression(node: UPostfixExpression) = visitElement(node)
|
||||
fun visitExpressionList(node: UExpressionList) = visitElement(node)
|
||||
fun visitIfExpression(node: UIfExpression) = visitElement(node)
|
||||
fun visitSwitchExpression(node: USwitchExpression) = visitElement(node)
|
||||
fun visitSwitchClauseExpression(node: USwitchClauseExpression) = visitElement(node)
|
||||
fun visitWhileExpression(node: UWhileExpression) = visitElement(node)
|
||||
fun visitDoWhileExpression(node: UDoWhileExpression) = visitElement(node)
|
||||
fun visitForExpression(node: UForExpression) = visitElement(node)
|
||||
fun visitForEachExpression(node: UForEachExpression) = visitElement(node)
|
||||
fun visitTryExpression(node: UTryExpression) = visitElement(node)
|
||||
fun visitCatchClause(node: UCatchClause) = visitElement(node)
|
||||
fun visitLiteralExpression(node: ULiteralExpression) = visitElement(node)
|
||||
fun visitThisExpression(node: UThisExpression) = visitElement(node)
|
||||
fun visitSuperExpression(node: USuperExpression) = visitElement(node)
|
||||
fun visitReturnExpression(node: UReturnExpression) = visitElement(node)
|
||||
fun visitBreakExpression(node: UBreakExpression) = visitElement(node)
|
||||
fun visitContinueExpression(node: UContinueExpression) = visitElement(node)
|
||||
fun visitThrowExpression(node: UThrowExpression) = visitElement(node)
|
||||
fun visitArrayAccessExpression(node: UArrayAccessExpression) = visitElement(node)
|
||||
fun visitCallableReferenceExpression(node: UCallableReferenceExpression) = visitElement(node)
|
||||
fun visitClassLiteralExpression(node: UClassLiteralExpression) = visitElement(node)
|
||||
fun visitLambdaExpression(node: ULambdaExpression) = visitElement(node)
|
||||
fun visitObjectLiteralExpression(node: UObjectLiteralExpression) = visitElement(node)
|
||||
|
||||
fun afterVisitFile(node: UFile) { afterVisitElement(node) }
|
||||
fun afterVisitImportStatement(node: UImportStatement) { afterVisitElement(node) }
|
||||
fun afterVisitClass(node: UClass) { afterVisitElement(node) }
|
||||
fun afterVisitInitializer(node: UClassInitializer) { afterVisitElement(node) }
|
||||
fun afterVisitMethod(node: UMethod) { afterVisitElement(node) }
|
||||
fun afterVisitVariable(node: UVariable) { afterVisitElement(node) }
|
||||
fun afterVisitParameter(node: UParameter){ afterVisitVariable(node) }
|
||||
fun afterVisitField(node: UField){ afterVisitVariable(node) }
|
||||
fun afterVisitLocalVariable(node: ULocalVariable){ afterVisitVariable(node) }
|
||||
fun afterVisitEnumConstant(node: UEnumConstant){ afterVisitField(node) }
|
||||
fun afterVisitAnnotation(node: UAnnotation) { afterVisitElement(node) }
|
||||
// After
|
||||
|
||||
// Expressions
|
||||
fun afterVisitLabeledExpression(node: ULabeledExpression) { afterVisitElement(node) }
|
||||
fun afterVisitDeclarationsExpression(node: UDeclarationsExpression) { afterVisitElement(node) }
|
||||
fun afterVisitBlockExpression(node: UBlockExpression) { afterVisitElement(node) }
|
||||
fun afterVisitQualifiedReferenceExpression(node: UQualifiedReferenceExpression) { afterVisitElement(node) }
|
||||
fun afterVisitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression) { afterVisitElement(node) }
|
||||
fun afterVisitTypeReferenceExpression(node: UTypeReferenceExpression) { afterVisitElement(node) }
|
||||
fun afterVisitCallExpression(node: UCallExpression) { afterVisitElement(node) }
|
||||
fun afterVisitBinaryExpression(node: UBinaryExpression) { afterVisitElement(node) }
|
||||
fun afterVisitBinaryExpressionWithType(node: UBinaryExpressionWithType) { afterVisitElement(node) }
|
||||
fun afterVisitParenthesizedExpression(node: UParenthesizedExpression) { afterVisitElement(node) }
|
||||
fun afterVisitUnaryExpression(node: UUnaryExpression) { afterVisitElement(node) }
|
||||
fun afterVisitPrefixExpression(node: UPrefixExpression) { afterVisitElement(node) }
|
||||
fun afterVisitPostfixExpression(node: UPostfixExpression) { afterVisitElement(node) }
|
||||
fun afterVisitExpressionList(node: UExpressionList) { afterVisitElement(node) }
|
||||
fun afterVisitIfExpression(node: UIfExpression) { afterVisitElement(node) }
|
||||
fun afterVisitSwitchExpression(node: USwitchExpression) { afterVisitElement(node) }
|
||||
fun afterVisitSwitchClauseExpression(node: USwitchClauseExpression) { afterVisitElement(node) }
|
||||
fun afterVisitWhileExpression(node: UWhileExpression) { afterVisitElement(node) }
|
||||
fun afterVisitDoWhileExpression(node: UDoWhileExpression) { afterVisitElement(node) }
|
||||
fun afterVisitForExpression(node: UForExpression) { afterVisitElement(node) }
|
||||
fun afterVisitForEachExpression(node: UForEachExpression) { afterVisitElement(node) }
|
||||
fun afterVisitTryExpression(node: UTryExpression) { afterVisitElement(node) }
|
||||
fun afterVisitCatchClause(node: UCatchClause) { afterVisitElement(node) }
|
||||
fun afterVisitLiteralExpression(node: ULiteralExpression) { afterVisitElement(node) }
|
||||
fun afterVisitThisExpression(node: UThisExpression) { afterVisitElement(node) }
|
||||
fun afterVisitSuperExpression(node: USuperExpression) { afterVisitElement(node) }
|
||||
fun afterVisitReturnExpression(node: UReturnExpression) { afterVisitElement(node) }
|
||||
fun afterVisitBreakExpression(node: UBreakExpression) { afterVisitElement(node) }
|
||||
fun afterVisitContinueExpression(node: UContinueExpression) { afterVisitElement(node) }
|
||||
fun afterVisitThrowExpression(node: UThrowExpression) { afterVisitElement(node) }
|
||||
fun afterVisitArrayAccessExpression(node: UArrayAccessExpression) { afterVisitElement(node) }
|
||||
fun afterVisitCallableReferenceExpression(node: UCallableReferenceExpression) { afterVisitElement(node) }
|
||||
fun afterVisitClassLiteralExpression(node: UClassLiteralExpression) { afterVisitElement(node) }
|
||||
fun afterVisitLambdaExpression(node: ULambdaExpression) { afterVisitElement(node) }
|
||||
fun afterVisitObjectLiteralExpression(node: UObjectLiteralExpression) { afterVisitElement(node) }
|
||||
fun afterVisitPolyadicExpression(node: UPolyadicExpression) { afterVisitElement(node) }
|
||||
fun afterVisitElement(node: UElement) {}
|
||||
|
||||
fun afterVisitFile(node: UFile) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitImportStatement(node: UImportStatement) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitClass(node: UClass) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitInitializer(node: UClassInitializer) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitMethod(node: UMethod) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitVariable(node: UVariable) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitParameter(node: UParameter) {
|
||||
afterVisitVariable(node)
|
||||
}
|
||||
|
||||
fun afterVisitField(node: UField) {
|
||||
afterVisitVariable(node)
|
||||
}
|
||||
|
||||
fun afterVisitLocalVariable(node: ULocalVariable) {
|
||||
afterVisitVariable(node)
|
||||
}
|
||||
|
||||
fun afterVisitEnumConstant(node: UEnumConstant) {
|
||||
afterVisitField(node)
|
||||
}
|
||||
|
||||
fun afterVisitAnnotation(node: UAnnotation) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
// Expressions
|
||||
fun afterVisitLabeledExpression(node: ULabeledExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitDeclarationsExpression(node: UDeclarationsExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitBlockExpression(node: UBlockExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitQualifiedReferenceExpression(node: UQualifiedReferenceExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitTypeReferenceExpression(node: UTypeReferenceExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitCallExpression(node: UCallExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitBinaryExpression(node: UBinaryExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitBinaryExpressionWithType(node: UBinaryExpressionWithType) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitParenthesizedExpression(node: UParenthesizedExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitUnaryExpression(node: UUnaryExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitPrefixExpression(node: UPrefixExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitPostfixExpression(node: UPostfixExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitExpressionList(node: UExpressionList) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitIfExpression(node: UIfExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitSwitchExpression(node: USwitchExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitSwitchClauseExpression(node: USwitchClauseExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitWhileExpression(node: UWhileExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitDoWhileExpression(node: UDoWhileExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitForExpression(node: UForExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitForEachExpression(node: UForEachExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitTryExpression(node: UTryExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitCatchClause(node: UCatchClause) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitLiteralExpression(node: ULiteralExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitThisExpression(node: UThisExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitSuperExpression(node: USuperExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitReturnExpression(node: UReturnExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitBreakExpression(node: UBreakExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitContinueExpression(node: UContinueExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitThrowExpression(node: UThrowExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitArrayAccessExpression(node: UArrayAccessExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitCallableReferenceExpression(node: UCallableReferenceExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitClassLiteralExpression(node: UClassLiteralExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitLambdaExpression(node: ULambdaExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitObjectLiteralExpression(node: UObjectLiteralExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
|
||||
fun afterVisitPolyadicExpression(node: UPolyadicExpression) {
|
||||
afterVisitElement(node)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractUastVisitor : UastVisitor {
|
||||
override fun visitElement(node: UElement): Boolean = false
|
||||
|
||||
override fun visitElement(node: UElement): Boolean = false
|
||||
|
||||
}
|
||||
|
||||
object EmptyUastVisitor : AbstractUastVisitor()
|
||||
@@ -23,67 +23,67 @@ import org.jetbrains.uast.java.internal.JavaUElementWithComments
|
||||
|
||||
abstract class JavaAbstractUElement(givenParent: UElement?) : JavaUElementWithComments, JvmDeclarationUElement {
|
||||
|
||||
@Suppress("unused") // Used in Kotlin 1.2, to be removed in 2018.1
|
||||
@Deprecated("use JavaAbstractUElement(givenParent)", ReplaceWith("JavaAbstractUElement(givenParent)"))
|
||||
constructor() : this(null)
|
||||
@Suppress("unused") // Used in Kotlin 1.2, to be removed in 2018.1
|
||||
@Deprecated("use JavaAbstractUElement(givenParent)", ReplaceWith("JavaAbstractUElement(givenParent)"))
|
||||
constructor() : this(null)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is UElement || other.javaClass != this.javaClass) return false
|
||||
return if (this.psi != null) this.psi == other.psi else this === other
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is UElement || other.javaClass != this.javaClass) return false
|
||||
return if (this.psi != null) this.psi == other.psi else this === other
|
||||
}
|
||||
|
||||
override fun hashCode() = psi?.hashCode() ?: System.identityHashCode(this)
|
||||
|
||||
override fun asSourceString(): String {
|
||||
return this.psi?.text ?: super<JavaUElementWithComments>.asSourceString()
|
||||
}
|
||||
|
||||
override fun toString() = asRenderString()
|
||||
|
||||
override val uastParent: UElement? by lz { givenParent ?: convertParent() }
|
||||
|
||||
protected open fun convertParent(): UElement? =
|
||||
getPsiParentForLazyConversion()?.let { JavaConverter.unwrapElements(it).toUElement() }?.also {
|
||||
if (it === this) throw IllegalStateException("lazy parent loop for $this")
|
||||
if (it.psi != null && it.psi === this.psi) throw IllegalStateException(
|
||||
"lazy parent loop: psi ${this.psi}(${this.psi?.javaClass}) for $this of ${this.javaClass}")
|
||||
}
|
||||
|
||||
override fun hashCode() = psi?.hashCode() ?: System.identityHashCode(this)
|
||||
protected open fun getPsiParentForLazyConversion() = this.psi?.parent
|
||||
|
||||
override fun asSourceString(): String {
|
||||
return this.psi?.text ?: super<JavaUElementWithComments>.asSourceString()
|
||||
}
|
||||
//explicitly overridden in abstract class to be binary compatible with Kotlin
|
||||
override val comments: List<UComment>
|
||||
get() = super<JavaUElementWithComments>.comments
|
||||
override val sourcePsi: PsiElement?
|
||||
get() = super.sourcePsi
|
||||
override val javaPsi: PsiElement?
|
||||
get() = super.javaPsi
|
||||
|
||||
override fun toString() = asRenderString()
|
||||
|
||||
override val uastParent: UElement? by lz { givenParent ?: convertParent() }
|
||||
|
||||
protected open fun convertParent(): UElement? =
|
||||
getPsiParentForLazyConversion()?.let { JavaConverter.unwrapElements(it).toUElement() }?.also {
|
||||
if (it === this) throw IllegalStateException("lazy parent loop for $this")
|
||||
if (it.psi != null && it.psi === this.psi) throw IllegalStateException(
|
||||
"lazy parent loop: psi ${this.psi}(${this.psi?.javaClass}) for $this of ${this.javaClass}")
|
||||
}
|
||||
|
||||
protected open fun getPsiParentForLazyConversion() = this.psi?.parent
|
||||
|
||||
//explicitly overridden in abstract class to be binary compatible with Kotlin
|
||||
override val comments: List<UComment>
|
||||
get() = super<JavaUElementWithComments>.comments
|
||||
override val sourcePsi: PsiElement?
|
||||
get() = super.sourcePsi
|
||||
override val javaPsi: PsiElement?
|
||||
get() = super.javaPsi
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
abstract class JavaAbstractUExpression(givenParent: UElement?) : JavaAbstractUElement(givenParent), UExpression {
|
||||
|
||||
@Suppress("unused") // Used in Kotlin 1.2, to be removed in 2018.1
|
||||
@Deprecated("use JavaAbstractUExpression(givenParent)", ReplaceWith("JavaAbstractUExpression(givenParent)"))
|
||||
constructor() : this(null)
|
||||
@Suppress("unused") // Used in Kotlin 1.2, to be removed in 2018.1
|
||||
@Deprecated("use JavaAbstractUExpression(givenParent)", ReplaceWith("JavaAbstractUExpression(givenParent)"))
|
||||
constructor() : this(null)
|
||||
|
||||
override fun evaluate(): Any? {
|
||||
val project = psi?.project ?: return null
|
||||
return JavaPsiFacade.getInstance(project).constantEvaluationHelper.computeConstantExpression(psi)
|
||||
}
|
||||
override fun evaluate(): Any? {
|
||||
val project = psi?.project ?: return null
|
||||
return JavaPsiFacade.getInstance(project).constantEvaluationHelper.computeConstantExpression(psi)
|
||||
}
|
||||
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
|
||||
override fun getExpressionType(): PsiType? {
|
||||
val expression = psi as? PsiExpression ?: return null
|
||||
return expression.type
|
||||
}
|
||||
override fun getExpressionType(): PsiType? {
|
||||
val expression = psi as? PsiExpression ?: return null
|
||||
return expression.type
|
||||
}
|
||||
|
||||
override fun getPsiParentForLazyConversion(): PsiElement? = super.getPsiParentForLazyConversion()?.let {
|
||||
when (it) {
|
||||
is PsiResourceExpression -> it.parent
|
||||
else -> it
|
||||
}
|
||||
override fun getPsiParentForLazyConversion(): PsiElement? = super.getPsiParentForLazyConversion()?.let {
|
||||
when (it) {
|
||||
is PsiResourceExpression -> it.parent
|
||||
else -> it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,307 +24,318 @@ import org.jetbrains.uast.java.expressions.JavaUNamedExpression
|
||||
import org.jetbrains.uast.java.expressions.JavaUSynchronizedExpression
|
||||
|
||||
class JavaUastLanguagePlugin : UastLanguagePlugin {
|
||||
override val priority = 0
|
||||
override val priority = 0
|
||||
|
||||
override fun isFileSupported(fileName: String) = fileName.endsWith(".java", ignoreCase = true)
|
||||
override fun isFileSupported(fileName: String) = fileName.endsWith(".java", ignoreCase = true)
|
||||
|
||||
override val language: Language
|
||||
get() = JavaLanguage.INSTANCE
|
||||
override val language: Language
|
||||
get() = JavaLanguage.INSTANCE
|
||||
|
||||
override fun isExpressionValueUsed(element: UExpression): Boolean = when (element) {
|
||||
is JavaUDeclarationsExpression -> false
|
||||
is UnknownJavaExpression -> (element.uastParent as? UExpression)?.let { isExpressionValueUsed(it) } ?: false
|
||||
else -> {
|
||||
val statement = element.psi as? PsiStatement
|
||||
statement != null && statement.parent !is PsiExpressionStatement
|
||||
override fun isExpressionValueUsed(element: UExpression): Boolean = when (element) {
|
||||
is JavaUDeclarationsExpression -> false
|
||||
is UnknownJavaExpression -> (element.uastParent as? UExpression)?.let { isExpressionValueUsed(it) } ?: false
|
||||
else -> {
|
||||
val statement = element.psi as? PsiStatement
|
||||
statement != null && statement.parent !is PsiExpressionStatement
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMethodCallExpression(
|
||||
element: PsiElement,
|
||||
containingClassFqName: String?,
|
||||
methodName: String
|
||||
): UastLanguagePlugin.ResolvedMethod? {
|
||||
if (element !is PsiMethodCallExpression) return null
|
||||
if (element.methodExpression.referenceName != methodName) return null
|
||||
|
||||
val uElement = convertElementWithParent(element, null)
|
||||
val callExpression = when (uElement) {
|
||||
is UCallExpression -> uElement
|
||||
is UQualifiedReferenceExpression -> uElement.selector as UCallExpression
|
||||
else -> error("Invalid element type: $uElement")
|
||||
}
|
||||
|
||||
val method = callExpression.resolve() ?: return null
|
||||
if (containingClassFqName != null) {
|
||||
val containingClass = method.containingClass ?: return null
|
||||
if (containingClass.qualifiedName != containingClassFqName) return null
|
||||
}
|
||||
|
||||
return UastLanguagePlugin.ResolvedMethod(callExpression, method)
|
||||
}
|
||||
|
||||
override fun getConstructorCallExpression(
|
||||
element: PsiElement,
|
||||
fqName: String
|
||||
): UastLanguagePlugin.ResolvedConstructor? {
|
||||
if (element !is PsiNewExpression) return null
|
||||
val simpleName = fqName.substringAfterLast('.')
|
||||
if (element.classReference?.referenceName != simpleName) return null
|
||||
|
||||
val callExpression = convertElementWithParent(element, null) as? UCallExpression ?: return null
|
||||
|
||||
val constructorMethod = element.resolveConstructor() ?: return null
|
||||
val containingClass = constructorMethod.containingClass ?: return null
|
||||
if (containingClass.qualifiedName != fqName) return null
|
||||
|
||||
return UastLanguagePlugin.ResolvedConstructor(callExpression, constructorMethod, containingClass)
|
||||
}
|
||||
|
||||
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
if (element !is PsiElement) return null
|
||||
return convertDeclaration(element, parent, requiredType) ?:
|
||||
JavaConverter.convertPsiElement(element, parent, requiredType)
|
||||
}
|
||||
|
||||
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
|
||||
if (element !is PsiElement) return null
|
||||
if (element is PsiJavaFile) return requiredType.el<UFile> { JavaUFile(element, this) }
|
||||
JavaConverter.getCached<UElement>(element)?.let { return it }
|
||||
|
||||
return convertDeclaration(element, null, requiredType) ?:
|
||||
JavaConverter.convertPsiElement(element, null, requiredType)
|
||||
}
|
||||
|
||||
private fun convertDeclaration(element: PsiElement,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>?): UElement? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? {
|
||||
return fun(): UElement? {
|
||||
return ctor(element as P, givenParent)
|
||||
}
|
||||
}
|
||||
|
||||
if (element.isValid) element.getUserData(JAVA_CACHED_UELEMENT_KEY)?.let { ref ->
|
||||
ref.get()?.let { return it }
|
||||
}
|
||||
|
||||
return with(requiredType) {
|
||||
when (element) {
|
||||
is PsiJavaFile -> el<UFile> { JavaUFile(element, this@JavaUastLanguagePlugin) }
|
||||
is UDeclaration -> el<UDeclaration> { element }
|
||||
is PsiClass -> el<UClass> {
|
||||
JavaUClass.create(element, givenParent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMethodCallExpression(
|
||||
element: PsiElement,
|
||||
containingClassFqName: String?,
|
||||
methodName: String
|
||||
): UastLanguagePlugin.ResolvedMethod? {
|
||||
if (element !is PsiMethodCallExpression) return null
|
||||
if (element.methodExpression.referenceName != methodName) return null
|
||||
|
||||
val uElement = convertElementWithParent(element, null)
|
||||
val callExpression = when (uElement) {
|
||||
is UCallExpression -> uElement
|
||||
is UQualifiedReferenceExpression -> uElement.selector as UCallExpression
|
||||
else -> error("Invalid element type: $uElement")
|
||||
is PsiMethod -> el<UMethod> {
|
||||
JavaUMethod.create(element, this@JavaUastLanguagePlugin, givenParent)
|
||||
}
|
||||
|
||||
val method = callExpression.resolve() ?: return null
|
||||
if (containingClassFqName != null) {
|
||||
val containingClass = method.containingClass ?: return null
|
||||
if (containingClass.qualifiedName != containingClassFqName) return null
|
||||
}
|
||||
|
||||
return UastLanguagePlugin.ResolvedMethod(callExpression, method)
|
||||
}
|
||||
|
||||
override fun getConstructorCallExpression(
|
||||
element: PsiElement,
|
||||
fqName: String
|
||||
): UastLanguagePlugin.ResolvedConstructor? {
|
||||
if (element !is PsiNewExpression) return null
|
||||
val simpleName = fqName.substringAfterLast('.')
|
||||
if (element.classReference?.referenceName != simpleName) return null
|
||||
|
||||
val callExpression = convertElementWithParent(element, null) as? UCallExpression ?: return null
|
||||
|
||||
val constructorMethod = element.resolveConstructor() ?: return null
|
||||
val containingClass = constructorMethod.containingClass ?: return null
|
||||
if (containingClass.qualifiedName != fqName) return null
|
||||
|
||||
return UastLanguagePlugin.ResolvedConstructor(callExpression, constructorMethod, containingClass)
|
||||
}
|
||||
|
||||
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
if (element !is PsiElement) return null
|
||||
return convertDeclaration(element, parent, requiredType) ?:
|
||||
JavaConverter.convertPsiElement(element, parent, requiredType)
|
||||
}
|
||||
|
||||
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
|
||||
if (element !is PsiElement) return null
|
||||
if (element is PsiJavaFile) return requiredType.el<UFile> { JavaUFile(element, this) }
|
||||
JavaConverter.getCached<UElement>(element)?.let { return it }
|
||||
|
||||
return convertDeclaration(element, null, requiredType) ?:
|
||||
JavaConverter.convertPsiElement(element, null, requiredType)
|
||||
}
|
||||
|
||||
private fun convertDeclaration(element: PsiElement,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>?): UElement? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? {
|
||||
return fun(): UElement? {
|
||||
return ctor(element as P, givenParent)
|
||||
}
|
||||
}
|
||||
|
||||
if (element.isValid) element.getUserData(JAVA_CACHED_UELEMENT_KEY)?.let { ref ->
|
||||
ref.get()?.let { return it }
|
||||
}
|
||||
|
||||
return with (requiredType) { when (element) {
|
||||
is PsiJavaFile -> el<UFile> { JavaUFile(element, this@JavaUastLanguagePlugin) }
|
||||
is UDeclaration -> el<UDeclaration> { element }
|
||||
is PsiClass -> el<UClass> {
|
||||
JavaUClass.create(element, givenParent)
|
||||
}
|
||||
is PsiMethod -> el<UMethod> {
|
||||
JavaUMethod.create(element, this@JavaUastLanguagePlugin, givenParent)
|
||||
}
|
||||
is PsiClassInitializer -> el<UClassInitializer>(build(::JavaUClassInitializer))
|
||||
is PsiEnumConstant -> el<UEnumConstant>(build(::JavaUEnumConstant))
|
||||
is PsiLocalVariable -> el<ULocalVariable>(build(::JavaULocalVariable))
|
||||
is PsiParameter -> el<UParameter>(build(::JavaUParameter))
|
||||
is PsiField -> el<UField>(build(::JavaUField))
|
||||
is PsiVariable -> el<UVariable>(build(::JavaUVariable))
|
||||
is PsiAnnotation -> el<UAnnotation>(build(::JavaUAnnotation))
|
||||
else -> null
|
||||
}}
|
||||
is PsiClassInitializer -> el<UClassInitializer>(build(::JavaUClassInitializer))
|
||||
is PsiEnumConstant -> el<UEnumConstant>(build(::JavaUEnumConstant))
|
||||
is PsiLocalVariable -> el<ULocalVariable>(build(::JavaULocalVariable))
|
||||
is PsiParameter -> el<UParameter>(build(::JavaUParameter))
|
||||
is PsiField -> el<UField>(build(::JavaUField))
|
||||
is PsiVariable -> el<UVariable>(build(::JavaUVariable))
|
||||
is PsiAnnotation -> el<UAnnotation>(build(::JavaUAnnotation))
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun <reified ActualT : UElement> Class<out UElement>?.el(f: () -> UElement?): UElement? {
|
||||
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
|
||||
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
internal inline fun <reified ActualT : UElement> Class<out UElement>?.expr(f: () -> UExpression?): UExpression? {
|
||||
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
|
||||
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
private fun UElement?.toCallback() = if (this != null) fun(): UElement? { return this } else null
|
||||
|
||||
internal object JavaConverter {
|
||||
internal inline fun <reified T : UElement> getCached(element: PsiElement): T? {
|
||||
return null
|
||||
//todo
|
||||
internal inline fun <reified T : UElement> getCached(element: PsiElement): T? {
|
||||
return null
|
||||
//todo
|
||||
}
|
||||
|
||||
internal tailrec fun unwrapElements(element: PsiElement?): PsiElement? = when (element) {
|
||||
is PsiExpressionStatement -> unwrapElements(element.parent)
|
||||
is PsiParameterList -> unwrapElements(element.parent)
|
||||
is PsiAnnotationParameterList -> unwrapElements(element.parent)
|
||||
is PsiModifierList -> unwrapElements(element.parent)
|
||||
is PsiExpressionList -> unwrapElements(element.parent)
|
||||
is PsiPackageStatement -> unwrapElements(element.parent)
|
||||
else -> element
|
||||
}
|
||||
|
||||
internal fun convertPsiElement(el: PsiElement,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null): UElement? {
|
||||
getCached<UElement>(el)?.let { return it }
|
||||
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? {
|
||||
return fun(): UElement? {
|
||||
return ctor(el as P, givenParent)
|
||||
}
|
||||
}
|
||||
|
||||
internal tailrec fun unwrapElements(element: PsiElement?): PsiElement? = when (element) {
|
||||
is PsiExpressionStatement -> unwrapElements(element.parent)
|
||||
is PsiParameterList -> unwrapElements(element.parent)
|
||||
is PsiAnnotationParameterList -> unwrapElements(element.parent)
|
||||
is PsiModifierList -> unwrapElements(element.parent)
|
||||
is PsiExpressionList -> unwrapElements(element.parent)
|
||||
is PsiPackageStatement -> unwrapElements(element.parent)
|
||||
else -> element
|
||||
}
|
||||
|
||||
internal fun convertPsiElement(el: PsiElement,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null): UElement? {
|
||||
getCached<UElement>(el)?.let { return it }
|
||||
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? {
|
||||
return fun(): UElement? {
|
||||
return ctor(el as P, givenParent)
|
||||
}
|
||||
return with(requiredType) {
|
||||
when (el) {
|
||||
is PsiCodeBlock -> el<UBlockExpression>(build(::JavaUCodeBlockExpression))
|
||||
is PsiResourceExpression -> convertExpression(el.expression, givenParent, requiredType)
|
||||
is PsiExpression -> convertExpression(el, givenParent, requiredType)
|
||||
is PsiStatement -> convertStatement(el, givenParent, requiredType)
|
||||
is PsiIdentifier -> el<USimpleNameReferenceExpression> {
|
||||
JavaUSimpleNameReferenceExpression(el, el.text, givenParent)
|
||||
}
|
||||
|
||||
return with (requiredType) { when (el) {
|
||||
is PsiCodeBlock -> el<UBlockExpression>(build(::JavaUCodeBlockExpression))
|
||||
is PsiResourceExpression -> convertExpression(el.expression, givenParent, requiredType)
|
||||
is PsiExpression -> convertExpression(el, givenParent, requiredType)
|
||||
is PsiStatement -> convertStatement(el, givenParent, requiredType)
|
||||
is PsiIdentifier -> el<USimpleNameReferenceExpression> {
|
||||
JavaUSimpleNameReferenceExpression(el, el.text, givenParent)
|
||||
}
|
||||
is PsiNameValuePair -> el<UNamedExpression>(build(::JavaUNamedExpression))
|
||||
is PsiArrayInitializerMemberValue -> el<UCallExpression>(build(::JavaAnnotationArrayInitializerUCallExpression))
|
||||
is PsiTypeElement -> el<UTypeReferenceExpression>(build(::JavaUTypeReferenceExpression))
|
||||
is PsiJavaCodeReferenceElement -> convertReference(el, givenParent, requiredType)
|
||||
else -> null
|
||||
}}
|
||||
is PsiNameValuePair -> el<UNamedExpression>(build(::JavaUNamedExpression))
|
||||
is PsiArrayInitializerMemberValue -> el<UCallExpression>(build(::JavaAnnotationArrayInitializerUCallExpression))
|
||||
is PsiTypeElement -> el<UTypeReferenceExpression>(build(::JavaUTypeReferenceExpression))
|
||||
is PsiJavaCodeReferenceElement -> convertReference(el, givenParent, requiredType)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convertBlock(block: PsiCodeBlock, parent: UElement?): UBlockExpression =
|
||||
getCached(block) ?: JavaUCodeBlockExpression(block, parent)
|
||||
}
|
||||
|
||||
internal fun convertReference(reference: PsiJavaCodeReferenceElement, givenParent: UElement?, requiredType: Class<out UElement>?): UExpression? {
|
||||
return with (requiredType) {
|
||||
if (reference.isQualified) {
|
||||
expr<UQualifiedReferenceExpression> { JavaUQualifiedReferenceExpression(reference, givenParent) }
|
||||
} else {
|
||||
val name = reference.referenceName ?: "<error name>"
|
||||
expr<USimpleNameReferenceExpression> { JavaUSimpleNameReferenceExpression(reference, name, givenParent, reference) }
|
||||
}
|
||||
internal fun convertBlock(block: PsiCodeBlock, parent: UElement?): UBlockExpression =
|
||||
getCached(block) ?: JavaUCodeBlockExpression(block, parent)
|
||||
|
||||
internal fun convertReference(reference: PsiJavaCodeReferenceElement,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>?): UExpression? {
|
||||
return with(requiredType) {
|
||||
if (reference.isQualified) {
|
||||
expr<UQualifiedReferenceExpression> { JavaUQualifiedReferenceExpression(reference, givenParent) }
|
||||
}
|
||||
else {
|
||||
val name = reference.referenceName ?: "<error name>"
|
||||
expr<USimpleNameReferenceExpression> { JavaUSimpleNameReferenceExpression(reference, name, givenParent, reference) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convertExpression(el: PsiExpression,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null): UExpression? {
|
||||
getCached<UExpression>(el)?.let { return it }
|
||||
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UExpression): () -> UExpression? {
|
||||
return fun(): UExpression? {
|
||||
return ctor(el as P, givenParent)
|
||||
}
|
||||
}
|
||||
|
||||
return with(requiredType) {
|
||||
when (el) {
|
||||
is PsiAssignmentExpression -> expr<UBinaryExpression>(build(::JavaUAssignmentExpression))
|
||||
is PsiConditionalExpression -> expr<UIfExpression>(build(::JavaUTernaryIfExpression))
|
||||
is PsiNewExpression -> {
|
||||
if (el.anonymousClass != null)
|
||||
expr<UObjectLiteralExpression>(build(::JavaUObjectLiteralExpression))
|
||||
else
|
||||
expr<UCallExpression>(build(::JavaConstructorUCallExpression))
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convertExpression(el: PsiExpression,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null): UExpression? {
|
||||
getCached<UExpression>(el)?.let { return it }
|
||||
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UExpression): () -> UExpression? {
|
||||
return fun(): UExpression? {
|
||||
return ctor(el as P, givenParent)
|
||||
is PsiMethodCallExpression -> {
|
||||
if (el.methodExpression.qualifierExpression != null) {
|
||||
if (requiredType == null ||
|
||||
requiredType.isAssignableFrom(UQualifiedReferenceExpression::class.java) ||
|
||||
requiredType.isAssignableFrom(UCallExpression::class.java)) {
|
||||
val expr = JavaUCompositeQualifiedExpression(el, givenParent).apply {
|
||||
receiverInitializer = { convertOrEmpty(el.methodExpression.qualifierExpression!!, this) }
|
||||
selector = JavaUCallExpression(el, this)
|
||||
}
|
||||
if (requiredType?.isAssignableFrom(UCallExpression::class.java) == true)
|
||||
expr.selector
|
||||
else
|
||||
expr
|
||||
}
|
||||
else
|
||||
null
|
||||
}
|
||||
else
|
||||
expr<UCallExpression>(build(::JavaUCallExpression))
|
||||
}
|
||||
is PsiArrayInitializerExpression -> expr<UCallExpression>(build(::JavaArrayInitializerUCallExpression))
|
||||
is PsiBinaryExpression -> expr<UBinaryExpression>(build(::JavaUBinaryExpression))
|
||||
// Should go after PsiBinaryExpression since it implements PsiPolyadicExpression
|
||||
is PsiPolyadicExpression -> expr<UPolyadicExpression>(build(::JavaUPolyadicExpression))
|
||||
is PsiParenthesizedExpression -> expr<UParenthesizedExpression>(build(::JavaUParenthesizedExpression))
|
||||
is PsiPrefixExpression -> expr<UPrefixExpression>(build(::JavaUPrefixExpression))
|
||||
is PsiPostfixExpression -> expr<UPostfixExpression>(build(::JavaUPostfixExpression))
|
||||
is PsiLiteralExpression -> expr<ULiteralExpression>(build(::JavaULiteralExpression))
|
||||
is PsiMethodReferenceExpression -> expr<UCallableReferenceExpression>(build(::JavaUCallableReferenceExpression))
|
||||
is PsiReferenceExpression -> convertReference(el, givenParent, requiredType)
|
||||
is PsiThisExpression -> expr<UThisExpression>(build(::JavaUThisExpression))
|
||||
is PsiSuperExpression -> expr<USuperExpression>(build(::JavaUSuperExpression))
|
||||
is PsiInstanceOfExpression -> expr<UBinaryExpressionWithType>(build(::JavaUInstanceCheckExpression))
|
||||
is PsiTypeCastExpression -> expr<UBinaryExpressionWithType>(build(::JavaUTypeCastExpression))
|
||||
is PsiClassObjectAccessExpression -> expr<UClassLiteralExpression>(build(::JavaUClassLiteralExpression))
|
||||
is PsiArrayAccessExpression -> expr<UArrayAccessExpression>(build(::JavaUArrayAccessExpression))
|
||||
is PsiLambdaExpression -> expr<ULambdaExpression>(build(::JavaULambdaExpression))
|
||||
else -> expr<UExpression>(build(::UnknownJavaExpression))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return with (requiredType) { when (el) {
|
||||
is PsiAssignmentExpression -> expr<UBinaryExpression>(build(::JavaUAssignmentExpression))
|
||||
is PsiConditionalExpression -> expr<UIfExpression>(build(::JavaUTernaryIfExpression))
|
||||
is PsiNewExpression -> {
|
||||
if (el.anonymousClass != null)
|
||||
expr<UObjectLiteralExpression>(build(::JavaUObjectLiteralExpression))
|
||||
else
|
||||
expr<UCallExpression>(build(::JavaConstructorUCallExpression))
|
||||
}
|
||||
is PsiMethodCallExpression -> {
|
||||
if (el.methodExpression.qualifierExpression != null) {
|
||||
if (requiredType == null ||
|
||||
requiredType.isAssignableFrom(UQualifiedReferenceExpression::class.java) ||
|
||||
requiredType.isAssignableFrom(UCallExpression::class.java)) {
|
||||
val expr = JavaUCompositeQualifiedExpression(el, givenParent).apply {
|
||||
receiverInitializer = { convertOrEmpty(el.methodExpression.qualifierExpression!!, this) }
|
||||
selector = JavaUCallExpression(el, this)
|
||||
}
|
||||
if (requiredType?.isAssignableFrom(UCallExpression::class.java) == true)
|
||||
expr.selector
|
||||
else
|
||||
expr
|
||||
}
|
||||
else
|
||||
null
|
||||
}
|
||||
else
|
||||
expr<UCallExpression>(build(::JavaUCallExpression))
|
||||
}
|
||||
is PsiArrayInitializerExpression -> expr<UCallExpression>(build(::JavaArrayInitializerUCallExpression))
|
||||
is PsiBinaryExpression -> expr<UBinaryExpression>(build(::JavaUBinaryExpression))
|
||||
// Should go after PsiBinaryExpression since it implements PsiPolyadicExpression
|
||||
is PsiPolyadicExpression -> expr<UPolyadicExpression>(build(::JavaUPolyadicExpression))
|
||||
is PsiParenthesizedExpression -> expr<UParenthesizedExpression>(build(::JavaUParenthesizedExpression))
|
||||
is PsiPrefixExpression -> expr<UPrefixExpression>(build(::JavaUPrefixExpression))
|
||||
is PsiPostfixExpression -> expr<UPostfixExpression>(build(::JavaUPostfixExpression))
|
||||
is PsiLiteralExpression -> expr<ULiteralExpression>(build(::JavaULiteralExpression))
|
||||
is PsiMethodReferenceExpression -> expr<UCallableReferenceExpression>(build(::JavaUCallableReferenceExpression))
|
||||
is PsiReferenceExpression -> convertReference(el, givenParent, requiredType)
|
||||
is PsiThisExpression -> expr<UThisExpression>(build(::JavaUThisExpression))
|
||||
is PsiSuperExpression -> expr<USuperExpression>(build(::JavaUSuperExpression))
|
||||
is PsiInstanceOfExpression -> expr<UBinaryExpressionWithType>(build(::JavaUInstanceCheckExpression))
|
||||
is PsiTypeCastExpression -> expr<UBinaryExpressionWithType>(build(::JavaUTypeCastExpression))
|
||||
is PsiClassObjectAccessExpression -> expr<UClassLiteralExpression>(build(::JavaUClassLiteralExpression))
|
||||
is PsiArrayAccessExpression -> expr<UArrayAccessExpression>(build(::JavaUArrayAccessExpression))
|
||||
is PsiLambdaExpression -> expr<ULambdaExpression>(build(::JavaULambdaExpression))
|
||||
else -> expr<UExpression>(build(::UnknownJavaExpression))
|
||||
}}
|
||||
internal fun convertStatement(el: PsiStatement,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null): UExpression? {
|
||||
getCached<UExpression>(el)?.let { return it }
|
||||
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UExpression): () -> UExpression? {
|
||||
return fun(): UExpression? {
|
||||
return ctor(el as P, givenParent)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convertStatement(el: PsiStatement,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null): UExpression? {
|
||||
getCached<UExpression>(el)?.let { return it }
|
||||
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UExpression): () -> UExpression? {
|
||||
return fun(): UExpression? {
|
||||
return ctor(el as P, givenParent)
|
||||
}
|
||||
return with(requiredType) {
|
||||
when (el) {
|
||||
is PsiDeclarationStatement -> expr<UDeclarationsExpression> {
|
||||
convertDeclarations(el.declaredElements, givenParent ?: JavaConverter.unwrapElements(el.parent).toUElement()!!)
|
||||
}
|
||||
|
||||
return with (requiredType) { when (el) {
|
||||
is PsiDeclarationStatement -> expr<UDeclarationsExpression> {
|
||||
convertDeclarations(el.declaredElements, givenParent ?: JavaConverter.unwrapElements(el.parent).toUElement() !!)
|
||||
}
|
||||
is PsiExpressionListStatement -> expr<UDeclarationsExpression> {
|
||||
convertDeclarations(el.expressionList.expressions, givenParent ?: JavaConverter.unwrapElements(el.parent).toUElement() !!)
|
||||
}
|
||||
is PsiBlockStatement -> expr<UBlockExpression>(build(::JavaUBlockExpression))
|
||||
is PsiLabeledStatement -> expr<ULabeledExpression>(build(::JavaULabeledExpression))
|
||||
is PsiExpressionStatement -> convertExpression(el.expression, givenParent, requiredType)
|
||||
is PsiIfStatement -> expr<UIfExpression>(build(::JavaUIfExpression))
|
||||
is PsiSwitchStatement -> expr<USwitchExpression>(build(::JavaUSwitchExpression))
|
||||
is PsiWhileStatement -> expr<UWhileExpression>(build(::JavaUWhileExpression))
|
||||
is PsiDoWhileStatement -> expr<UDoWhileExpression>(build(::JavaUDoWhileExpression))
|
||||
is PsiForStatement -> expr<UForExpression>(build(::JavaUForExpression))
|
||||
is PsiForeachStatement -> expr<UForEachExpression>(build(::JavaUForEachExpression))
|
||||
is PsiBreakStatement -> expr<UBreakExpression>(build(::JavaUBreakExpression))
|
||||
is PsiContinueStatement -> expr<UContinueExpression>(build(::JavaUContinueExpression))
|
||||
is PsiReturnStatement -> expr<UReturnExpression>(build(::JavaUReturnExpression))
|
||||
is PsiAssertStatement -> expr<UCallExpression>(build(::JavaUAssertExpression))
|
||||
is PsiThrowStatement -> expr<UThrowExpression>(build(::JavaUThrowExpression))
|
||||
is PsiSynchronizedStatement -> expr<UBlockExpression>(build(::JavaUSynchronizedExpression))
|
||||
is PsiTryStatement -> expr<UTryExpression>(build(::JavaUTryExpression))
|
||||
is PsiEmptyStatement -> expr<UExpression> { UastEmptyExpression }
|
||||
else -> expr<UExpression>(build(::UnknownJavaExpression))
|
||||
}}
|
||||
}
|
||||
|
||||
private fun convertDeclarations(elements: Array<out PsiElement>, parent: UElement): UDeclarationsExpression {
|
||||
return JavaUDeclarationsExpression(parent).apply {
|
||||
val declarations = mutableListOf<UDeclaration>()
|
||||
for (element in elements) {
|
||||
if (element is PsiVariable) {
|
||||
declarations += JavaUVariable.create(element, this)
|
||||
}
|
||||
else if (element is PsiClass) {
|
||||
declarations += JavaUClass.create(element, this)
|
||||
}
|
||||
}
|
||||
this.declarations = declarations
|
||||
is PsiExpressionListStatement -> expr<UDeclarationsExpression> {
|
||||
convertDeclarations(el.expressionList.expressions, givenParent ?: JavaConverter.unwrapElements(el.parent).toUElement()!!)
|
||||
}
|
||||
is PsiBlockStatement -> expr<UBlockExpression>(build(::JavaUBlockExpression))
|
||||
is PsiLabeledStatement -> expr<ULabeledExpression>(build(::JavaULabeledExpression))
|
||||
is PsiExpressionStatement -> convertExpression(el.expression, givenParent, requiredType)
|
||||
is PsiIfStatement -> expr<UIfExpression>(build(::JavaUIfExpression))
|
||||
is PsiSwitchStatement -> expr<USwitchExpression>(build(::JavaUSwitchExpression))
|
||||
is PsiWhileStatement -> expr<UWhileExpression>(build(::JavaUWhileExpression))
|
||||
is PsiDoWhileStatement -> expr<UDoWhileExpression>(build(::JavaUDoWhileExpression))
|
||||
is PsiForStatement -> expr<UForExpression>(build(::JavaUForExpression))
|
||||
is PsiForeachStatement -> expr<UForEachExpression>(build(::JavaUForEachExpression))
|
||||
is PsiBreakStatement -> expr<UBreakExpression>(build(::JavaUBreakExpression))
|
||||
is PsiContinueStatement -> expr<UContinueExpression>(build(::JavaUContinueExpression))
|
||||
is PsiReturnStatement -> expr<UReturnExpression>(build(::JavaUReturnExpression))
|
||||
is PsiAssertStatement -> expr<UCallExpression>(build(::JavaUAssertExpression))
|
||||
is PsiThrowStatement -> expr<UThrowExpression>(build(::JavaUThrowExpression))
|
||||
is PsiSynchronizedStatement -> expr<UBlockExpression>(build(::JavaUSynchronizedExpression))
|
||||
is PsiTryStatement -> expr<UTryExpression>(build(::JavaUTryExpression))
|
||||
is PsiEmptyStatement -> expr<UExpression> { UastEmptyExpression }
|
||||
else -> expr<UExpression>(build(::UnknownJavaExpression))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convertOrEmpty(statement: PsiStatement?, parent: UElement?): UExpression {
|
||||
return statement?.let { convertStatement(it, parent, null) } ?: UastEmptyExpression
|
||||
private fun convertDeclarations(elements: Array<out PsiElement>, parent: UElement): UDeclarationsExpression {
|
||||
return JavaUDeclarationsExpression(parent).apply {
|
||||
val declarations = mutableListOf<UDeclaration>()
|
||||
for (element in elements) {
|
||||
if (element is PsiVariable) {
|
||||
declarations += JavaUVariable.create(element, this)
|
||||
}
|
||||
else if (element is PsiClass) {
|
||||
declarations += JavaUClass.create(element, this)
|
||||
}
|
||||
}
|
||||
this.declarations = declarations
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convertOrEmpty(expression: PsiExpression?, parent: UElement?): UExpression {
|
||||
return expression?.let { convertExpression(it, parent) } ?: UastEmptyExpression
|
||||
}
|
||||
internal fun convertOrEmpty(statement: PsiStatement?, parent: UElement?): UExpression {
|
||||
return statement?.let { convertStatement(it, parent, null) } ?: UastEmptyExpression
|
||||
}
|
||||
|
||||
internal fun convertOrNull(expression: PsiExpression?, parent: UElement?): UExpression? {
|
||||
return if (expression != null) convertExpression(expression, parent) else null
|
||||
}
|
||||
internal fun convertOrEmpty(expression: PsiExpression?, parent: UElement?): UExpression {
|
||||
return expression?.let { convertExpression(it, parent) } ?: UastEmptyExpression
|
||||
}
|
||||
|
||||
internal fun convertOrEmpty(block: PsiCodeBlock?, parent: UElement?): UExpression {
|
||||
return if (block != null) convertBlock(block, parent) else UastEmptyExpression
|
||||
}
|
||||
internal fun convertOrNull(expression: PsiExpression?, parent: UElement?): UExpression? {
|
||||
return if (expression != null) convertExpression(expression, parent) else null
|
||||
}
|
||||
|
||||
internal fun convertOrEmpty(block: PsiCodeBlock?, parent: UElement?): UExpression {
|
||||
return if (block != null) convertBlock(block, parent) else UastEmptyExpression
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -22,14 +22,14 @@ import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
|
||||
class JavaUDoWhileExpression(
|
||||
override val psi: PsiDoWhileStatement,
|
||||
givenParent: UElement?
|
||||
override val psi: PsiDoWhileStatement,
|
||||
givenParent: UElement?
|
||||
) : JavaAbstractUExpression(givenParent), UDoWhileExpression {
|
||||
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
||||
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
||||
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
||||
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
||||
|
||||
override val doIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.DO_KEYWORD), this)
|
||||
override val whileIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.WHILE_KEYWORD), this)
|
||||
override val doIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.DO_KEYWORD), this)
|
||||
override val whileIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.WHILE_KEYWORD), this)
|
||||
}
|
||||
+8
-8
@@ -23,15 +23,15 @@ import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.UParameter
|
||||
|
||||
class JavaUForEachExpression(
|
||||
override val psi: PsiForeachStatement,
|
||||
givenParent: UElement?
|
||||
override val psi: PsiForeachStatement,
|
||||
givenParent: UElement?
|
||||
) : JavaAbstractUExpression(givenParent), UForEachExpression {
|
||||
override val variable: UParameter
|
||||
get() = JavaUParameter(psi.iterationParameter, this)
|
||||
override val variable: UParameter
|
||||
get() = JavaUParameter(psi.iterationParameter, this)
|
||||
|
||||
override val iteratedValue by lz { JavaConverter.convertOrEmpty(psi.iteratedValue, this) }
|
||||
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
||||
override val iteratedValue by lz { JavaConverter.convertOrEmpty(psi.iteratedValue, this) }
|
||||
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
||||
|
||||
override val forIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.FOR_KEYWORD), this)
|
||||
override val forIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.FOR_KEYWORD), this)
|
||||
}
|
||||
@@ -22,14 +22,14 @@ import org.jetbrains.uast.UForExpression
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
|
||||
class JavaUForExpression(
|
||||
override val psi: PsiForStatement,
|
||||
givenParent: UElement?
|
||||
override val psi: PsiForStatement,
|
||||
givenParent: UElement?
|
||||
) : JavaAbstractUExpression(givenParent), UForExpression {
|
||||
override val declaration by lz { psi.initialization?.let { JavaConverter.convertStatement(it, this) } }
|
||||
override val condition by lz { psi.condition?.let { JavaConverter.convertExpression(it, this) } }
|
||||
override val update by lz { psi.update?.let { JavaConverter.convertStatement(it, this) } }
|
||||
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
||||
override val declaration by lz { psi.initialization?.let { JavaConverter.convertStatement(it, this) } }
|
||||
override val condition by lz { psi.condition?.let { JavaConverter.convertExpression(it, this) } }
|
||||
override val update by lz { psi.update?.let { JavaConverter.convertStatement(it, this) } }
|
||||
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
||||
|
||||
override val forIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.FOR_KEYWORD), this)
|
||||
override val forIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.FOR_KEYWORD), this)
|
||||
}
|
||||
@@ -22,19 +22,19 @@ import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.UIfExpression
|
||||
|
||||
class JavaUIfExpression(
|
||||
override val psi: PsiIfStatement,
|
||||
givenParent: UElement?
|
||||
override val psi: PsiIfStatement,
|
||||
givenParent: UElement?
|
||||
) : JavaAbstractUExpression(givenParent), UIfExpression {
|
||||
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
||||
override val thenExpression by lz { JavaConverter.convertOrEmpty(psi.thenBranch, this) }
|
||||
override val elseExpression by lz { JavaConverter.convertOrEmpty(psi.elseBranch, this) }
|
||||
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
||||
override val thenExpression by lz { JavaConverter.convertOrEmpty(psi.thenBranch, this) }
|
||||
override val elseExpression by lz { JavaConverter.convertOrEmpty(psi.elseBranch, this) }
|
||||
|
||||
override val isTernary: Boolean
|
||||
get() = false
|
||||
override val isTernary: Boolean
|
||||
get() = false
|
||||
|
||||
override val ifIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.IF_KEYWORD), this)
|
||||
override val ifIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.IF_KEYWORD), this)
|
||||
|
||||
override val elseIdentifier: UIdentifier?
|
||||
get() = psi.getChildByRole(ChildRole.ELSE_KEYWORD)?.let { UIdentifier(it, this) }
|
||||
override val elseIdentifier: UIdentifier?
|
||||
get() = psi.getChildByRole(ChildRole.ELSE_KEYWORD)?.let { UIdentifier(it, this) }
|
||||
}
|
||||
+66
-66
@@ -22,95 +22,95 @@ import org.jetbrains.uast.java.expressions.JavaUExpressionList
|
||||
import org.jetbrains.uast.java.kinds.JavaSpecialExpressionKinds
|
||||
|
||||
class JavaUSwitchExpression(
|
||||
override val psi: PsiSwitchStatement,
|
||||
givenParent: UElement?
|
||||
override val psi: PsiSwitchStatement,
|
||||
givenParent: UElement?
|
||||
) : JavaAbstractUExpression(givenParent), USwitchExpression {
|
||||
override val expression by lz { JavaConverter.convertOrEmpty(psi.expression, this) }
|
||||
override val expression by lz { JavaConverter.convertOrEmpty(psi.expression, this) }
|
||||
|
||||
override val body: UExpressionList by lz {
|
||||
object : JavaUExpressionList(psi, JavaSpecialExpressionKinds.SWITCH, this) {
|
||||
override fun asRenderString() = expressions.joinToString("\n") {
|
||||
it.asRenderString().withMargin
|
||||
}
|
||||
}.apply {
|
||||
expressions = this@JavaUSwitchExpression.psi.body?.convertToSwitchEntryList(this) ?: emptyList()
|
||||
}
|
||||
override val body: UExpressionList by lz {
|
||||
object : JavaUExpressionList(psi, JavaSpecialExpressionKinds.SWITCH, this) {
|
||||
override fun asRenderString() = expressions.joinToString("\n") {
|
||||
it.asRenderString().withMargin
|
||||
}
|
||||
}.apply {
|
||||
expressions = this@JavaUSwitchExpression.psi.body?.convertToSwitchEntryList(this) ?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override val switchIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.SWITCH_KEYWORD), this)
|
||||
override val switchIdentifier: UIdentifier
|
||||
get() = UIdentifier(psi.getChildByRole(ChildRole.SWITCH_KEYWORD), this)
|
||||
}
|
||||
|
||||
private fun PsiCodeBlock.convertToSwitchEntryList(containingElement: UExpression): List<JavaUSwitchEntry> {
|
||||
var currentLabels = listOf<PsiSwitchLabelStatement>()
|
||||
var currentBody = listOf<PsiStatement>()
|
||||
val result = mutableListOf<JavaUSwitchEntry>()
|
||||
for (statement in statements) {
|
||||
if (statement is PsiSwitchLabelStatement) {
|
||||
if (currentBody.isEmpty()) {
|
||||
currentLabels += statement
|
||||
}
|
||||
else if (currentLabels.isNotEmpty()) {
|
||||
result += JavaUSwitchEntry(currentLabels, currentBody, containingElement)
|
||||
currentLabels = listOf(statement)
|
||||
currentBody = listOf<PsiStatement>()
|
||||
}
|
||||
}
|
||||
else {
|
||||
currentBody += statement
|
||||
}
|
||||
}
|
||||
if (currentLabels.isNotEmpty()) {
|
||||
var currentLabels = listOf<PsiSwitchLabelStatement>()
|
||||
var currentBody = listOf<PsiStatement>()
|
||||
val result = mutableListOf<JavaUSwitchEntry>()
|
||||
for (statement in statements) {
|
||||
if (statement is PsiSwitchLabelStatement) {
|
||||
if (currentBody.isEmpty()) {
|
||||
currentLabels += statement
|
||||
}
|
||||
else if (currentLabels.isNotEmpty()) {
|
||||
result += JavaUSwitchEntry(currentLabels, currentBody, containingElement)
|
||||
currentLabels = listOf(statement)
|
||||
currentBody = listOf<PsiStatement>()
|
||||
}
|
||||
}
|
||||
return result
|
||||
else {
|
||||
currentBody += statement
|
||||
}
|
||||
}
|
||||
if (currentLabels.isNotEmpty()) {
|
||||
result += JavaUSwitchEntry(currentLabels, currentBody, containingElement)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
class JavaUSwitchEntry(
|
||||
val labels: List<PsiSwitchLabelStatement>,
|
||||
val statements: List<PsiStatement>,
|
||||
givenParent: UElement?
|
||||
val labels: List<PsiSwitchLabelStatement>,
|
||||
val statements: List<PsiStatement>,
|
||||
givenParent: UElement?
|
||||
) : JavaAbstractUExpression(givenParent), USwitchClauseExpressionWithBody {
|
||||
override val psi: PsiSwitchLabelStatement = labels.first()
|
||||
override val psi: PsiSwitchLabelStatement = labels.first()
|
||||
|
||||
override val caseValues by lz {
|
||||
labels.mapNotNull {
|
||||
if (it.isDefaultCase) {
|
||||
JavaUDefaultCaseExpression
|
||||
}
|
||||
else {
|
||||
val value = it.caseValue
|
||||
value?.let { JavaConverter.convertExpression(it, this) }
|
||||
}
|
||||
}
|
||||
override val caseValues by lz {
|
||||
labels.mapNotNull {
|
||||
if (it.isDefaultCase) {
|
||||
JavaUDefaultCaseExpression
|
||||
}
|
||||
else {
|
||||
val value = it.caseValue
|
||||
value?.let { JavaConverter.convertExpression(it, this) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val body: UExpressionList by lz {
|
||||
object : JavaUExpressionList(psi, JavaSpecialExpressionKinds.SWITCH_ENTRY, this) {
|
||||
override fun asRenderString() = buildString {
|
||||
appendln("{")
|
||||
expressions.forEach { appendln(it.asRenderString().withMargin) }
|
||||
appendln("}")
|
||||
}
|
||||
}.apply {
|
||||
val statements = this@JavaUSwitchEntry.statements
|
||||
expressions = statements.map { JavaConverter.convertOrEmpty(it, this) }
|
||||
}
|
||||
override val body: UExpressionList by lz {
|
||||
object : JavaUExpressionList(psi, JavaSpecialExpressionKinds.SWITCH_ENTRY, this) {
|
||||
override fun asRenderString() = buildString {
|
||||
appendln("{")
|
||||
expressions.forEach { appendln(it.asRenderString().withMargin) }
|
||||
appendln("}")
|
||||
}
|
||||
}.apply {
|
||||
val statements = this@JavaUSwitchEntry.statements
|
||||
expressions = statements.map { JavaConverter.convertOrEmpty(it, this) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object JavaUDefaultCaseExpression : UExpression, JvmDeclarationUElement {
|
||||
override val uastParent: UElement?
|
||||
get() = null
|
||||
override val uastParent: UElement?
|
||||
get() = null
|
||||
|
||||
override val psi: PsiElement?
|
||||
get() = null
|
||||
override val psi: PsiElement?
|
||||
get() = null
|
||||
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
|
||||
override fun asLogString() = "UDefaultCaseExpression"
|
||||
override fun asLogString() = "UDefaultCaseExpression"
|
||||
|
||||
override fun asRenderString() = "else"
|
||||
override fun asRenderString() = "else"
|
||||
}
|
||||
+11
-11
@@ -21,19 +21,19 @@ import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.UIfExpression
|
||||
|
||||
class JavaUTernaryIfExpression(
|
||||
override val psi: PsiConditionalExpression,
|
||||
givenParent: UElement?
|
||||
override val psi: PsiConditionalExpression,
|
||||
givenParent: UElement?
|
||||
) : JavaAbstractUExpression(givenParent), UIfExpression {
|
||||
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
||||
override val thenExpression by lz { JavaConverter.convertOrEmpty(psi.thenExpression, this) }
|
||||
override val elseExpression by lz { JavaConverter.convertOrEmpty(psi.elseExpression, this) }
|
||||
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
||||
override val thenExpression by lz { JavaConverter.convertOrEmpty(psi.thenExpression, this) }
|
||||
override val elseExpression by lz { JavaConverter.convertOrEmpty(psi.elseExpression, this) }
|
||||
|
||||
override val isTernary: Boolean
|
||||
get() = true
|
||||
override val isTernary: Boolean
|
||||
get() = true
|
||||
|
||||
override val ifIdentifier: UIdentifier
|
||||
get() = UIdentifier(null, this)
|
||||
override val ifIdentifier: UIdentifier
|
||||
get() = UIdentifier(null, this)
|
||||
|
||||
override val elseIdentifier: UIdentifier?
|
||||
get() = UIdentifier(null, this)
|
||||
override val elseIdentifier: UIdentifier?
|
||||
get() = UIdentifier(null, this)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user