Lint: Update Uast implementation (the new version is without declaration level)
This commit is contained in:
committed by
Yan Zhulanow
parent
6491d3fbac
commit
d5d491e6b2
@@ -1,50 +1,73 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
/**
|
import com.intellij.lang.Language
|
||||||
* Interface for the Uast context.
|
import com.intellij.openapi.project.Project
|
||||||
*
|
import com.intellij.psi.PsiClass
|
||||||
* Context is needed for resolution, cause the reference can point to the element of the different language.
|
import com.intellij.psi.PsiElement
|
||||||
*/
|
import com.intellij.psi.PsiMethod
|
||||||
interface UastContext {
|
import com.intellij.psi.PsiVariable
|
||||||
/**
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
* Returns all active language plugins.
|
|
||||||
*/
|
|
||||||
val languagePlugins: List<UastLanguagePlugin>
|
|
||||||
|
|
||||||
/**
|
class UastContext(override val project: Project) : UastLanguagePlugin {
|
||||||
* Convert an element of some language-specific AST to Uast element.
|
private companion object {
|
||||||
* If two or more language plugins can convert the given [element] type,
|
private val CONTEXT_LANGUAGE = object : Language("UastContextLanguage") {}
|
||||||
* the first converter in the [languagePlugins] list will be chosen.
|
}
|
||||||
*
|
|
||||||
* @param element the language-specific AST element
|
|
||||||
* @return [UElement] instance, or null if [element] type is not supported by any of the provided language plugins.
|
|
||||||
*/
|
|
||||||
fun convert(element: Any?): UElement? {
|
|
||||||
if (element == null) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
for (plugin in languagePlugins) {
|
override val language: Language
|
||||||
val uelement = plugin.converter.convertWithParent(element)
|
get() = CONTEXT_LANGUAGE
|
||||||
if (uelement != null) {
|
|
||||||
return uelement
|
override val priority: Int
|
||||||
}
|
get() = 0
|
||||||
|
|
||||||
|
val languagePlugins: Collection<UastLanguagePlugin>
|
||||||
|
get() = UastLanguagePlugin.getInstances(project)
|
||||||
|
|
||||||
|
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? {
|
||||||
|
return findPlugin(element)?.convertElement(element, parent, requiredType)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
|
||||||
|
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 {
|
||||||
|
if (this is PsiElementBacked) {
|
||||||
|
psi?.language?.let { return it }
|
||||||
}
|
}
|
||||||
return null
|
val containingElement = this.containingElement ?: throw IllegalStateException("At least UFile should have a language")
|
||||||
|
return containingElement.getLanguage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,93 +1,98 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import com.intellij.lang.Language
|
||||||
|
import com.intellij.openapi.extensions.ExtensionPointName
|
||||||
|
import com.intellij.openapi.extensions.Extensions
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.*
|
||||||
|
|
||||||
|
interface UastLanguagePlugin {
|
||||||
|
companion object {
|
||||||
|
val extensionPointName = ExtensionPointName.create<UastLanguagePlugin>("org.jetbrains.uast.uastLanguagePlugin")
|
||||||
|
|
||||||
|
fun getInstances(project: Project): Collection<UastLanguagePlugin> {
|
||||||
|
val projectArea = Extensions.getArea(project)
|
||||||
|
if (!projectArea.hasExtensionPoint(extensionPointName.name)) return listOf()
|
||||||
|
return projectArea.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)
|
||||||
|
|
||||||
|
val language: Language
|
||||||
|
|
||||||
|
val project: Project
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for the Uast element converter.
|
|
||||||
* Each [UastLanguagePlugin] should implement a proper [UastContext],
|
|
||||||
* which translates language-specific AST elements to Uast elements.
|
|
||||||
*/
|
|
||||||
interface UastConverter {
|
|
||||||
/**
|
/**
|
||||||
* Convert a language-specific AST element to the [UElement] implementation with the given parent.
|
* Checks if the file with the given [fileName] is supported.
|
||||||
*
|
*
|
||||||
* @param element the element of the supported language-specific AST.
|
* @param fileName the source file name.
|
||||||
* @param parent the parent of the newly created [UElement].
|
* @return true, if the file is supported by this converter, false otherwise.
|
||||||
* @return a [UElement], or null if the given [element] is not supported by this converter.
|
|
||||||
*
|
|
||||||
* No exceptions should be thrown during conversion, return `null` instead.
|
|
||||||
*/
|
*/
|
||||||
fun convert(element: Any?, parent: UElement): UElement?
|
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
|
||||||
|
|
||||||
|
fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>? = null): UElement?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert [element] to the [UElement] with the given parent.
|
* Convert [element] to the [UElement] with the given parent.
|
||||||
*/
|
*/
|
||||||
fun convertWithParent(element: Any?): UElement?
|
fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement?
|
||||||
|
|
||||||
/**
|
fun getMethodCallExpression(
|
||||||
* Checks if the file with the given [name] is supported.
|
element: PsiElement,
|
||||||
*
|
containingClassFqName: String?,
|
||||||
* @param name the source file name.
|
methodName: String
|
||||||
* @return true, if the file is supported by this converter, false otherwise.
|
): ResolvedMethod?
|
||||||
*/
|
|
||||||
fun isFileSupported(name: String): Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
fun getConstructorCallExpression(
|
||||||
* Interface for the Uast language plugin.
|
element: PsiElement,
|
||||||
*
|
fqName: String
|
||||||
* [UElement] implementations are loaded using language plugins provided in [UastContext].
|
) : ResolvedConstructor?
|
||||||
* Each plugin must have a language-specific AST -> Uast (e.g. PsiElement -> UElement) converter.
|
|
||||||
*/
|
|
||||||
interface UastLanguagePlugin {
|
|
||||||
/**
|
|
||||||
* Returns converter for the specific language AST.
|
|
||||||
*/
|
|
||||||
val converter: UastConverter
|
|
||||||
|
|
||||||
/**
|
fun getMethodBody(element: PsiMethod): UExpression? {
|
||||||
* Returns list of visitor extensions for the specific language AST.
|
if (element is UMethod) return element.uastBody
|
||||||
*/
|
return (convertElementWithParent(element, null) as? UMethod)?.uastBody
|
||||||
val visitorExtensions: List<UastVisitorExtension>
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for the Uast visitor extension.
|
|
||||||
*
|
|
||||||
* A language plugin could provide a number of visitor extensions, which transforms some [UElement] into another.
|
|
||||||
* For example, Java accessors (getters/setters) are expressed in Kotlin as properties,
|
|
||||||
* but it can be useful to see them as functions in diagnostics, so the visitor extension
|
|
||||||
* can convert such property accessor calls to the ordinary function calls.
|
|
||||||
*/
|
|
||||||
interface UastVisitorExtension {
|
|
||||||
/**
|
|
||||||
* Invoke extension on an element.
|
|
||||||
*
|
|
||||||
* @param element a [UElement] to process.
|
|
||||||
* @param visitor current visitor.
|
|
||||||
* @param context current context.
|
|
||||||
*/
|
|
||||||
operator fun invoke(element: UElement, visitor: UastVisitor, context: UastContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
object UastConverterUtils {
|
|
||||||
@JvmStatic
|
|
||||||
fun isFileSupported(converters: List<UastLanguagePlugin>, name: String): Boolean {
|
|
||||||
return converters.any { it.converter.isFileSupported(name) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getInitializerBody(element: PsiClassInitializer): UExpression {
|
||||||
|
if (element is UClassInitializer) return element.uastBody
|
||||||
|
return (convertElementWithParent(element, null) as? UClassInitializer)?.uastBody ?: UastEmptyExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : UElement> UastLanguagePlugin.convert(element: PsiElement, parent: UElement?): 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
|
||||||
}
|
}
|
||||||
@@ -1,348 +1,135 @@
|
|||||||
/*
|
@file:JvmMultifileClass
|
||||||
* Copyright 2000-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
@file:JvmName("UastUtils")
|
@file:JvmName("UastUtils")
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.vfs.VfsUtilCore
|
||||||
|
import com.intellij.psi.PsiClass
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiNamedElement
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import org.jetbrains.uast.expressions.UReferenceExpression
|
||||||
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
internal val ERROR_NAME = "<error>"
|
inline fun <reified T : UElement> UElement.getParentOfType(strict: Boolean = true): T? = getParentOfType(T::class.java, strict)
|
||||||
|
|
||||||
/**
|
@JvmOverloads
|
||||||
* Returns the containing class of an element.
|
fun <T : UElement> UElement.getParentOfType(parentClass: Class<out UElement>, strict: Boolean = true): T? {
|
||||||
*
|
var element = (if (strict) containingElement else this) ?: return null
|
||||||
* @return the containing [UClass] element,
|
while (true) {
|
||||||
* or null if the receiver is null, or it is a top-level declaration.
|
if (parentClass.isInstance(element)) {
|
||||||
*/
|
@Suppress("UNCHECKED_CAST")
|
||||||
tailrec fun UElement?.getContainingClass(): UClass? {
|
return element as T
|
||||||
val parent = this?.parent ?: return null
|
}
|
||||||
if (parent is UClass) return parent
|
element = element.containingElement ?: return null
|
||||||
return parent.getContainingClass()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun <T : UElement> UElement.getParentOfType(
|
||||||
* Returns the containing file of an element.
|
parentClass: Class<out UElement>,
|
||||||
*
|
strict: Boolean = true,
|
||||||
* @return the containing [UFile] element,
|
vararg terminators: Class<out UElement>
|
||||||
* or null if the receiver is null, or the element is not inside a [UFile] (it is abmormal).
|
): T? {
|
||||||
*/
|
var element = (if (strict) containingElement else this) ?: return null
|
||||||
tailrec fun UElement?.getContainingFile(): UFile? {
|
while (true) {
|
||||||
val parent = this?.parent ?: return null
|
if (parentClass.isInstance(element)) {
|
||||||
if (parent is UFile) return parent
|
@Suppress("UNCHECKED_CAST")
|
||||||
return parent.getContainingFile()
|
return element as T
|
||||||
|
}
|
||||||
|
if (terminators.any { it.isInstance(element) }) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
element = element.containingElement ?: return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun UElement?.getContainingClassOrEmpty() = getContainingClass() ?: UClassNotResolved
|
fun <T : UElement> UElement.getParentOfType(
|
||||||
|
strict: Boolean = true,
|
||||||
/**
|
firstParentClass: Class<out T>,
|
||||||
* Returns the containing function of an element.
|
vararg parentClasses: Class<out T>
|
||||||
*
|
): T? {
|
||||||
* @return the containing [UFunction] element,
|
var element = (if (strict) containingElement else this) ?: return null
|
||||||
* or null if the receiver is null, or the element is not inside a [UFunction].
|
while (true) {
|
||||||
*/
|
if (firstParentClass.isInstance(element)) {
|
||||||
tailrec fun UElement?.getContainingFunction(): UFunction? {
|
@Suppress("UNCHECKED_CAST")
|
||||||
val parent = this?.parent ?: return null
|
return element as T
|
||||||
if (parent is UFunction) return parent
|
}
|
||||||
return parent.getContainingFunction()
|
if (parentClasses.any { it.isInstance(element) }) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return element as T
|
||||||
|
}
|
||||||
|
element = element.containingElement ?: return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun UElement.getContainingFile() = getParentOfType<UFile>(UFile::class.java)
|
||||||
* Returns the containing declaration of an element.
|
|
||||||
*
|
|
||||||
* @return the containing [UDeclaration] element,
|
|
||||||
* or null if the receiver is null, or the element is a top-level declaration.
|
|
||||||
*/
|
|
||||||
tailrec fun UElement?.getContainingDeclaration(): UDeclaration? {
|
|
||||||
val parent = this?.parent ?: return null
|
|
||||||
if (parent is UDeclaration) return parent
|
|
||||||
return parent.getContainingDeclaration()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
fun UElement.getContainingUMethod() = getParentOfType<UMethod>(UMethod::class.java)
|
||||||
* Checks if the element is a top-level declaration.
|
fun UElement.getContainingUVariable() = getParentOfType<UVariable>(UVariable::class.java)
|
||||||
*
|
|
||||||
* @return true if the element is a top-level declaration, false otherwise.
|
|
||||||
*/
|
|
||||||
fun UDeclaration.isTopLevel() = parent is UFile
|
|
||||||
|
|
||||||
/**
|
fun UElement.getContainingMethod() = getContainingUMethod()?.psi
|
||||||
* Builds the log message for the [UElement.logString] function.
|
fun UElement.getContainingVariable() = getContainingUVariable()?.psi
|
||||||
*
|
|
||||||
* @param firstLine the message line (the interface name, some optional information).
|
fun PsiElement?.getContainingClass() = this?.let { PsiTreeUtil.getParentOfType(it, PsiClass::class.java) }
|
||||||
* @param nested nested UElements. Could be `List<UElement>`, [UElement] or `null`.
|
|
||||||
* @throws IllegalStateException if the [nested] argument is invalid.
|
fun UElement.isChildOf(probablyParent: UElement?, strict: Boolean = false): Boolean {
|
||||||
* @return the rendered log string.
|
tailrec fun isChildOf(current: UElement?, probablyParent: UElement): Boolean {
|
||||||
*/
|
return when (current) {
|
||||||
fun UElement.log(firstLine: String, vararg nested: Any?): String {
|
null -> false
|
||||||
return (if (firstLine.isBlank()) "" else firstLine + "\n") + nested.joinToString("\n") {
|
probablyParent -> true
|
||||||
when (it) {
|
else -> isChildOf(current.containingElement, probablyParent)
|
||||||
null -> "<no element>".withMargin
|
|
||||||
is List<*> ->
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
(it as List<UElement>).logString()
|
|
||||||
is UElement -> it.logString().withMargin
|
|
||||||
else -> error("Invalid element type: $it")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (probablyParent == null) return false
|
||||||
|
return isChildOf(if (strict) this else containingElement, probablyParent)
|
||||||
}
|
}
|
||||||
|
|
||||||
val String.withMargin: String
|
|
||||||
get() = lines().joinToString("\n") { " " + it }
|
|
||||||
|
|
||||||
fun List<UElement>.acceptList(visitor: UastVisitor) {
|
|
||||||
for (element in this) {
|
|
||||||
element.accept(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
fun UClass.findFunctions(name: String) = declarations.filter { it is UFunction && it.matchesName(name) } as List<UFunction>
|
|
||||||
|
|
||||||
fun UCallExpression.getReceiver(): UExpression? = (this.parent as? UQualifiedExpression)?.receiver
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the receiver element if it implements [UResolvable].
|
* Resolves the receiver element if it implements [UResolvable].
|
||||||
*
|
*
|
||||||
* @return the resolved element, or null if the element was not resolved, or if the receiver element is not an [UResolvable].
|
* @return the resolved element, or null if the element was not resolved, or if the receiver element is not an [UResolvable].
|
||||||
*/
|
*/
|
||||||
fun UElement.resolveIfCan(context: UastContext): UDeclaration? = (this as? UResolvable)?.resolve(context)
|
fun UElement.tryResolve(): PsiElement? = (this as? UResolvable)?.resolve()
|
||||||
|
|
||||||
/**
|
fun UElement.tryResolveNamed(): PsiNamedElement? = (this as? UResolvable)?.resolve() as? PsiNamedElement
|
||||||
* Find an annotation with the required qualified name.
|
|
||||||
*
|
|
||||||
* @param fqName the qualified name to search
|
|
||||||
* @return [UAnnotation] element if the annotation with the specified [fqName] was found, null otherwise.
|
|
||||||
*/
|
|
||||||
fun UAnnotated.findAnnotation(fqName: String) = annotations.firstOrNull { it.fqName == fqName }
|
|
||||||
|
|
||||||
/**
|
fun UElement.tryResolveUDeclaration(context: UastContext): UDeclaration? {
|
||||||
* Get all class declarations (including supertypes).
|
return (this as? UResolvable)?.resolve()?.let { context.convertElementWithParent(it, null) as? UDeclaration }
|
||||||
*
|
|
||||||
* @param context the Uast context
|
|
||||||
* @return the list of declarations for the receiver class
|
|
||||||
*/
|
|
||||||
fun UClass.getAllDeclarations(context: UastContext): List<UDeclaration> = mutableListOf<UDeclaration>().apply {
|
|
||||||
this += declarations
|
|
||||||
for (superType in superTypes) {
|
|
||||||
superType.resolveClass(context)?.declarations?.let { this += it }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun UReferenceExpression?.getQualifiedName() = (this?.resolve() as? PsiClass)?.qualifiedName
|
||||||
* Get all functions in class (including supertypes).
|
|
||||||
*
|
|
||||||
* @param context the Uast context
|
|
||||||
* @return the list of functions for the receiver class and its supertypes
|
|
||||||
*/
|
|
||||||
fun UClass.getAllFunctions(context: UastContext) = getAllDeclarations(context).filterIsInstance<UFunction>()
|
|
||||||
|
|
||||||
tailrec fun UQualifiedExpression.getCallElementFromQualified(): UCallExpression? {
|
|
||||||
val selector = this.selector
|
|
||||||
return when (selector) {
|
|
||||||
is UQualifiedExpression -> selector.getCallElementFromQualified()
|
|
||||||
is UCallExpression -> selector
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the nearest parent of the type [T].
|
* Returns the String expression value, or null if the value can't be calculated or if the calculated value is not a String.
|
||||||
*
|
|
||||||
* @return the nearest parent of type [T], or null if the parent with such type was not found.
|
|
||||||
*/
|
*/
|
||||||
inline fun <reified T: UElement> UElement.getParentOfType(): T? = getParentOfType(T::class.java)
|
fun UExpression.evaluateString(): String? = evaluate() as? String
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the nearest parent of the type [T].
|
* Get a physical [File] for this file, or null if there is no such file on disk.
|
||||||
*
|
|
||||||
* @param strict if false, return the received element if it's type is [T], do not check the received element overwise.
|
|
||||||
* @return the nearest parent of type [T], or null if the parent with such type was not found.
|
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
fun UFile.getIoFile(): File? = psi.virtualFile?.let { VfsUtilCore.virtualToIoFile(it) }
|
||||||
fun <T: UElement> UElement.getParentOfType(clazz: Class<T>, strict: Boolean = true): T? {
|
|
||||||
tailrec fun findParent(element: UElement?): UElement? {
|
tailrec fun UElement.getUastContext(): UastContext {
|
||||||
return when {
|
if (this is PsiElementBacked) {
|
||||||
element == null -> null
|
val psi = this.psi
|
||||||
clazz.isInstance(element) -> element
|
if (psi != null) {
|
||||||
else -> findParent(element.parent)
|
return ServiceManager.getService(psi.project, UastContext::class.java) ?: error("UastContext not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
return (containingElement ?: error("PsiElement should exist at least for UFile")).getUastContext()
|
||||||
return findParent(if (!strict) this else parent) as? T
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
tailrec fun UElement.getLanguagePlugin(): UastLanguagePlugin {
|
||||||
* Get the topmost parent qualified expression for the call expression.
|
if (this is PsiElementBacked) {
|
||||||
*
|
val psi = this.psi
|
||||||
* Example 1:
|
if (psi != null) {
|
||||||
* Code: variable.call(args)
|
val uastContext = ServiceManager.getService(psi.project, UastContext::class.java) ?: error("UastContext not found")
|
||||||
* Call element: E = call(args)
|
return uastContext.findPlugin(psi) ?: error("Language plugin was not found for $this (${this.javaClass.name})")
|
||||||
* Qualified call element: Q = [getQualifiedCallElement](E) = variable.call(args)
|
|
||||||
*
|
|
||||||
* Example 2:
|
|
||||||
* Code: call(args)
|
|
||||||
* Call element: E = call(args)
|
|
||||||
* Qualified call element: Q = [getQualifiedCallElement](E) = call(args) (no qualifier)
|
|
||||||
*
|
|
||||||
* @return containing qualified expression if the call is a child of the qualified expression, call element otherwise.
|
|
||||||
*/
|
|
||||||
fun UCallExpression.getQualifiedCallElement(): UExpression {
|
|
||||||
fun findParent(current: UExpression?, previous: UExpression): UExpression? = when (current) {
|
|
||||||
is UQualifiedExpression -> {
|
|
||||||
if (current.selector == previous)
|
|
||||||
findParent(current.parent as? UExpression, current) ?: current
|
|
||||||
else
|
|
||||||
previous
|
|
||||||
}
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
return findParent(parent as? UExpression, this) ?: this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> UClass.findStaticMemberOfType(name: String, type: Class<out T>): T? {
|
|
||||||
for (companion in companions) {
|
|
||||||
val member = companion.declarations.firstOrNull {
|
|
||||||
it.name == name && type.isInstance(it) && it is UModifierOwner && it.hasModifier(UastModifier.STATIC)
|
|
||||||
}
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
if (member != null) return member as T
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
return declarations.firstOrNull {
|
|
||||||
it.name == name && it is UModifierOwner
|
|
||||||
&& it.hasModifier(UastModifier.STATIC) && type.isInstance(it)
|
|
||||||
} as T
|
|
||||||
}
|
|
||||||
|
|
||||||
fun UExpression.asQualifiedIdentifiers(): List<String>? {
|
|
||||||
if (this is USimpleReferenceExpression) {
|
|
||||||
return listOf(this.identifier)
|
|
||||||
} else if (this !is UQualifiedExpression) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
var error = false
|
|
||||||
val list = mutableListOf<String>()
|
|
||||||
fun addIdentifiers(expr: UQualifiedExpression) {
|
|
||||||
val receiver = expr.receiver
|
|
||||||
val selector = expr.selector as? USimpleReferenceExpression ?: run { error = true; return }
|
|
||||||
when (receiver) {
|
|
||||||
is UQualifiedExpression -> addIdentifiers(receiver)
|
|
||||||
is USimpleReferenceExpression -> list += receiver.identifier
|
|
||||||
else -> {
|
|
||||||
error = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
list += selector.identifier
|
|
||||||
}
|
|
||||||
|
|
||||||
addIdentifiers(this)
|
|
||||||
return if (error) null else list
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the received expression is a qualified chain of identifiers, and the chain is [fqName].
|
|
||||||
*
|
|
||||||
* @param fqName the chain part to check against. Sequence of identifiers, separated by dot ('.'). Example: "com.example".
|
|
||||||
* @return true, if the received expression is a qualified chain of identifiers, and the chain is [fqName].
|
|
||||||
*/
|
|
||||||
fun UExpression.matchesQualified(fqName: String): Boolean {
|
|
||||||
val identifiers = this.asQualifiedIdentifiers() ?: return false
|
|
||||||
val passedIdentifiers = fqName.split('.')
|
|
||||||
return identifiers == passedIdentifiers
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the received expression is a qualified chain of identifiers, and the leading part of such chain is [fqName].
|
|
||||||
*
|
|
||||||
* @param fqName the chain part to check against. Sequence of identifiers, separated by dot ('.'). Example: "com.example".
|
|
||||||
* @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.asQualifiedIdentifiers() ?: 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
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the received expression is a qualified chain of identifiers, and the trailing part of such chain is [fqName].
|
|
||||||
*
|
|
||||||
* @param fqName the chain part to check against. Sequence of identifiers, separated by dot ('.'). Example: "com.example".
|
|
||||||
* @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.asQualifiedIdentifiers()?.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
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the outermost qualified expression.
|
|
||||||
*
|
|
||||||
* @return the outermost qualified expression,
|
|
||||||
* this element if the parent expression is not a qualified expression,
|
|
||||||
* or null if the element is not a qualified expression.
|
|
||||||
*/
|
|
||||||
fun UExpression.findOutermostQualifiedExpression(): UQualifiedExpression? {
|
|
||||||
val parent = this.parent
|
|
||||||
return when (parent) {
|
|
||||||
is UQualifiedExpression -> parent.findOutermostQualifiedExpression()
|
|
||||||
else -> if (this is UQualifiedExpression) this else null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the list of qualified expressions.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* Code: obj.call(param).anotherCall(param2).getter
|
|
||||||
* Qualified chain: [obj, call(param), anotherCall(param2), getter]
|
|
||||||
*
|
|
||||||
* @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: UQualifiedExpression, chains: MutableList<UExpression>) {
|
|
||||||
val receiver = expr.receiver
|
|
||||||
if (receiver is UQualifiedExpression) {
|
|
||||||
collect(receiver, chains)
|
|
||||||
} else {
|
|
||||||
chains += receiver
|
|
||||||
}
|
|
||||||
|
|
||||||
val selector = expr.selector
|
|
||||||
if (selector is UQualifiedExpression) {
|
|
||||||
collect(selector, chains)
|
|
||||||
} else {
|
|
||||||
chains += selector
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val qualifiedExpression = this.findOutermostQualifiedExpression() ?: return emptyList()
|
return (containingElement ?: error("PsiElement should exist at least for UFile")).getLanguagePlugin()
|
||||||
val chains = mutableListOf<UExpression>()
|
|
||||||
collect(qualifiedExpression, chains)
|
|
||||||
return chains
|
|
||||||
}
|
}
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
|
||||||
|
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
|
||||||
|
|
||||||
/**
|
|
||||||
Represents an applied JVM annotation.
|
|
||||||
*/
|
|
||||||
interface UAnnotation : UElement, UNamed, UFqNamed {
|
|
||||||
/**
|
|
||||||
* Returns the list of named value arguments.
|
|
||||||
*/
|
|
||||||
val valueArguments: List<UNamedExpression>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the class of this annotation.
|
|
||||||
*
|
|
||||||
* @return annotation class or null if the class was not resolved
|
|
||||||
*/
|
|
||||||
fun resolve(context: UastContext): UClass?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the evaluated value of the argument with the specified name.
|
|
||||||
*
|
|
||||||
* @param name name of the annotation value parameter
|
|
||||||
* @return the argument value
|
|
||||||
*/
|
|
||||||
fun getValue(name: String) = valueArguments.firstOrNull { it.name == name }?.expression?.evaluate()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of Pair(name, evaluatedValue) for all applied annotation arguments.
|
|
||||||
*
|
|
||||||
* @return the list of name-value pairs.
|
|
||||||
*/
|
|
||||||
fun getValues() = valueArguments.map { Pair(it.name, it.expression.evaluate()) }
|
|
||||||
|
|
||||||
override fun logString() = log("UAnnotation ($name)")
|
|
||||||
|
|
||||||
override fun renderString(): String {
|
|
||||||
return if (valueArguments.isEmpty())
|
|
||||||
"@$name"
|
|
||||||
else
|
|
||||||
"@$name(" + valueArguments.joinToString { it.renderString() } + ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
|
||||||
if (visitor.visitAnnotation(this)) return
|
|
||||||
valueArguments.acceptList(visitor)
|
|
||||||
visitor.afterVisitAnnotation(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents an annotated element.
|
|
||||||
*/
|
|
||||||
interface UAnnotated : UElement {
|
|
||||||
/**
|
|
||||||
* Returns the list of annotations applied to the current element.
|
|
||||||
*/
|
|
||||||
val annotations: List<UAnnotation>
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
|
class UComment(override val psi: PsiElement, override val containingElement: UElement) : UElement, PsiElementBacked {
|
||||||
|
val text: String
|
||||||
|
get() = asSourceString()
|
||||||
|
|
||||||
|
override fun asLogString() = "UComment"
|
||||||
|
override fun asRenderString(): String = asSourceString()
|
||||||
|
override fun asSourceString(): String = psi.text
|
||||||
|
}
|
||||||
@@ -24,14 +24,20 @@ interface UElement {
|
|||||||
/**
|
/**
|
||||||
* Returns the element parent.
|
* Returns the element parent.
|
||||||
*/
|
*/
|
||||||
val parent: UElement?
|
val containingElement: UElement?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this element is valid, false otherwise.
|
* Returns true if this element is valid, false otherwise.
|
||||||
*/
|
*/
|
||||||
open val isValid: Boolean
|
val isPsiValid: Boolean
|
||||||
get() = true
|
get() = true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of comments for this element.
|
||||||
|
*/
|
||||||
|
val comments: List<UComment>
|
||||||
|
get() = emptyList()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the log string.
|
* Returns the log string.
|
||||||
*
|
*
|
||||||
@@ -49,7 +55,7 @@ interface UElement {
|
|||||||
* @return the expression tree for this element.
|
* @return the expression tree for this element.
|
||||||
* @see [UIfExpression] for example.
|
* @see [UIfExpression] for example.
|
||||||
*/
|
*/
|
||||||
fun logString(): String
|
fun asLogString(): String
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the string in pseudo-code.
|
* Returns the string in pseudo-code.
|
||||||
@@ -63,7 +69,15 @@ interface UElement {
|
|||||||
* @return the rendered text.
|
* @return the rendered text.
|
||||||
* @see [UIfExpression] for example.
|
* @see [UIfExpression] for example.
|
||||||
*/
|
*/
|
||||||
fun renderString(): String = logString()
|
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()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Passes the element to the specified visitor.
|
* Passes the element to the specified visitor.
|
||||||
@@ -72,104 +86,6 @@ interface UElement {
|
|||||||
*/
|
*/
|
||||||
fun accept(visitor: UastVisitor) {
|
fun accept(visitor: UastVisitor) {
|
||||||
visitor.visitElement(this)
|
visitor.visitElement(this)
|
||||||
|
visitor.afterVisitElement(this)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface for the [UElement] which was synthesized by an [UastExtendableVisitor].
|
|
||||||
* A synthesized element is not processed by an [UastExtendableVisitor].
|
|
||||||
*/
|
|
||||||
interface SynthesizedUElement : UElement
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface for the [UElement] which has a name.
|
|
||||||
*/
|
|
||||||
interface UNamed {
|
|
||||||
/**
|
|
||||||
* Returns the name of this element.
|
|
||||||
*/
|
|
||||||
val name: String
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the element name is equal to the passed name.
|
|
||||||
*
|
|
||||||
* @param name the name to check against
|
|
||||||
* @return true if the element name is equal to [name], false otherwise.
|
|
||||||
*/
|
|
||||||
fun matchesName(name: String) = this.name == name
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface for the [UElement] which has a qualified name.
|
|
||||||
*/
|
|
||||||
interface UFqNamed : UNamed {
|
|
||||||
/**
|
|
||||||
* Returns the qualified name of this element, or null if the qualified name was not resolved.
|
|
||||||
*/
|
|
||||||
val fqName: String?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the element qualified name is equal to the passed name.
|
|
||||||
*
|
|
||||||
* @param fqName qualified name to check against
|
|
||||||
* @return true if the element name is not null and is equal to [name], false otherwise.
|
|
||||||
*/
|
|
||||||
fun matchesFqName(fqName: String) = this.fqName == fqName
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface for the [UElement] which has Uast modifiers.
|
|
||||||
*/
|
|
||||||
interface UModifierOwner {
|
|
||||||
/**
|
|
||||||
* Checks if the element has the passed modifier.
|
|
||||||
*
|
|
||||||
* @param modifier modifier to check
|
|
||||||
* @return true if the element has [modifier], false otherwise.
|
|
||||||
*/
|
|
||||||
fun hasModifier(modifier: UastModifier): Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface for the [UElement] which has a visibility (class, function, variable).
|
|
||||||
*/
|
|
||||||
interface UVisibilityOwner {
|
|
||||||
/**
|
|
||||||
* Returns the element visibility.
|
|
||||||
*/
|
|
||||||
val visibility: UastVisibility
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An inteface for the [UElement] which can be resolved to the its declaration.
|
|
||||||
*/
|
|
||||||
interface UResolvable {
|
|
||||||
/**
|
|
||||||
* Returns the declaration element.
|
|
||||||
*
|
|
||||||
* @param context the Uast context
|
|
||||||
* @return the resolved declaration, or null if the declaration was not resolved.
|
|
||||||
*/
|
|
||||||
fun resolve(context: UastContext): UDeclaration?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the declaration element or an empty Uast declaration element if the declaration was not resolved.
|
|
||||||
* An empty declaration element should be a singleton.
|
|
||||||
* [resolveOrEmpty] should not create new elements each time the declaration was not resolved.
|
|
||||||
*
|
|
||||||
* @param context the Uast context
|
|
||||||
* @return the resolved declaration, of an empty error Uast declaration element if the declaration was not resolved.
|
|
||||||
*
|
|
||||||
* @see [UDeclarationNotResolved]
|
|
||||||
*/
|
|
||||||
fun resolveOrEmpty(context: UastContext): UDeclaration = resolve(context) ?: UDeclarationNotResolved
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the declaration [UClass] element of null if the declaration was not resolved.
|
|
||||||
*
|
|
||||||
* @param context the Uast context
|
|
||||||
* @return the resolved [UClass] element, or null if the class was not resolved,
|
|
||||||
* or if the resolved [UElement] is not an instance of [UClass].
|
|
||||||
*/
|
|
||||||
fun resolveClass(context: UastContext): UClass? = resolve(context) as? UClass
|
|
||||||
}
|
}
|
||||||
@@ -15,12 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiAnnotation
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an expression or statement (which is considered as an expression in Uast).
|
||||||
|
*/
|
||||||
interface UExpression : UElement {
|
interface UExpression : UElement {
|
||||||
open fun evaluate(): Any? = null
|
/**
|
||||||
fun evaluateString(): String? = evaluate() as? String
|
* Returns the expression value or null if the value can't be calculated.
|
||||||
fun getExpressionType(): UType? = null
|
*/
|
||||||
|
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
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
visitor.visitElement(this)
|
visitor.visitElement(this)
|
||||||
@@ -28,15 +39,35 @@ interface UExpression : UElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NoAnnotations : UAnnotated {
|
/**
|
||||||
override val annotations: List<UAnnotation>
|
* Represents an annotated element.
|
||||||
get() = emptyList()
|
*/
|
||||||
|
interface UAnnotated : UElement {
|
||||||
|
/**
|
||||||
|
* Returns the list of annotations applied to the current element.
|
||||||
|
*/
|
||||||
|
val annotations: List<PsiAnnotation>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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): PsiAnnotation? = annotations.firstOrNull { it.qualifiedName == fqName }
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NoModifiers : UModifierOwner {
|
/**
|
||||||
override fun hasModifier(modifier: UastModifier) = false
|
* In some cases (user typing, syntax error) elements, which are supposed to exist, are missing.
|
||||||
}
|
* The obvious example — the lack of the condition expression in [UIfExpression], e.g. `if () return`.
|
||||||
|
* [UIfExpression.condition] is required to return not-null values,
|
||||||
|
* and Uast implementation should return something instead of `null` in this case.
|
||||||
|
*
|
||||||
|
* Use [UastEmptyExpression] in this case.
|
||||||
|
*/
|
||||||
|
object UastEmptyExpression : UExpression {
|
||||||
|
override val containingElement: UElement?
|
||||||
|
get() = null
|
||||||
|
|
||||||
class EmptyUExpression(override val parent: UElement) : UExpression {
|
override fun asLogString() = "EmptyExpression"
|
||||||
override fun logString() = "EmptyExpression"
|
|
||||||
}
|
}
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
|
||||||
|
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a source file.
|
|
||||||
* File is the topmost element of the UElement hierarchy.
|
|
||||||
* Files should not be nested, thus the [parent] property should always return null.
|
|
||||||
*/
|
|
||||||
interface UFile: UElement {
|
|
||||||
/**
|
|
||||||
* Returns the qualified package name of this file.
|
|
||||||
* Could be an empty string if the package is "default", or null if the package directive is not present in this file.
|
|
||||||
*/
|
|
||||||
val packageFqName: String?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of import statements.
|
|
||||||
*/
|
|
||||||
val importStatements: List<UImportStatement>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of declarations in this file (classes, properties, functions, etc).
|
|
||||||
*/
|
|
||||||
val declarations: List<UDeclaration>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns list of classes containing in this file.
|
|
||||||
*/
|
|
||||||
val classes: List<UClass>
|
|
||||||
get() = declarations.filterIsInstance<UClass>()
|
|
||||||
|
|
||||||
override val parent: UElement?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
|
||||||
if (visitor.visitFile(this)) return
|
|
||||||
declarations.acceptList(visitor)
|
|
||||||
importStatements.acceptList(visitor)
|
|
||||||
visitor.afterVisitFile(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun logString() = "UFile (package = $packageFqName)\n" + declarations.joinToString("\n") { it.logString().withMargin }
|
|
||||||
|
|
||||||
override fun renderString() = buildString {
|
|
||||||
if (!packageFqName.isNullOrBlank()) {
|
|
||||||
appendln("package $packageFqName")
|
|
||||||
appendln()
|
|
||||||
}
|
|
||||||
|
|
||||||
declarations.forEach { appendln(it.renderString()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+11
-7
@@ -14,16 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.uast.UElement
|
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
class KotlinDumbUElement(
|
class UIdentifier(
|
||||||
override val psi: PsiElement?,
|
override val psi: PsiElement?,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : KotlinAbstractUElement(), UElement, PsiElementBacked {
|
) : UElement, PsiElementBacked {
|
||||||
override fun logString() = "KotlinDumbUElement"
|
/**
|
||||||
override fun renderString() = "<stub@$psi>"
|
* Returns the identifier name.
|
||||||
|
*/
|
||||||
|
val name: String
|
||||||
|
get() = psi?.text ?: "<error>"
|
||||||
|
|
||||||
|
override fun asLogString() = "Identifier ($name)"
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface for the [UElement] which has a name.
|
||||||
|
*/
|
||||||
|
interface UNamed {
|
||||||
|
/**
|
||||||
|
* Returns the element name.
|
||||||
|
*/
|
||||||
|
val name: String?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the element name is equal to the passed name.
|
||||||
|
*
|
||||||
|
* @param name the name to check against
|
||||||
|
* @return true if the element name is equal to [name], false otherwise.
|
||||||
|
*/
|
||||||
|
fun matchesName(name: String) = this.name == name
|
||||||
|
}
|
||||||
@@ -0,0 +1,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?
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
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 <A : Any?> accept(visitor: PsiTypeVisitor<A>) = visitor.visitType(this)
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,6 +33,16 @@ interface UDoWhileExpression : ULoopExpression {
|
|||||||
*/
|
*/
|
||||||
val condition: UExpression
|
val condition: UExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an identifier for the 'do' keyword.
|
||||||
|
*/
|
||||||
|
val doIdentifier: UIdentifier
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an identifier for the 'while' keyword.
|
||||||
|
*/
|
||||||
|
val whileIdentifier: UIdentifier
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitDoWhileExpression(this)) return
|
if (visitor.visitDoWhileExpression(this)) return
|
||||||
condition.accept(visitor)
|
condition.accept(visitor)
|
||||||
@@ -39,11 +50,11 @@ interface UDoWhileExpression : ULoopExpression {
|
|||||||
visitor.afterVisitDoWhileExpression(this)
|
visitor.afterVisitDoWhileExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = buildString {
|
override fun asRenderString() = buildString {
|
||||||
append("do ")
|
append("do ")
|
||||||
append(body.renderString())
|
append(body.asRenderString())
|
||||||
appendln("while (${condition.renderString()})")
|
appendln("while (${condition.asRenderString()})")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UDoWhileExpression", condition, body)
|
override fun asLogString() = log("UDoWhileExpression", condition, body)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,29 +31,33 @@ interface UForEachExpression : ULoopExpression {
|
|||||||
/**
|
/**
|
||||||
* Returns the loop variable.
|
* Returns the loop variable.
|
||||||
*/
|
*/
|
||||||
val variable: UVariable
|
val variable: UParameter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the iterated value (collection, sequence, iterable etc.)
|
* Returns the iterated value (collection, sequence, iterable etc.)
|
||||||
*/
|
*/
|
||||||
val iteratedValue: UExpression
|
val iteratedValue: UExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the identifier for the 'for' ('foreach') keyword.
|
||||||
|
*/
|
||||||
|
val forIdentifier: UIdentifier
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitForEachExpression(this)) return
|
if (visitor.visitForEachExpression(this)) return
|
||||||
variable.accept(visitor)
|
|
||||||
iteratedValue.accept(visitor)
|
iteratedValue.accept(visitor)
|
||||||
body.accept(visitor)
|
body.accept(visitor)
|
||||||
visitor.afterVisitForEachExpression(this)
|
visitor.afterVisitForEachExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = buildString {
|
override fun asRenderString() = buildString {
|
||||||
append("for (")
|
append("for (")
|
||||||
append(variable.name)
|
append(variable.name)
|
||||||
append(" : ")
|
append(" : ")
|
||||||
append(iteratedValue.renderString())
|
append(iteratedValue.asRenderString())
|
||||||
append(") ")
|
append(") ")
|
||||||
append(body.renderString())
|
append(body.asRenderString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UForEachExpression", variable, iteratedValue, body)
|
override fun asLogString() = log("UForEachExpression", variable, iteratedValue, body)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,6 +43,11 @@ interface UForExpression : ULoopExpression {
|
|||||||
*/
|
*/
|
||||||
val update: UExpression?
|
val update: UExpression?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the identifier for the 'for' keyword.
|
||||||
|
*/
|
||||||
|
val forIdentifier: UIdentifier
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitForExpression(this)) return
|
if (visitor.visitForExpression(this)) return
|
||||||
declaration?.accept(visitor)
|
declaration?.accept(visitor)
|
||||||
@@ -51,16 +57,16 @@ interface UForExpression : ULoopExpression {
|
|||||||
visitor.afterVisitForExpression(this)
|
visitor.afterVisitForExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = buildString {
|
override fun asRenderString() = buildString {
|
||||||
append("for (")
|
append("for (")
|
||||||
declaration?.let { append(it.renderString()) }
|
declaration?.let { append(it.asRenderString()) }
|
||||||
append("; ")
|
append("; ")
|
||||||
condition?.let { append(it.renderString()) }
|
condition?.let { append(it.asRenderString()) }
|
||||||
append("; ")
|
append("; ")
|
||||||
update?.let { append(it.renderString()) }
|
update?.let { append(it.asRenderString()) }
|
||||||
append(") ")
|
append(") ")
|
||||||
append(body.renderString())
|
append(body.asRenderString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UForExpression", declaration, condition, update, body)
|
override fun asLogString() = log("UForExpression", declaration, condition, update, body)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,43 +42,53 @@ interface UIfExpression : UExpression {
|
|||||||
/**
|
/**
|
||||||
* Returns the expression which is executed if the condition is true, or null if the expression is empty.
|
* Returns the expression which is executed if the condition is true, or null if the expression is empty.
|
||||||
*/
|
*/
|
||||||
val thenBranch: UExpression?
|
val thenExpression: UExpression?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the expression which is executed if the condition is false, or null if the expression is empty.
|
* Returns the expression which is executed if the condition is false, or null if the expression is empty.
|
||||||
*/
|
*/
|
||||||
val elseBranch: UExpression?
|
val elseExpression: UExpression?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the expression is ternary (condition ? trueExpression : falseExpression).
|
* Returns true if the expression is ternary (condition ? trueExpression : falseExpression).
|
||||||
*/
|
*/
|
||||||
val isTernary: Boolean
|
val isTernary: Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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?
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitIfExpression(this)) return
|
if (visitor.visitIfExpression(this)) return
|
||||||
condition.accept(visitor)
|
condition.accept(visitor)
|
||||||
thenBranch?.accept(visitor)
|
thenExpression?.accept(visitor)
|
||||||
elseBranch?.accept(visitor)
|
elseExpression?.accept(visitor)
|
||||||
visitor.afterVisitIfExpression(this)
|
visitor.afterVisitIfExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UIfExpression", condition, thenBranch, elseBranch)
|
override fun asLogString() = log("UIfExpression", condition, thenExpression, elseExpression)
|
||||||
|
|
||||||
override fun renderString() = buildString {
|
override fun asRenderString() = buildString {
|
||||||
if (isTernary) {
|
if (isTernary) {
|
||||||
append("(" + condition.renderString() + ")")
|
append("(" + condition.asRenderString() + ")")
|
||||||
append(" ? ")
|
append(" ? ")
|
||||||
append("(" + (thenBranch?.renderString() ?: "<noexpr>") + ")")
|
append("(" + (thenExpression?.asRenderString() ?: "<noexpr>") + ")")
|
||||||
append(" : ")
|
append(" : ")
|
||||||
append("(" + (elseBranch?.renderString() ?: "<noexpr>") + ")")
|
append("(" + (elseExpression?.asRenderString() ?: "<noexpr>") + ")")
|
||||||
} else {
|
} else {
|
||||||
append("if (${condition.renderString()}) ")
|
append("if (${condition.asRenderString()}) ")
|
||||||
thenBranch?.let { append(it.renderString()) }
|
thenExpression?.let { append(it.asRenderString()) }
|
||||||
val elseBranch = elseBranch
|
val elseBranch = elseExpression
|
||||||
if (elseBranch != null && elseBranch !is EmptyUExpression) {
|
if (elseBranch != null && elseBranch !is UastEmptyExpression) {
|
||||||
if (thenBranch !is UBlockExpression) append(" ")
|
if (thenExpression !is UBlockExpression) append(" ")
|
||||||
append("else ")
|
append("else ")
|
||||||
append(elseBranch.renderString())
|
append(elseBranch.asRenderString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the loop expression.
|
* Represents a loop expression.
|
||||||
*/
|
*/
|
||||||
interface ULoopExpression : UExpression {
|
interface ULoopExpression : UExpression {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,17 +32,22 @@ import org.jetbrains.uast.visitor.UastVisitor
|
|||||||
* conditional expression.
|
* conditional expression.
|
||||||
*/
|
*/
|
||||||
interface USwitchExpression : UExpression {
|
interface USwitchExpression : UExpression {
|
||||||
/*
|
/**
|
||||||
Returns the expression on which the `switch` expression is performed.
|
Returns the expression on which the `switch` expression is performed.
|
||||||
*/
|
*/
|
||||||
val expression: UExpression?
|
val expression: UExpression?
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Returns the switch body.
|
Returns the switch body.
|
||||||
Body should contain [USwitchClauseExpression] expressions.
|
The body should contain [USwitchClauseExpression] expressions.
|
||||||
*/
|
*/
|
||||||
val body: UExpression
|
val body: UExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an identifier for the 'switch' ('case', 'when', ...) keyword.
|
||||||
|
*/
|
||||||
|
val switchIdentifier: UIdentifier
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitSwitchExpression(this)) return
|
if (visitor.visitSwitchExpression(this)) return
|
||||||
expression?.accept(visitor)
|
expression?.accept(visitor)
|
||||||
@@ -48,11 +55,12 @@ interface USwitchExpression : UExpression {
|
|||||||
visitor.afterVisitSwitchExpression(this)
|
visitor.afterVisitSwitchExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("USwitchExpression", expression, body)
|
override fun asLogString() = log("USwitchExpression", expression, body)
|
||||||
override fun renderString() = buildString {
|
|
||||||
val expr = expression?.let { "(" + it.renderString() + ") " } ?: ""
|
override fun asRenderString() = buildString {
|
||||||
|
val expr = expression?.let { "(" + it.asRenderString() + ") " } ?: ""
|
||||||
appendln("switch $expr")
|
appendln("switch $expr")
|
||||||
appendln(body.renderString())
|
appendln(body.asRenderString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,8 +82,8 @@ interface USwitchClauseExpression : UExpression {
|
|||||||
visitor.afterVisitSwitchClauseExpression(this)
|
visitor.afterVisitSwitchClauseExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = (caseValues?.joinToString { it.renderString() } ?: "else") + " -> "
|
override fun asRenderString() = (caseValues?.joinToString { it.asRenderString() } ?: "else") + " -> "
|
||||||
override fun logString() = log("USwitchClauseExpression", caseValues)
|
override fun asLogString() = log("USwitchClauseExpression", caseValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,6 +105,6 @@ interface USwitchClauseExpressionWithBody : USwitchClauseExpression {
|
|||||||
visitor.afterVisitSwitchClauseExpression(this)
|
visitor.afterVisitSwitchClauseExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = (caseValues?.joinToString { it.renderString() } ?: "else") + " -> " + body.renderString()
|
override fun asRenderString() = (caseValues?.joinToString { it.asRenderString() } ?: "else") + " -> " + body.asRenderString()
|
||||||
override fun logString() = log("USwitchClauseExpressionWithBody", caseValues, body)
|
override fun asLogString() = log("USwitchClauseExpressionWithBody", caseValues, body)
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiResourceListElement
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
|
import org.jetbrains.uast.expressions.UTypeReferenceExpression
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,10 +43,15 @@ import org.jetbrains.uast.visitor.UastVisitor
|
|||||||
* expressions.
|
* expressions.
|
||||||
*/
|
*/
|
||||||
interface UTryExpression : UExpression {
|
interface UTryExpression : UExpression {
|
||||||
|
/**
|
||||||
|
* Returns `true` if the try expression is a try-with-resources expression.
|
||||||
|
*/
|
||||||
|
val isResources: Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of try resources, or null if this expression is not a `try-with-resources` expression.
|
* Returns the list of try resources, or null if this expression is not a `try-with-resources` expression.
|
||||||
*/
|
*/
|
||||||
val resources: List<UElement>?
|
val resources: List<PsiResourceListElement>?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the `try` clause expression.
|
* Returns the `try` clause expression.
|
||||||
@@ -58,26 +68,32 @@ interface UTryExpression : UExpression {
|
|||||||
*/
|
*/
|
||||||
val finallyClause: UExpression?
|
val finallyClause: UExpression?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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?
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitTryExpression(this)) return
|
if (visitor.visitTryExpression(this)) return
|
||||||
resources?.acceptList(visitor)
|
|
||||||
tryClause.accept(visitor)
|
tryClause.accept(visitor)
|
||||||
catchClauses.acceptList(visitor)
|
catchClauses.acceptList(visitor)
|
||||||
finallyClause?.accept(visitor)
|
finallyClause?.accept(visitor)
|
||||||
visitor.afterVisitTryExpression(this)
|
visitor.afterVisitTryExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = buildString {
|
override fun asRenderString() = buildString {
|
||||||
append("try ")
|
append("try ")
|
||||||
appendln(tryClause.renderString().trim('\n'))
|
appendln(tryClause.asRenderString().trim('\n', '\r'))
|
||||||
catchClauses.forEach { appendln(it.renderString().trim('\n')) }
|
catchClauses.forEach { appendln(it.asRenderString().trim('\n', '\r')) }
|
||||||
finallyClause?.let { append("finally ").append(it.renderString().trim('\n')) }
|
finallyClause?.let { append("finally ").append(it.asRenderString().trim('\n', '\r')) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = "UTryExpression\n" +
|
override fun asLogString() = log("UTryExpression", tryClause, catchClauses, finallyClause)
|
||||||
tryClause.logString().withMargin +
|
|
||||||
catchClauses.joinToString("\n") { it.logString().withMargin } +
|
|
||||||
(finallyClause?.let { it.logString().withMargin } ?: "<no finally clause>" )
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -92,21 +108,25 @@ interface UCatchClause : UElement {
|
|||||||
/**
|
/**
|
||||||
* Returns the exception parameter variables for this `catch` clause.
|
* Returns the exception parameter variables for this `catch` clause.
|
||||||
*/
|
*/
|
||||||
val parameters: List<UVariable>
|
val parameters: List<UParameter>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the exception types for this `catch` clause.
|
* Returns the exception type references for this `catch` clause.
|
||||||
*/
|
*/
|
||||||
val types: List<UType>
|
val typeReferences: List<UTypeReferenceExpression>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the expression types for this `catch` clause.
|
||||||
|
*/
|
||||||
|
val types: List<PsiType>
|
||||||
|
get() = typeReferences.map { it.type }
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitCatchClause(this)) return
|
if (visitor.visitCatchClause(this)) return
|
||||||
body.accept(visitor)
|
body.accept(visitor)
|
||||||
parameters.acceptList(visitor)
|
|
||||||
types.acceptList(visitor)
|
|
||||||
visitor.afterVisitCatchClause(this)
|
visitor.afterVisitCatchClause(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UCatchClause", body)
|
override fun asLogString() = log("UCatchClause", body)
|
||||||
override fun renderString() = "catch (e) " + body.renderString()
|
override fun asRenderString() = "catch (e) " + body.asRenderString()
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,6 +33,11 @@ interface UWhileExpression : ULoopExpression {
|
|||||||
*/
|
*/
|
||||||
val condition: UExpression
|
val condition: UExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an identifier for the 'while' keyword.
|
||||||
|
*/
|
||||||
|
val whileIdentifier: UIdentifier
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitWhileExpression(this)) return
|
if (visitor.visitWhileExpression(this)) return
|
||||||
condition.accept(visitor)
|
condition.accept(visitor)
|
||||||
@@ -39,10 +45,10 @@ interface UWhileExpression : ULoopExpression {
|
|||||||
visitor.afterVisitWhileExpression(this)
|
visitor.afterVisitWhileExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = buildString {
|
override fun asRenderString() = buildString {
|
||||||
append("while (${condition.renderString()}) ")
|
append("while (${condition.asRenderString()}) ")
|
||||||
append(body.renderString())
|
append(body.asRenderString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UWhileExpression", condition, body)
|
override fun asLogString() = log("UWhileExpression", condition, body)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiAnnotation
|
||||||
|
|
||||||
|
class SimpleUAnnotation(
|
||||||
|
psi: PsiAnnotation,
|
||||||
|
override val containingElement: UElement?
|
||||||
|
) : UAnnotation, PsiAnnotation by psi {
|
||||||
|
override val psi: PsiAnnotation = unwrap(psi)
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
fun unwrap(psi: PsiAnnotation): PsiAnnotation {
|
||||||
|
val unwrapped = if (psi is UAnnotation) psi.psi else psi
|
||||||
|
assert(unwrapped !is UElement)
|
||||||
|
return unwrapped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiAnnotation
|
||||||
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An annotation wrapper to be used in [UastVisitor].
|
||||||
|
*/
|
||||||
|
interface UAnnotation : UElement, PsiAnnotation, PsiElementBacked {
|
||||||
|
/**
|
||||||
|
* Returns the original annotation (which is *always* unwrapped [PsiAnnotation], never a [UAnnotation]).
|
||||||
|
*/
|
||||||
|
override val psi: PsiAnnotation
|
||||||
|
|
||||||
|
override fun getOriginalElement() = psi.originalElement
|
||||||
|
|
||||||
|
override fun asLogString() = "UAnnotation"
|
||||||
|
|
||||||
|
override fun accept(visitor: UastVisitor) {
|
||||||
|
if (visitor.visitAnnotation(this)) return
|
||||||
|
visitor.afterVisitAnnotation(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,152 +1,45 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiAnonymousClass
|
||||||
|
import com.intellij.psi.PsiClass
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a JVM class (ordinary class, interface, annotation, singleton, etc.).
|
* A class wrapper to be used in [UastVisitor].
|
||||||
*/
|
*/
|
||||||
interface UClass : UDeclaration, UFqNamed, UModifierOwner, UVisibilityOwner, UAnnotated {
|
interface UClass : UDeclaration, PsiClass {
|
||||||
/**
|
override val psi: PsiClass
|
||||||
* Returns the class simple (non-qualified) name.
|
|
||||||
* The simple class name is only for the debug purposes. Do not check against it in the production code.
|
|
||||||
*/
|
|
||||||
override val name: String
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the class is anonymous ([name] in this case should return a placeholder like "<anonymous>").
|
* Returns a [UClass] wrapper of the superclass of this class, or null if this class is [java.lang.Object].
|
||||||
*/
|
*/
|
||||||
val isAnonymous: Boolean
|
val uastSuperClass: UClass?
|
||||||
|
get() {
|
||||||
|
val superClass = superClass ?: return null
|
||||||
|
return getUastContext().convertWithParent(superClass)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the class kind (ordinary class, interface, annotation, etc.).
|
* Returns [UDeclaration] wrappers for the class declarations.
|
||||||
*/
|
*/
|
||||||
val kind: UastClassKind
|
val uastDeclarations: List<UDeclaration>
|
||||||
|
|
||||||
|
val uastFields: List<UVariable>
|
||||||
|
val uastInitializers: List<UClassInitializer>
|
||||||
|
val uastMethods: List<UMethod>
|
||||||
|
val uastNestedClasses: List<UClass>
|
||||||
|
|
||||||
/**
|
override fun asLogString() = "UClass (name = $name)"
|
||||||
* Returns the default type for this class.
|
|
||||||
*/
|
|
||||||
val defaultType: UType
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the class companions.
|
|
||||||
*/
|
|
||||||
val companions: List<UClass>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the class JVM name, or null if the JVM name is unknown.
|
|
||||||
*/
|
|
||||||
open val internalName: String?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the all supertypes of this class.
|
|
||||||
*/
|
|
||||||
val superTypes: List<UType>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns class declarations (nested classes, constructors, functions, variables, etc.).
|
|
||||||
* An empty (default) constructor also should be present.
|
|
||||||
*/
|
|
||||||
val declarations: List<UDeclaration>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns nested classes declared in this class.
|
|
||||||
*/
|
|
||||||
val nestedClasses: List<UClass>
|
|
||||||
get() = declarations.filterIsInstance<UClass>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns functions declared in this class.
|
|
||||||
*/
|
|
||||||
val functions: List<UFunction>
|
|
||||||
get() = declarations.filterIsInstance<UFunction>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns properties declared in this class.
|
|
||||||
*/
|
|
||||||
val properties: List<UVariable>
|
|
||||||
get() = declarations.filterIsInstance<UVariable>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns constructors declared in this class.
|
|
||||||
*/
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
val constructors: List<UFunction>
|
|
||||||
get() = declarations.filter { it is UFunction && it.kind == UastFunctionKind.CONSTRUCTOR } as List<UFunction>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the class is subclass of another.
|
|
||||||
*
|
|
||||||
* @param fqName qualified name of the class to check against
|
|
||||||
* @return true if the class is the *subclass* of the class with the specified [fqName],
|
|
||||||
* false if the class qualified name is [fqName] or if the class is not a subclass of the class with the specified [fqName]
|
|
||||||
*/
|
|
||||||
fun isSubclassOf(fqName: String) : Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the direct superclass of this class.
|
|
||||||
*
|
|
||||||
* @return null if the class has not a superclass (java.lang.Object).
|
|
||||||
*/
|
|
||||||
fun getSuperClass(context: UastContext): UClass?
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitClass(this)) return
|
if (visitor.visitClass(this)) return
|
||||||
nameElement?.accept(visitor)
|
uastAnnotations.acceptList(visitor)
|
||||||
declarations.acceptList(visitor)
|
uastDeclarations.acceptList(visitor)
|
||||||
annotations.acceptList(visitor)
|
|
||||||
visitor.afterVisitClass(this)
|
visitor.afterVisitClass(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = buildString {
|
|
||||||
appendWithSpace(visibility.name)
|
|
||||||
appendWithSpace(renderModifiers())
|
|
||||||
appendWithSpace(kind.text)
|
|
||||||
appendWithSpace(name)
|
|
||||||
|
|
||||||
val declarations = if (declarations.isEmpty()) "" else buildString {
|
|
||||||
appendln("{")
|
|
||||||
append(declarations.joinToString("\n\n") { it.renderString().trim('\n') }.withMargin)
|
|
||||||
append("\n}")
|
|
||||||
}
|
|
||||||
append(declarations)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun logString() = log("UClass ($name, kind = ${kind.text})", declarations)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object UClassNotResolved : UClass {
|
interface UAnonymousClass : UClass, PsiAnonymousClass {
|
||||||
override val isAnonymous = true
|
override val psi: PsiAnonymousClass
|
||||||
override val kind = UastClassKind.CLASS
|
|
||||||
override val visibility = UastVisibility.PRIVATE
|
|
||||||
override val superTypes = emptyList<UType>()
|
|
||||||
override val declarations = emptyList<UDeclaration>()
|
|
||||||
override fun isSubclassOf(fqName: String) = false
|
|
||||||
override val companions = emptyList<UClass>()
|
|
||||||
override val defaultType = UastErrorType
|
|
||||||
override val nameElement = null
|
|
||||||
override val parent = null
|
|
||||||
override val name = ERROR_NAME
|
|
||||||
override val fqName = null
|
|
||||||
override val internalName = null
|
|
||||||
|
|
||||||
override fun hasModifier(modifier: UastModifier) = false
|
|
||||||
override val annotations = emptyList<UAnnotation>()
|
|
||||||
|
|
||||||
override fun getSuperClass(context: UastContext) = null
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiClassInitializer
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class initializer wrapper to be used in [UastVisitor].
|
||||||
|
*/
|
||||||
|
interface UClassInitializer : UDeclaration, PsiClassInitializer {
|
||||||
|
override val psi: PsiClassInitializer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the body of this class initializer.
|
||||||
|
*/
|
||||||
|
val uastBody: UExpression
|
||||||
|
|
||||||
|
@Deprecated("Use uastBody instead.", ReplaceWith("uastBody"))
|
||||||
|
override fun getBody() = psi.body
|
||||||
|
|
||||||
|
override fun accept(visitor: UastVisitor) {
|
||||||
|
if (visitor.visitInitializer(this)) return
|
||||||
|
uastAnnotations.acceptList(visitor)
|
||||||
|
uastBody.accept(visitor)
|
||||||
|
visitor.afterVisitInitializer(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asLogString() = "UMethod (name = ${psi.name}"
|
||||||
|
}
|
||||||
@@ -1,57 +1,43 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiModifier
|
||||||
|
import com.intellij.psi.PsiModifierListOwner
|
||||||
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a declaration.
|
* A [PsiElement] declaration wrapper.
|
||||||
*/
|
*/
|
||||||
interface UDeclaration : UElement, UNamed {
|
interface UDeclaration : UElement, PsiElementBacked, PsiModifierListOwner {
|
||||||
/**
|
/**
|
||||||
* Returns an element for the name node, or null if the node does not exist in the underlying AST (Psi).
|
* Returns the original declaration (which is *always* unwrapped, never a [UDeclaration]).
|
||||||
*/
|
*/
|
||||||
val nameElement: UElement?
|
override val psi: PsiModifierListOwner
|
||||||
|
|
||||||
|
override fun getOriginalElement(): PsiElement? = psi.originalElement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the function name is [name], and the function containing class qualified name is [containingClassFqName].
|
* Returns the declaration name identifier, or null if the declaration is anonymous.
|
||||||
*
|
|
||||||
* @param containingClassFqName the required containing class qualified name.
|
|
||||||
* @param name the function name to check against.
|
|
||||||
* @return true if the call is a function call, the function name is [name],
|
|
||||||
* and the qualified name of the function direct containing class is [containingClassFqName],
|
|
||||||
* false otherwise.
|
|
||||||
*/
|
*/
|
||||||
open fun matchesNameWithContaining(containingClassFqName: String, name: String): Boolean {
|
val uastAnchor: UElement?
|
||||||
if (!matchesName(name)) return false
|
|
||||||
val containingClass = this.getContainingClass() ?: return false
|
|
||||||
return containingClass.matchesFqName(containingClassFqName)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
val uastAnnotations: List<UAnnotation>
|
||||||
visitor.visitElement(this)
|
|
||||||
visitor.afterVisitElement(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object UDeclarationNotResolved : UDeclaration {
|
/**
|
||||||
override val name = ERROR_NAME
|
* Returns `true` if this declaration has a [PsiModifier.STATIC] modifier.
|
||||||
override val nameElement = null
|
*/
|
||||||
override val parent = null
|
val isStatic: Boolean
|
||||||
|
get() = hasModifierProperty(PsiModifier.STATIC)
|
||||||
|
|
||||||
override fun logString() = "[!] $name"
|
/**
|
||||||
override fun renderString() = name
|
* 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]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Uast file.
|
||||||
|
*/
|
||||||
|
interface UFile : UElement {
|
||||||
|
/**
|
||||||
|
* Returns the original [PsiFile].
|
||||||
|
*/
|
||||||
|
val psi: PsiFile
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 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 all comments in file.
|
||||||
|
*/
|
||||||
|
val allCommentsInFile: List<UComment>
|
||||||
|
|
||||||
|
override fun asLogString() = "UFile"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [UFile] is a top-level element of the Uast hierarchy, thus the [containingElement] always returns null for it.
|
||||||
|
*/
|
||||||
|
override val containingElement: UElement?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
override fun accept(visitor: UastVisitor) {
|
||||||
|
if (visitor.visitFile(this)) return
|
||||||
|
imports.acceptList(visitor)
|
||||||
|
classes.acceptList(visitor)
|
||||||
|
visitor.afterVisitFile(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
|
||||||
|
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a function.
|
|
||||||
* Function could be a JVM method, a property accessor, a constructor, etc.
|
|
||||||
*/
|
|
||||||
interface UFunction : UDeclaration, UModifierOwner, UVisibilityOwner, UAnnotated {
|
|
||||||
/**
|
|
||||||
* Returns the function kind.
|
|
||||||
*/
|
|
||||||
val kind: UastFunctionKind
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the function value parameters.
|
|
||||||
*/
|
|
||||||
val valueParameters: List<UVariable>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the function value parameters count.
|
|
||||||
* Retrieving the parameter count could be faster than getting the [valueParameters.size],
|
|
||||||
* because there is no need to create actual [UVariable] instances.
|
|
||||||
*/
|
|
||||||
val valueParameterCount: Int
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the function type parameters.
|
|
||||||
*/
|
|
||||||
val typeParameters: List<UTypeReference>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the function type parameter count.
|
|
||||||
*/
|
|
||||||
val typeParameterCount: Int
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the function return type, or null if the function does not have a return type
|
|
||||||
* (e.g. it is a constructor).
|
|
||||||
*/
|
|
||||||
val returnType: UType?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the function body expression.
|
|
||||||
*/
|
|
||||||
val body: UExpression?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the function JVM descriptor (for example, "(ILjava/lang/String;)[I"), or null if the descriptor is unknown.
|
|
||||||
*/
|
|
||||||
open val bytecodeDescriptor: String?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the list of all super functions for this function.
|
|
||||||
*/
|
|
||||||
fun getSuperFunctions(context: UastContext): List<UFunction>
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
|
||||||
if (visitor.visitFunction(this)) return
|
|
||||||
nameElement?.accept(visitor)
|
|
||||||
valueParameters.acceptList(visitor)
|
|
||||||
body?.accept(visitor)
|
|
||||||
annotations.acceptList(visitor)
|
|
||||||
typeParameters.acceptList(visitor)
|
|
||||||
returnType?.accept(visitor)
|
|
||||||
visitor.afterVisitFunction(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun renderString(): String = buildString {
|
|
||||||
appendWithSpace(visibility.name)
|
|
||||||
appendWithSpace(renderModifiers())
|
|
||||||
append("fun ")
|
|
||||||
if (typeParameterCount > 0) {
|
|
||||||
append('<').append(typeParameters.joinToString { it.renderString() }).append("> ")
|
|
||||||
}
|
|
||||||
append(name)
|
|
||||||
append('(')
|
|
||||||
append(valueParameters.joinToString() { it.renderString() })
|
|
||||||
append(')')
|
|
||||||
returnType?.let { append(": " + it.renderString()) }
|
|
||||||
|
|
||||||
val body = body
|
|
||||||
val bodyRendered = when (body) {
|
|
||||||
null -> ""
|
|
||||||
is UBlockExpression -> " " + body.renderString()
|
|
||||||
else -> " = " + body.renderString()
|
|
||||||
}
|
|
||||||
append(bodyRendered)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun logString() = log("UFunction ($name, kind = ${kind.text}, paramCount = $valueParameterCount)", body)
|
|
||||||
}
|
|
||||||
|
|
||||||
object UFunctionNotResolved : UFunction {
|
|
||||||
override val kind = UastFunctionKind(ERROR_NAME)
|
|
||||||
override val valueParameters = emptyList<UVariable>()
|
|
||||||
override val valueParameterCount = 0
|
|
||||||
override val typeParameters = emptyList<UTypeReference>()
|
|
||||||
override val typeParameterCount = 0
|
|
||||||
override val returnType = null
|
|
||||||
override val body = null
|
|
||||||
override val visibility = UastVisibility.PRIVATE
|
|
||||||
override val nameElement = null
|
|
||||||
override val parent = null
|
|
||||||
override val name = ERROR_NAME
|
|
||||||
|
|
||||||
override fun hasModifier(modifier: UastModifier) = false
|
|
||||||
override fun getSuperFunctions(context: UastContext) = emptyList<UFunction>()
|
|
||||||
override val annotations = emptyList<UAnnotation>()
|
|
||||||
}
|
|
||||||
@@ -1,49 +1,26 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an import statement.
|
* Represents an import statement.
|
||||||
*/
|
*/
|
||||||
interface UImportStatement : UElement {
|
interface UImportStatement : UResolvable, UElement, PsiElementBacked {
|
||||||
/**
|
/**
|
||||||
* Returns the qualified name to import.
|
* Returns true if the statement is an import-on-demand (star-import) statement.
|
||||||
*/
|
*/
|
||||||
val fqNameToImport: String?
|
val isOnDemand: Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true is the import is a "star" import (on-demand, all-under).
|
* Returns the reference to the imported element.
|
||||||
*/
|
*/
|
||||||
val isStarImport: Boolean
|
val importReference: UElement?
|
||||||
|
|
||||||
/**
|
override fun asLogString() = "UImportStatement (onDemand = $isOnDemand)"
|
||||||
* Resolve the import statement to the declaration.
|
|
||||||
*
|
|
||||||
* @param context the Uast context
|
|
||||||
* @return the declaration element, or null if the declaration was not resolved.
|
|
||||||
*/
|
|
||||||
fun resolve(context: UastContext): UDeclaration?
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
visitor.visitImportStatement(this)
|
if (visitor.visitImportStatement(this)) return
|
||||||
visitor.afterVisitImportStatement(this)
|
visitor.afterVisitImportStatement(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = "UImport ($fqNameToImport)"
|
|
||||||
override fun renderString() = "import ${fqNameToImport ?: ""}"
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiAnnotationMethod
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A method visitor to be used in [UastVisitor].
|
||||||
|
*/
|
||||||
|
interface UMethod : UDeclaration, PsiMethod {
|
||||||
|
override val psi: PsiMethod
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the body expression (which can be also a [UBlockExpression]).
|
||||||
|
*/
|
||||||
|
val uastBody: UExpression?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the method parameters.
|
||||||
|
*/
|
||||||
|
val uastParameters: List<UParameter>
|
||||||
|
|
||||||
|
@Deprecated("Use uastBody instead.", ReplaceWith("uastBody"))
|
||||||
|
override fun getBody() = psi.body
|
||||||
|
|
||||||
|
override fun accept(visitor: UastVisitor) {
|
||||||
|
if (visitor.visitMethod(this)) return
|
||||||
|
uastAnnotations.acceptList(visitor)
|
||||||
|
uastParameters.acceptList(visitor)
|
||||||
|
uastBody?.accept(visitor)
|
||||||
|
visitor.afterVisitMethod(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asLogString() = "UMethod (name = $name)"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UAnnotationMethod : UMethod, PsiAnnotationMethod {
|
||||||
|
override val psi: PsiAnnotationMethod
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default value of this annotation method.
|
||||||
|
*/
|
||||||
|
val uastDefaultValue: UExpression?
|
||||||
|
|
||||||
|
override fun getDefaultValue() = psi.defaultValue
|
||||||
|
|
||||||
|
override fun accept(visitor: UastVisitor) {
|
||||||
|
if (visitor.visitMethod(this)) return
|
||||||
|
uastAnnotations.acceptList(visitor)
|
||||||
|
uastParameters.acceptList(visitor)
|
||||||
|
uastBody?.accept(visitor)
|
||||||
|
uastDefaultValue?.accept(visitor)
|
||||||
|
visitor.afterVisitMethod(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asLogString() = "UAnnotationMethod (name = $name)"
|
||||||
|
}
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
|
||||||
|
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the type.
|
|
||||||
* The abstraction is quite simple. Intersection types, union types, platform types are yet to be supported.
|
|
||||||
*/
|
|
||||||
interface UType : UElement, UNamed, UFqNamed, UAnnotated, UResolvable {
|
|
||||||
/**
|
|
||||||
* Returns the simple (non-qualified) type name.
|
|
||||||
* The simple type name is only for the debug purposes. Do not check against it in the production code.
|
|
||||||
*/
|
|
||||||
override val name: String
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the type is either a boxed or an unboxed [Integer], false otherwise.
|
|
||||||
*/
|
|
||||||
val isInt: Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the type is either a boxed or an unboxed [Short], false otherwise.
|
|
||||||
*/
|
|
||||||
val isShort: Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the type is either a boxed or an unboxed [Long], false otherwise.
|
|
||||||
*/
|
|
||||||
val isLong: Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the type is either a boxed or an unboxed [Float], false otherwise.
|
|
||||||
*/
|
|
||||||
val isFloat: Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the type is either a boxed or an unboxed [Double], false otherwise.
|
|
||||||
*/
|
|
||||||
val isDouble: Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the type is either a boxed or an unboxed [Character], false otherwise.
|
|
||||||
*/
|
|
||||||
val isChar: Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the type is either a boxed or an unboxed [Boolean], false otherwise.
|
|
||||||
*/
|
|
||||||
val isBoolean: Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the type is either a boxed or an unboxed [Byte], false otherwise.
|
|
||||||
*/
|
|
||||||
val isByte: Boolean
|
|
||||||
|
|
||||||
override fun logString() = "UType ($name)"
|
|
||||||
override fun renderString() = name
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the [UClass] declaration element for this type.
|
|
||||||
*
|
|
||||||
* @param context the Uast context
|
|
||||||
* @return the [UClass] declaration element, or null if the class was not resolved.
|
|
||||||
*/
|
|
||||||
override fun resolve(context: UastContext): UClass?
|
|
||||||
|
|
||||||
override fun resolveOrEmpty(context: UastContext) = resolve(context) ?: UClassNotResolved
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
|
||||||
if (visitor.visitType(this)) return
|
|
||||||
annotations.acceptList(visitor)
|
|
||||||
visitor.afterVisitType(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a type reference.
|
|
||||||
*/
|
|
||||||
interface UTypeReference : UDeclaration, UResolvable {
|
|
||||||
override fun renderString() = ""
|
|
||||||
override fun logString() = log("UTypeReference")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the [UClass] declaration for this type reference.
|
|
||||||
*
|
|
||||||
* @param context the Uast context
|
|
||||||
* @return the [UClass] declaration element, or null if the class was not resolved.
|
|
||||||
*/
|
|
||||||
override fun resolve(context: UastContext): UClass?
|
|
||||||
|
|
||||||
override fun resolveOrEmpty(context: UastContext) = resolve(context) ?: UClassNotResolved
|
|
||||||
}
|
|
||||||
|
|
||||||
object UastErrorType : UType, NoAnnotations {
|
|
||||||
override val isInt = false
|
|
||||||
override val isLong = false
|
|
||||||
override val isShort = false
|
|
||||||
override val isFloat = false
|
|
||||||
override val isDouble = false
|
|
||||||
override val isChar = false
|
|
||||||
override val isByte = false
|
|
||||||
override val parent = null
|
|
||||||
override val name = ERROR_NAME
|
|
||||||
override val fqName = null
|
|
||||||
override val isBoolean = false
|
|
||||||
override fun resolve(context: UastContext) = null
|
|
||||||
}
|
|
||||||
@@ -1,95 +1,70 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
import org.jetbrains.uast.kinds.UastVariableInitialierKind
|
import com.intellij.psi.*
|
||||||
|
import org.jetbrains.uast.expressions.UTypeReferenceExpression
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
interface UVariable : UDeclaration, UModifierOwner, UVisibilityOwner, UAnnotated {
|
/**
|
||||||
/**
|
* A variable wrapper to be used in [UastVisitor].
|
||||||
* Return the variable initializer (or the default value for value parameter), or null if the variable is not initialized.
|
*/
|
||||||
*/
|
interface UVariable : UDeclaration, PsiVariable {
|
||||||
val initializer: UExpression?
|
override val psi: PsiVariable
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the variable initializer kind (simple initializer, property delegation, etc.).
|
* Returns the variable initializer or the parameter default value, or null if the variable has not an initializer.
|
||||||
*/
|
*/
|
||||||
val initializerKind: UastVariableInitialierKind
|
val uastInitializer: UExpression?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the variable kind.
|
* Returns variable type reference.
|
||||||
*/
|
*/
|
||||||
val kind: UastVariableKind
|
val typeReference: UTypeReferenceExpression?
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the variable type.
|
|
||||||
*/
|
|
||||||
val type: UType
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the list of accessors if the variable is a property, or null otherwise.
|
|
||||||
*/
|
|
||||||
open val accessors: List<UFunction>?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitVariable(this)) return
|
if (visitor.visitVariable(this)) return
|
||||||
nameElement?.accept(visitor)
|
uastAnnotations.acceptList(visitor)
|
||||||
initializer?.accept(visitor)
|
uastInitializer?.accept(visitor)
|
||||||
annotations.acceptList(visitor)
|
|
||||||
type.accept(visitor)
|
|
||||||
visitor.afterVisitVariable(this)
|
visitor.afterVisitVariable(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString(): String = buildString {
|
@Deprecated("Use uastInitializer instead.", ReplaceWith("uastInitializer"))
|
||||||
if (kind != UastVariableKind.VALUE_PARAMETER) appendWithSpace(visibility.name)
|
override fun getInitializer() = psi.initializer
|
||||||
appendWithSpace(renderModifiers())
|
|
||||||
if (kind != UastVariableKind.VALUE_PARAMETER) append("var ")
|
|
||||||
append(name)
|
|
||||||
append(": ")
|
|
||||||
append(type.name)
|
|
||||||
if (initializer != null && initializer !is EmptyUExpression) {
|
|
||||||
append(" = ")
|
|
||||||
append(initializer!!.renderString())
|
|
||||||
}
|
|
||||||
|
|
||||||
accessors?.let {
|
override fun asLogString() = "UVariable (name = $name)"
|
||||||
appendln()
|
|
||||||
it.forEachIndexed { i, accessor ->
|
override fun asRenderString() = buildString {
|
||||||
this@buildString.append(accessor.renderString().withMargin)
|
val modifiers = PsiModifier.MODIFIERS.filter { psi.hasModifierProperty(it) }.joinToString(" ")
|
||||||
if ((i + 1) < it.size) appendln()
|
if (modifiers.isNotEmpty()) append(modifiers).append(' ')
|
||||||
}
|
append("var ").append(psi.name).append(": ").append(psi.type.getCanonicalText(false))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = "UVariable ($name, kind = ${kind.name})\n" +
|
|
||||||
(initializer?.let { it.logString().withMargin } ?: "<no initializer>")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object UVariableNotResolved : UVariable {
|
interface UParameter : UVariable, PsiParameter {
|
||||||
override val initializer = null
|
override val psi: PsiParameter
|
||||||
override val initializerKind = UastVariableInitialierKind.NO_INITIALIZER
|
}
|
||||||
override val kind = UastVariableKind(ERROR_NAME)
|
|
||||||
override val type = UastErrorType
|
|
||||||
override val nameElement = null
|
|
||||||
override val parent = null
|
|
||||||
override val name = ERROR_NAME
|
|
||||||
override val visibility = UastVisibility.LOCAL
|
|
||||||
|
|
||||||
override fun hasModifier(modifier: UastModifier) = false
|
interface UField : UVariable, PsiField {
|
||||||
override val annotations = emptyList<UAnnotation>()
|
override val psi: PsiField
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ULocalVariable : UVariable, PsiLocalVariable {
|
||||||
|
override val psi: PsiLocalVariable
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UEnumConstant : UField, UCallExpression, PsiEnumConstant {
|
||||||
|
override val psi: PsiEnumConstant
|
||||||
|
|
||||||
|
override fun asLogString() = "UEnumConstant (name = ${psi.name}"
|
||||||
|
|
||||||
|
override fun accept(visitor: UastVisitor) {
|
||||||
|
if (visitor.visitVariable(this)) return
|
||||||
|
uastAnnotations.acceptList(visitor)
|
||||||
|
methodIdentifier?.accept(visitor)
|
||||||
|
classReference?.accept(visitor)
|
||||||
|
valueArguments.acceptList(visitor)
|
||||||
|
visitor.afterVisitVariable(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asRenderString() = name ?: "<ERROR>"
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,6 +40,7 @@ interface UArrayAccessExpression : UExpression {
|
|||||||
visitor.afterVisitArrayAccessExpression(this)
|
visitor.afterVisitArrayAccessExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UArrayAccessExpression", receiver, indices)
|
override fun asLogString() = log("UArrayAccessExpression", receiver, indices)
|
||||||
override fun renderString() = receiver.renderString() + indices.joinToString(prefix = "[", postfix = "]") { it.renderString() }
|
override fun asRenderString() = receiver.asRenderString() +
|
||||||
|
indices.joinToString(prefix = "[", postfix = "]") { it.asRenderString() }
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,15 +27,27 @@ interface UBinaryExpression : UExpression {
|
|||||||
*/
|
*/
|
||||||
val leftOperand: UExpression
|
val leftOperand: UExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the right operand.
|
||||||
|
*/
|
||||||
|
val rightOperand: UExpression
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the binary operator.
|
* Returns the binary operator.
|
||||||
*/
|
*/
|
||||||
val operator: UastBinaryOperator
|
val operator: UastBinaryOperator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the right operand.
|
* Returns the operator identifier.
|
||||||
*/
|
*/
|
||||||
val rightOperand: UExpression
|
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?
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitBinaryExpression(this)) return
|
if (visitor.visitBinaryExpression(this)) return
|
||||||
@@ -43,8 +56,10 @@ interface UBinaryExpression : UExpression {
|
|||||||
visitor.afterVisitBinaryExpression(this)
|
visitor.afterVisitBinaryExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() =
|
override fun asLogString() =
|
||||||
"UBinaryExpression (${operator.text})\n" + leftOperand.logString().withMargin + "\n" + rightOperand.logString().withMargin
|
"UBinaryExpression (${operator.text})" + LINE_SEPARATOR +
|
||||||
|
leftOperand.asLogString().withMargin + LINE_SEPARATOR +
|
||||||
|
rightOperand.asLogString().withMargin
|
||||||
|
|
||||||
override fun renderString() = leftOperand.renderString() + ' ' + operator.text + ' ' + rightOperand.renderString()
|
override fun asRenderString() = leftOperand.asRenderString() + ' ' + operator.text + ' ' + rightOperand.asRenderString()
|
||||||
}
|
}
|
||||||
+12
-7
@@ -15,6 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
|
import org.jetbrains.uast.expressions.UTypeReferenceExpression
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,22 +36,23 @@ interface UBinaryExpressionWithType : UExpression {
|
|||||||
val operationKind: UastBinaryExpressionWithTypeKind
|
val operationKind: UastBinaryExpressionWithTypeKind
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type.
|
* Returns the type reference of this expression.
|
||||||
*/
|
*/
|
||||||
val type: UType
|
val typeReference: UTypeReferenceExpression?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type reference.
|
* Returns the type.
|
||||||
*/
|
*/
|
||||||
val typeReference: UTypeReference?
|
val type: PsiType
|
||||||
|
|
||||||
override fun logString() = log("UBinaryExpressionWithType (${getExpressionType()?.name}, ${operationKind.name})", operand)
|
override fun asLogString() = log("UBinaryExpressionWithType " +
|
||||||
override fun renderString() = "${operand.renderString()} ${operationKind.name} ${type.name}"
|
"(${getExpressionType()?.name}, ${operationKind.name})", operand)
|
||||||
|
|
||||||
|
override fun asRenderString() = "${operand.asRenderString()} ${operationKind.name} ${type.name}"
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitBinaryExpressionWithType(this)) return
|
if (visitor.visitBinaryExpressionWithType(this)) return
|
||||||
operand.accept(visitor)
|
operand.accept(visitor)
|
||||||
type.accept(visitor)
|
|
||||||
visitor.afterVisitBinaryExpressionWithType(this)
|
visitor.afterVisitBinaryExpressionWithType(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,11 +34,11 @@ interface UBlockExpression : UExpression {
|
|||||||
visitor.afterVisitBlockExpression(this)
|
visitor.afterVisitBlockExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UBlockExpression", expressions)
|
override fun asLogString() = log("UBlockExpression", expressions)
|
||||||
|
|
||||||
override fun renderString() = buildString {
|
override fun asRenderString() = buildString {
|
||||||
appendln("{")
|
appendln("{")
|
||||||
expressions.forEach { appendln(it.renderString().withMargin) }
|
expressions.forEach { appendln(it.asRenderString().withMargin) }
|
||||||
appendln("}")
|
appendln("}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -32,6 +32,6 @@ interface UBreakExpression : UExpression {
|
|||||||
visitor.afterVisitBreakExpression(this)
|
visitor.afterVisitBreakExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = "UBreakExpression (" + (label ?: "<no label>") + ")"
|
override fun asLogString() = "UBreakExpression (" + (label ?: "<no label>") + ")"
|
||||||
override fun renderString() = label?.let { "break@$it" } ?: "break"
|
override fun asRenderString() = label?.let { "break@$it" } ?: "break"
|
||||||
}
|
}
|
||||||
@@ -15,64 +15,49 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
|
import org.jetbrains.uast.expressions.UReferenceExpression
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a call expression (function call, constructor call, array initializer).
|
* Represents a call expression (method/constructor call, array initializer).
|
||||||
*/
|
*/
|
||||||
interface UCallExpression : UExpression, UResolvable {
|
interface UCallExpression : UExpression, UResolvable {
|
||||||
val receiverType: UType?
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the call kind.
|
* Returns the call kind.
|
||||||
*/
|
*/
|
||||||
val kind: UastCallKind
|
val kind: UastCallKind
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the function reference expression if the call is a function call, null otherwise.
|
* 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 functionReference: USimpleReferenceExpression?
|
val methodName: String?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 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.
|
* Returns the class reference if the call is a constructor call, null otherwise.
|
||||||
*/
|
*/
|
||||||
val classReference: USimpleReferenceExpression?
|
val classReference: UReferenceExpression?
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the function name if the call is a function call, null otherwise.
|
|
||||||
*
|
|
||||||
* [functionName] should only be used in debug messages.
|
|
||||||
* Use [matchesFunctionName] to check against the name.
|
|
||||||
*/
|
|
||||||
val functionName: String?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an element for the function name node, or null if the node does not exist in the underlying AST (Psi).
|
|
||||||
*/
|
|
||||||
val functionNameElement: UElement?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the function name is [name].
|
|
||||||
*
|
|
||||||
* @param name the name to check against.
|
|
||||||
* @return true if the call is a function call, and the function name is [name], false otherwise.
|
|
||||||
*/
|
|
||||||
open fun matchesFunctionName(name: String) = functionName == name
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the function name is [name], and the function containing class qualified name is [containingClassFqName].
|
|
||||||
*
|
|
||||||
* @param containingClassFqName the required containing class qualified name.
|
|
||||||
* @param name the function name to check against.
|
|
||||||
* @return true if the call is a function call, the function name is [name],
|
|
||||||
* and the qualified name of the function direct containing class is [containingClassFqName],
|
|
||||||
* false otherwise.
|
|
||||||
*/
|
|
||||||
open fun matchesFunctionNameWithContaining(containingClassFqName: String, name: String): Boolean {
|
|
||||||
if (!matchesFunctionName(name)) return false
|
|
||||||
val containingClass = parent as? UClass ?: return false
|
|
||||||
return containingClass.matchesFqName(containingClassFqName)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value argument count.
|
* Returns the value argument count.
|
||||||
@@ -93,40 +78,35 @@ interface UCallExpression : UExpression, UResolvable {
|
|||||||
val typeArgumentCount: Int
|
val typeArgumentCount: Int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the function type arguments.
|
* Returns the type arguments for the call.
|
||||||
*/
|
*/
|
||||||
val typeArguments: List<UType>
|
val typeArguments: List<PsiType>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the call to the [UFunction] element.
|
* Returns the return type of the called function, or null if the call is not a function call.
|
||||||
*
|
|
||||||
* @param context the Uast context
|
|
||||||
* @return the [UFunction] element, or null if the reference was not resolved.
|
|
||||||
*/
|
*/
|
||||||
override fun resolve(context: UastContext): UFunction?
|
val returnType: PsiType?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to resolve the call to the [UFunction] element.
|
* Resolve the called method.
|
||||||
*
|
*
|
||||||
* @param context the Uast context
|
* @return the [PsiMethod], or null if the method was not resolved.
|
||||||
* @return the [UFunction] element, of [UFunctionNotResolved] if the reference was not resolved,
|
* Note that the [PsiMethod] is an unwrapped [PsiMethod], not a [UMethod].
|
||||||
* or the call is not a function call.
|
|
||||||
*/
|
*/
|
||||||
override fun resolveOrEmpty(context: UastContext): UFunction = resolve(context) ?: UFunctionNotResolved
|
override fun resolve(): PsiMethod?
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitCallExpression(this)) return
|
if (visitor.visitCallExpression(this)) return
|
||||||
functionReference?.accept(visitor)
|
methodIdentifier?.accept(visitor)
|
||||||
classReference?.accept(visitor)
|
classReference?.accept(visitor)
|
||||||
functionNameElement?.accept(visitor)
|
|
||||||
valueArguments.acceptList(visitor)
|
valueArguments.acceptList(visitor)
|
||||||
typeArguments.acceptList(visitor)
|
|
||||||
visitor.afterVisitCallExpression(this)
|
visitor.afterVisitCallExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UFunctionCallExpression ($kind, argCount = $valueArgumentCount)", functionReference, valueArguments)
|
override fun asLogString() = log("UCallExpression ($kind, argCount = $valueArgumentCount)", methodIdentifier, valueArguments)
|
||||||
override fun renderString(): String {
|
|
||||||
val ref = functionName ?: classReference?.renderString() ?: functionReference?.renderString() ?: "<noref>"
|
override fun asRenderString(): String {
|
||||||
return ref + "(" + valueArguments.joinToString { it.renderString() } + ")"
|
val ref = classReference?.asRenderString() ?: methodName ?: methodIdentifier?.asRenderString() ?: "<noref>"
|
||||||
|
return ref + "(" + valueArguments.joinToString { it.asRenderString() } + ")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+9
-7
@@ -15,12 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a callable reference expression, e.g. `Clazz::functionName`.
|
* Represents a callable reference expression, e.g. `Clazz::methodName`.
|
||||||
*/
|
*/
|
||||||
interface UCallableReferenceExpression : UExpression, UResolvable {
|
interface UCallableReferenceExpression : UExpression {
|
||||||
/**
|
/**
|
||||||
* Returns the qualifier expression.
|
* Returns the qualifier expression.
|
||||||
* Can be null if the [qualifierType] is known.
|
* Can be null if the [qualifierType] is known.
|
||||||
@@ -31,7 +33,7 @@ interface UCallableReferenceExpression : UExpression, UResolvable {
|
|||||||
* Returns the qualifier type.
|
* Returns the qualifier type.
|
||||||
* Can be null if the qualifier is an expression.
|
* Can be null if the qualifier is an expression.
|
||||||
*/
|
*/
|
||||||
val qualifierType: UType?
|
val qualifierType: PsiType?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the callable name.
|
* Returns the callable name.
|
||||||
@@ -41,14 +43,14 @@ interface UCallableReferenceExpression : UExpression, UResolvable {
|
|||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitCallableReferenceExpression(this)) return
|
if (visitor.visitCallableReferenceExpression(this)) return
|
||||||
qualifierExpression?.accept(visitor)
|
qualifierExpression?.accept(visitor)
|
||||||
qualifierType?.accept(visitor)
|
|
||||||
visitor.afterVisitCallableReferenceExpression(this)
|
visitor.afterVisitCallableReferenceExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = "UCallableReferenceExpression"
|
override fun asLogString() = "UCallableReferenceExpression"
|
||||||
override fun renderString() = buildString {
|
|
||||||
|
override fun asRenderString() = buildString {
|
||||||
qualifierExpression?.let {
|
qualifierExpression?.let {
|
||||||
append(it.renderString())
|
append(it.asRenderString())
|
||||||
} ?: qualifierType?.let {
|
} ?: qualifierType?.let {
|
||||||
append(it.name)
|
append(it.name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,22 +15,31 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the class literal expression, e.g. `Clazz.class`.
|
* Represents the class literal expression, e.g. `Clazz.class`.
|
||||||
*/
|
*/
|
||||||
interface UClassLiteralExpression : UExpression {
|
interface UClassLiteralExpression : UExpression {
|
||||||
override fun logString() = "UClassLiteralExpression"
|
override fun asLogString() = "UClassLiteralExpression"
|
||||||
override fun renderString() = type?.name.orEmpty() + "::class"
|
override fun asRenderString() = (type?.name) ?: "(${expression?.asRenderString() ?: "<no expression>"})" + "::class"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type for this class literal expression.
|
* Returns a type of this class literal, or null if the type can't be determined in a compile-time.
|
||||||
*/
|
*/
|
||||||
val type: UType?
|
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) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
visitor.visitClassLiteralExpression(this)
|
visitor.visitClassLiteralExpression(this)
|
||||||
|
expression?.accept(visitor)
|
||||||
visitor.afterVisitClassLiteralExpression(this)
|
visitor.afterVisitClassLiteralExpression(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -32,6 +32,6 @@ interface UContinueExpression : UExpression {
|
|||||||
visitor.afterVisitContinueExpression(this)
|
visitor.afterVisitContinueExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = "UContinueExpression (" + (label ?: "<no label>") + ")"
|
override fun asLogString() = "UContinueExpression (" + (label ?: "<no label>") + ")"
|
||||||
override fun renderString() = label?.let { "continue@$it" } ?: "continue"
|
override fun asRenderString() = label?.let { "continue@$it" } ?: "continue"
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,7 +40,6 @@ interface ULabeledExpression : UExpression {
|
|||||||
|
|
||||||
override fun evaluate() = expression.evaluate()
|
override fun evaluate() = expression.evaluate()
|
||||||
|
|
||||||
override fun logString() = log("ULabeledExpression ($label)", expression)
|
override fun asLogString() = log("ULabeledExpression ($label)", expression)
|
||||||
|
override fun asRenderString() = "$label@ ${expression.asRenderString()}"
|
||||||
override fun renderString() = "$label@ ${expression.renderString()}"
|
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,7 +26,7 @@ interface ULambdaExpression : UExpression {
|
|||||||
/**
|
/**
|
||||||
* Returns the list of lambda value parameters.
|
* Returns the list of lambda value parameters.
|
||||||
*/
|
*/
|
||||||
val valueParameters: List<UVariable>
|
val valueParameters: List<UParameter>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the lambda body expression.
|
* Returns the lambda body expression.
|
||||||
@@ -38,13 +40,14 @@ interface ULambdaExpression : UExpression {
|
|||||||
visitor.afterVisitLambdaExpression(this)
|
visitor.afterVisitLambdaExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("ULambdaExpression", valueParameters, body)
|
override fun asLogString() = log("ULambdaExpression", valueParameters, body)
|
||||||
override fun renderString(): String {
|
|
||||||
|
override fun asRenderString(): String {
|
||||||
val renderedValueParameters = if (valueParameters.isEmpty())
|
val renderedValueParameters = if (valueParameters.isEmpty())
|
||||||
""
|
""
|
||||||
else
|
else
|
||||||
valueParameters.joinToString { it.renderString() } + " ->\n"
|
valueParameters.joinToString { it.asRenderString() } + " ->" + LINE_SEPARATOR
|
||||||
|
|
||||||
return "{ " + renderedValueParameters + body.renderString().withMargin + "\n}"
|
return "{ " + renderedValueParameters + body.asRenderString().withMargin + LINE_SEPARATOR + "}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ interface ULiteralExpression : UExpression {
|
|||||||
/**
|
/**
|
||||||
* Returns true if the literal is a `null`-literal, false otherwise.
|
* Returns true if the literal is a `null`-literal, false otherwise.
|
||||||
*/
|
*/
|
||||||
open val isNull: Boolean
|
val isNull: Boolean
|
||||||
get() = value == null
|
get() = value == null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +50,7 @@ interface ULiteralExpression : UExpression {
|
|||||||
visitor.afterVisitLiteralExpression(this)
|
visitor.afterVisitLiteralExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString(): String {
|
override fun asRenderString(): String {
|
||||||
val value = value
|
val value = value
|
||||||
return when (value) {
|
return when (value) {
|
||||||
null -> "null"
|
null -> "null"
|
||||||
@@ -63,5 +63,5 @@ interface ULiteralExpression : UExpression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = "ULiteralExpression (${renderString()})"
|
override fun asLogString() = "ULiteralExpression (${asRenderString()})"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
class UNamedExpression(
|
class UNamedExpression(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
): UExpression, UNamed {
|
): UExpression, UNamed {
|
||||||
lateinit var expression: UExpression
|
lateinit var expression: UExpression
|
||||||
|
|
||||||
@@ -29,8 +30,16 @@ class UNamedExpression(
|
|||||||
visitor.afterVisitElement(this)
|
visitor.afterVisitElement(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UNamedExpression ($name)", expression)
|
override fun asLogString() = log("UNamedExpression ($name)", expression)
|
||||||
override fun renderString() = "$name: $expression"
|
override fun asRenderString() = name + " = " + expression.asRenderString()
|
||||||
|
|
||||||
override fun evaluate() = expression.evaluate()
|
override fun evaluate() = expression.evaluate()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
inline fun create(name: String, parent: UElement?, innerExpr: UElement.() -> UExpression): UNamedExpression {
|
||||||
|
return UNamedExpression(name, parent).apply {
|
||||||
|
expression = innerExpr(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,23 +15,44 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an object literal expression, e.g. `new Runnable() {}` in Java.
|
* Represents an object literal expression, e.g. `new Runnable() {}` in Java.
|
||||||
*/
|
*/
|
||||||
interface UObjectLiteralExpression : UExpression {
|
interface UObjectLiteralExpression : UCallExpression {
|
||||||
/**
|
/**
|
||||||
* Returns the class declaration.
|
* Returns the class declaration.
|
||||||
*/
|
*/
|
||||||
val declaration: UClass
|
val declaration: UClass
|
||||||
|
|
||||||
|
override val methodIdentifier: UIdentifier?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
override val kind: UastCallKind
|
||||||
|
get() = UastCallKind.CONSTRUCTOR_CALL
|
||||||
|
|
||||||
|
override val methodName: String?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
override val receiver: UExpression?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
override val receiverType: PsiType?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
override val returnType: PsiType?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitObjectLiteralExpression(this)) return
|
if (visitor.visitObjectLiteralExpression(this)) return
|
||||||
declaration.accept(visitor)
|
declaration.accept(visitor)
|
||||||
visitor.afterVisitObjectLiteralExpression(this)
|
visitor.afterVisitObjectLiteralExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UObjectLiteralExpression", declaration)
|
override fun asLogString() = log("UObjectLiteralExpression", declaration)
|
||||||
override fun renderString() = "anonymous " + declaration.renderString()
|
override fun asRenderString() = "anonymous " + declaration.text
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,6 +35,6 @@ interface UParenthesizedExpression : UExpression {
|
|||||||
|
|
||||||
override fun evaluate() = expression.evaluate()
|
override fun evaluate() = expression.evaluate()
|
||||||
|
|
||||||
override fun logString() = log("UParenthesizedExpression", expression)
|
override fun asLogString() = log("UParenthesizedExpression", expression)
|
||||||
override fun renderString() = '(' + expression.renderString() + ')'
|
override fun asRenderString() = '(' + expression.asRenderString() + ')'
|
||||||
}
|
}
|
||||||
+7
-21
@@ -15,12 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.expressions.UReferenceExpression
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the qualified expression (receiver.selector).
|
* Represents the qualified expression (receiver.selector).
|
||||||
*/
|
*/
|
||||||
interface UQualifiedExpression : UExpression, UResolvable {
|
interface UQualifiedReferenceExpression : UReferenceExpression {
|
||||||
/**
|
/**
|
||||||
* Returns the expression receiver.
|
* Returns the expression receiver.
|
||||||
*/
|
*/
|
||||||
@@ -36,30 +38,14 @@ interface UQualifiedExpression : UExpression, UResolvable {
|
|||||||
*/
|
*/
|
||||||
val accessType: UastQualifiedExpressionAccessType
|
val accessType: UastQualifiedExpressionAccessType
|
||||||
|
|
||||||
/**
|
override fun asRenderString() = receiver.asRenderString() + accessType.name + selector.asRenderString()
|
||||||
* Checks if the selector is a simple reference expression, and if its identifier is [identifier].
|
|
||||||
*
|
|
||||||
* @param identifier the identifier to check agains
|
|
||||||
* @return true if the selector is a simple reference expression, and if its identifier is [identifier],
|
|
||||||
* false otherwise
|
|
||||||
*/
|
|
||||||
fun selectorMatches(identifier: String) = (selector as? USimpleReferenceExpression)?.identifier == identifier
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the selector identifier if the selector is a simple reference expression.
|
|
||||||
*
|
|
||||||
* @return the selector identifier if the selector is a simple reference expression, null otherwise.
|
|
||||||
*/
|
|
||||||
fun getSelectorAsIdentifier(): String? = (selector as? USimpleReferenceExpression)?.identifier
|
|
||||||
|
|
||||||
override fun renderString() = receiver.renderString() + accessType.name + selector.renderString()
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitQualifiedExpression(this)) return
|
if (visitor.visitQualifiedReferenceExpression(this)) return
|
||||||
receiver.accept(visitor)
|
receiver.accept(visitor)
|
||||||
selector.accept(visitor)
|
selector.accept(visitor)
|
||||||
visitor.afterVisitQualifiedExpression(this)
|
visitor.afterVisitQualifiedReferenceExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UQualifiedExpression", receiver, selector)
|
override fun asLogString() = log("UQualifiedExpression", receiver, selector)
|
||||||
}
|
}
|
||||||
+11
-5
@@ -13,11 +13,17 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jetbrains.uast.java
|
|
||||||
|
|
||||||
import org.jetbrains.uast.UastVisibility
|
package org.jetbrains.uast.expressions
|
||||||
|
|
||||||
object JavaUastVisibilities {
|
import org.jetbrains.uast.UExpression
|
||||||
@JvmField
|
import org.jetbrains.uast.UResolvable
|
||||||
val PACKAGE_LOCAL = UastVisibility("package_local")
|
|
||||||
|
interface UReferenceExpression : UExpression, UResolvable {
|
||||||
|
/**
|
||||||
|
* Returns the resolved name for this reference, or null if the reference can't be resolved.
|
||||||
|
*/
|
||||||
|
val resolvedName: String?
|
||||||
|
|
||||||
|
override fun asLogString() = "UReferenceExpression"
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,6 +34,6 @@ interface UReturnExpression : UExpression {
|
|||||||
visitor.afterVisitReturnExpression(this)
|
visitor.afterVisitReturnExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = returnExpression.let { if (it == null) "return" else "return " + it.renderString() }
|
override fun asRenderString() = returnExpression.let { if (it == null) "return" else "return " + it.asRenderString() }
|
||||||
override fun logString() = log("UReturnExpression", returnExpression)
|
override fun asLogString() = log("UReturnExpression", returnExpression)
|
||||||
}
|
}
|
||||||
+7
-6
@@ -15,22 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.expressions.UReferenceExpression
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a simple reference expression (a non-qualified identifier).
|
* Represents a simple reference expression (a non-qualified identifier).
|
||||||
*/
|
*/
|
||||||
interface USimpleReferenceExpression : UExpression, UResolvable {
|
interface USimpleNameReferenceExpression : UReferenceExpression {
|
||||||
/**
|
/**
|
||||||
* Returns the identifier name.
|
* Returns the identifier name.
|
||||||
*/
|
*/
|
||||||
val identifier: String
|
val identifier: String
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
visitor.visitSimpleReferenceExpression(this)
|
visitor.visitSimpleNameReferenceExpression(this)
|
||||||
visitor.afterVisitSimpleReferenceExpression(this)
|
visitor.afterVisitSimpleNameReferenceExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = "USimpleReferenceExpression ($identifier)"
|
override fun asLogString() = "USimpleReferenceExpression ($identifier)"
|
||||||
override fun renderString() = identifier
|
override fun asRenderString() = identifier
|
||||||
}
|
}
|
||||||
@@ -22,8 +22,8 @@ import org.jetbrains.uast.visitor.UastVisitor
|
|||||||
* Qualified `super` is not supported at the moment.
|
* Qualified `super` is not supported at the moment.
|
||||||
*/
|
*/
|
||||||
interface USuperExpression : UExpression {
|
interface USuperExpression : UExpression {
|
||||||
override fun logString() = "USuperExpression"
|
override fun asLogString() = "USuperExpression"
|
||||||
override fun renderString() = "super"
|
override fun asRenderString() = "super"
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
visitor.visitSuperExpression(this)
|
visitor.visitSuperExpression(this)
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import org.jetbrains.uast.visitor.UastVisitor
|
|||||||
* Qualified `this` is not supported at the moment.
|
* Qualified `this` is not supported at the moment.
|
||||||
*/
|
*/
|
||||||
interface UThisExpression : UExpression {
|
interface UThisExpression : UExpression {
|
||||||
override fun logString() = "UThisExpression"
|
override fun asLogString() = "UThisExpression"
|
||||||
override fun renderString() = "this"
|
override fun asRenderString() = "this"
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
visitor.visitThisExpression(this)
|
visitor.visitThisExpression(this)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,7 +34,6 @@ interface UThrowExpression : UExpression {
|
|||||||
visitor.afterVisitThrowExpression(this)
|
visitor.afterVisitThrowExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = "throw " + thrownExpression.renderString()
|
override fun asRenderString() = "throw " + thrownExpression.asRenderString()
|
||||||
|
override fun asLogString() = log("UThrowExpression", thrownExpression)
|
||||||
override fun logString() = log("UThrowExpression", thrownExpression)
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package org.jetbrains.uast.expressions
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
|
import com.intellij.psi.util.PsiTypesUtil
|
||||||
|
import org.jetbrains.uast.UExpression
|
||||||
|
import org.jetbrains.uast.name
|
||||||
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
|
interface UTypeReferenceExpression : UExpression {
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
|
||||||
|
override fun accept(visitor: UastVisitor) {
|
||||||
|
visitor.visitTypeReferenceExpression(this)
|
||||||
|
visitor.afterVisitTypeReferenceExpression(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asLogString() = "UTypeReferenceExpression (${type.name})"
|
||||||
|
override fun asRenderString() = type.name
|
||||||
|
}
|
||||||
@@ -15,12 +15,33 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
interface UUnaryExpression : UExpression {
|
interface UUnaryExpression : UExpression {
|
||||||
|
/**
|
||||||
|
* Returns the expression operand.
|
||||||
|
*/
|
||||||
val operand: UExpression
|
val operand: UExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the expression operator.
|
||||||
|
*/
|
||||||
val operator: UastOperator
|
val operator: UastOperator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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?
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitUnaryExpression(this)) return
|
if (visitor.visitUnaryExpression(this)) return
|
||||||
operand.accept(visitor)
|
operand.accept(visitor)
|
||||||
@@ -37,8 +58,8 @@ interface UPrefixExpression : UUnaryExpression {
|
|||||||
visitor.afterVisitPrefixExpression(this)
|
visitor.afterVisitPrefixExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UPrefixExpression (${operator.text})", operand)
|
override fun asLogString() = log("UPrefixExpression (${operator.text})", operand)
|
||||||
override fun renderString() = operator.text + operand.renderString()
|
override fun asRenderString() = operator.text + operand.asRenderString()
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UPostfixExpression : UUnaryExpression {
|
interface UPostfixExpression : UUnaryExpression {
|
||||||
@@ -50,6 +71,6 @@ interface UPostfixExpression : UUnaryExpression {
|
|||||||
visitor.afterVisitPostfixExpression(this)
|
visitor.afterVisitPostfixExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logString() = log("UPostfixExpression (${operator.text})", operand)
|
override fun asLogString() = log("UPostfixExpression (${operator.text})", operand)
|
||||||
override fun renderString() = operand.renderString() + operator.text
|
override fun asRenderString() = operand.asRenderString() + operator.text
|
||||||
}
|
}
|
||||||
+8
-17
@@ -15,35 +15,26 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
import org.jetbrains.uast.internal.acceptList
|
||||||
|
import org.jetbrains.uast.internal.log
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a list of declarations.
|
* Represents a list of declarations.
|
||||||
* Example in Java: `int a = 4, b = 3`.
|
* Example in Java: `int a = 4, b = 3`.
|
||||||
*/
|
*/
|
||||||
interface UDeclarationsExpression : UExpression {
|
interface UVariableDeclarationsExpression : UExpression {
|
||||||
/**
|
/**
|
||||||
* Returns the list of declarations inside this [UDeclarationsExpression].
|
* Returns the list of variables inside this [UVariableDeclarationsExpression].
|
||||||
*/
|
|
||||||
val declarations: List<UElement>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of variables inside this [UDeclarationsExpression].
|
|
||||||
*/
|
*/
|
||||||
val variables: List<UVariable>
|
val variables: List<UVariable>
|
||||||
get() = declarations.filterIsInstance<UVariable>()
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitDeclarationsExpression(this)) return
|
if (visitor.visitDeclarationsExpression(this)) return
|
||||||
declarations.acceptList(visitor)
|
variables.acceptList(visitor)
|
||||||
visitor.afterVisitDeclarationsExpression(this)
|
visitor.afterVisitDeclarationsExpression(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderString() = declarations.joinToString("\n") { it.renderString() }
|
override fun asRenderString() = variables.joinToString(LINE_SEPARATOR) { it.asRenderString() }
|
||||||
override fun logString() = log("UDeclarationsExpression", declarations)
|
override fun asLogString() = log("UDeclarationsExpression", variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleUDeclarationsExpression(
|
|
||||||
override val parent: UElement,
|
|
||||||
override val declarations: List<UElement>
|
|
||||||
) : UDeclarationsExpression
|
|
||||||
@@ -23,6 +23,27 @@ package org.jetbrains.uast
|
|||||||
*/
|
*/
|
||||||
fun UElement.isNullLiteral(): Boolean = this is ULiteralExpression && this.isNull
|
fun UElement.isNullLiteral(): Boolean = this is ULiteralExpression && this.isNull
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the [UElement] is a boolean literal.
|
||||||
|
*
|
||||||
|
* @return true if the receiver is a boolean literal, false otherwise.
|
||||||
|
*/
|
||||||
|
fun UElement.isBooleanLiteral(): Boolean = this is ULiteralExpression && this.isBoolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the [UElement] is a `true` boolean literal.
|
||||||
|
*
|
||||||
|
* @return true if the receiver is a `true` boolean literal, false otherwise.
|
||||||
|
*/
|
||||||
|
fun UElement.isTrueLiteral(): Boolean = this is ULiteralExpression && this.isBoolean && this.value == true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the [UElement] is a `false` boolean literal.
|
||||||
|
*
|
||||||
|
* @return true if the receiver is a `false` boolean literal, false otherwise.
|
||||||
|
*/
|
||||||
|
fun UElement.isFalseLiteral(): Boolean = this is ULiteralExpression && this.isBoolean && this.value == false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the [UElement] is a [String] literal.
|
* Checks if the [UElement] is a [String] literal.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.jetbrains.uast.internal
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.uast.LINE_SEPARATOR
|
||||||
|
import org.jetbrains.uast.UElement
|
||||||
|
import org.jetbrains.uast.asLogString
|
||||||
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
import org.jetbrains.uast.withMargin
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the log message for the [UElement.asLogString] function.
|
||||||
|
*
|
||||||
|
* @param firstLine the message line (the interface name, some optional information).
|
||||||
|
* @param nested nested UElements. Could be `List<UElement>`, [UElement] or `null`.
|
||||||
|
* @throws IllegalStateException if the [nested] argument is invalid.
|
||||||
|
* @return the rendered log string.
|
||||||
|
*/
|
||||||
|
fun UElement.log(firstLine: String, vararg nested: Any?): String {
|
||||||
|
return (if (firstLine.isBlank()) "" else firstLine + LINE_SEPARATOR) + nested.joinToString(LINE_SEPARATOR) {
|
||||||
|
when (it) {
|
||||||
|
null -> "<no element>".withMargin
|
||||||
|
is List<*> -> {
|
||||||
|
if (it.firstOrNull() is PsiElement) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
(it as List<PsiElement>).joinToString(LINE_SEPARATOR) { it.text }
|
||||||
|
} else {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
(it as List<UElement>).asLogString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is UElement -> it.asLogString().withMargin
|
||||||
|
else -> error("Invalid element type: $it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<UElement>.acceptList(visitor: UastVisitor) {
|
||||||
|
for (element in this) {
|
||||||
|
element.accept(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,15 +15,32 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
internal fun List<UElement>.logString() = joinToString("\n") { it.logString().withMargin }
|
import com.intellij.psi.PsiType
|
||||||
|
|
||||||
internal fun UModifierOwner.renderModifiers() = UastModifier.VALUES
|
internal val ERROR_NAME = "<error>"
|
||||||
.filter { hasModifier(it) }
|
|
||||||
.joinToString(" ") { it.name }
|
internal val LINE_SEPARATOR = System.getProperty("line.separator") ?: "\n"
|
||||||
|
|
||||||
|
val String.withMargin: String
|
||||||
|
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 fun StringBuilder.appendWithSpace(s: String) {
|
internal fun StringBuilder.appendWithSpace(s: String) {
|
||||||
if (s.isNotEmpty()) {
|
if (s.isNotEmpty()) {
|
||||||
append(s)
|
append(s)
|
||||||
append(' ')
|
append(' ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal tailrec fun UExpression.unwrapParenthesis(): UExpression = when (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)
|
||||||
+1
-5
@@ -34,8 +34,4 @@ open class UastBinaryExpressionWithTypeKind(val name: String) {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val UNKNOWN = UastBinaryExpressionWithTypeKind("<unknown>")
|
val UNKNOWN = UastBinaryExpressionWithTypeKind("<unknown>")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun UElement.isTypeCast() = this is UBinaryExpressionWithType && this.operationKind is UastBinaryExpressionWithTypeKind.TypeCast
|
|
||||||
|
|
||||||
fun UElement.isInstanceCheck() = this is UBinaryExpressionWithType && this.operationKind is UastBinaryExpressionWithTypeKind.InstanceCheck
|
|
||||||
@@ -20,7 +20,7 @@ package org.jetbrains.uast
|
|||||||
*/
|
*/
|
||||||
open class UastBinaryOperator(override val text: String): UastOperator {
|
open class UastBinaryOperator(override val text: String): UastOperator {
|
||||||
class LogicalOperator(text: String): UastBinaryOperator(text)
|
class LogicalOperator(text: String): UastBinaryOperator(text)
|
||||||
class ComparationOperator(text: String): UastBinaryOperator(text)
|
class ComparisonOperator(text: String): UastBinaryOperator(text)
|
||||||
class ArithmeticOperator(text: String): UastBinaryOperator(text)
|
class ArithmeticOperator(text: String): UastBinaryOperator(text)
|
||||||
class BitwiseOperator(text: String): UastBinaryOperator(text)
|
class BitwiseOperator(text: String): UastBinaryOperator(text)
|
||||||
class AssignOperator(text: String): UastBinaryOperator(text)
|
class AssignOperator(text: String): UastBinaryOperator(text)
|
||||||
@@ -36,7 +36,7 @@ open class UastBinaryOperator(override val text: String): UastOperator {
|
|||||||
val MINUS = ArithmeticOperator("-")
|
val MINUS = ArithmeticOperator("-")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val MULT = ArithmeticOperator("*")
|
val MULTIPLY = ArithmeticOperator("*")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val DIV = ArithmeticOperator("/")
|
val DIV = ArithmeticOperator("/")
|
||||||
@@ -60,28 +60,28 @@ open class UastBinaryOperator(override val text: String): UastOperator {
|
|||||||
val BITWISE_XOR = BitwiseOperator("^")
|
val BITWISE_XOR = BitwiseOperator("^")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val EQUALS = ComparationOperator("==")
|
val EQUALS = ComparisonOperator("==")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val NOT_EQUALS = ComparationOperator("!=")
|
val NOT_EQUALS = ComparisonOperator("!=")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val IDENTITY_EQUALS = ComparationOperator("===")
|
val IDENTITY_EQUALS = ComparisonOperator("===")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val IDENTITY_NOT_EQUALS = ComparationOperator("!==")
|
val IDENTITY_NOT_EQUALS = ComparisonOperator("!==")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val GREATER = ComparationOperator(">")
|
val GREATER = ComparisonOperator(">")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val GREATER_OR_EQUAL = ComparationOperator(">=")
|
val GREATER_OR_EQUAL = ComparisonOperator(">=")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val LESS = ComparationOperator("<")
|
val LESS = ComparisonOperator("<")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val LESS_OR_EQUAL = ComparationOperator("<=")
|
val LESS_OR_EQUAL = ComparisonOperator("<=")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val SHIFT_LEFT = BitwiseOperator("<<")
|
val SHIFT_LEFT = BitwiseOperator("<<")
|
||||||
@@ -93,7 +93,7 @@ open class UastBinaryOperator(override val text: String): UastOperator {
|
|||||||
val UNSIGNED_SHIFT_RIGHT = BitwiseOperator(">>>")
|
val UNSIGNED_SHIFT_RIGHT = BitwiseOperator(">>>")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val UNKNOWN = UastBinaryOperator("<unknown>")
|
val OTHER = UastBinaryOperator("<other>")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val PLUS_ASSIGN = AssignOperator("+=")
|
val PLUS_ASSIGN = AssignOperator("+=")
|
||||||
|
|||||||
@@ -21,13 +21,24 @@ package org.jetbrains.uast
|
|||||||
open class UastCallKind(val name: String) {
|
open class UastCallKind(val name: String) {
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
val FUNCTION_CALL = UastCallKind("function_call")
|
val METHOD_CALL = UastCallKind("method_call")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val CONSTRUCTOR_CALL = UastCallKind("constructor_call")
|
val CONSTRUCTOR_CALL = UastCallKind("constructor_call")
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val NEW_ARRAY_WITH_DIMENSIONS = UastCallKind("new_array_with_dimensions")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
@JvmField
|
||||||
val ARRAY_INITIALIZER = UastCallKind("array_initializer")
|
val NESTED_ARRAY_INITIALIZER = UastCallKind("array_initializer")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String{
|
override fun toString(): String{
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Kinds of [UFunction].
|
|
||||||
*/
|
|
||||||
open class UastFunctionKind(val text: String) {
|
|
||||||
class UastInitializerKind(val name: String) : UastFunctionKind("INITIALIZER ($name)")
|
|
||||||
class UastVariableAccessor(val name: String) : UastFunctionKind(name)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmField
|
|
||||||
val FUNCTION = UastFunctionKind("function")
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
val CONSTRUCTOR = UastFunctionKind("constructor")
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
val GETTER = UastVariableAccessor("getter")
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
val SETTER = UastVariableAccessor("setter")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String{
|
|
||||||
return "UastFunctionKind(text='$text')"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uast declaration modifiers.
|
|
||||||
*
|
|
||||||
* @see UModifierOwner
|
|
||||||
*/
|
|
||||||
open class UastModifier(val name: String) {
|
|
||||||
companion object {
|
|
||||||
@JvmField
|
|
||||||
val ABSTRACT = UastModifier("abstract")
|
|
||||||
@JvmField
|
|
||||||
val STATIC = UastModifier("static")
|
|
||||||
@JvmField
|
|
||||||
val FINAL = UastModifier("final")
|
|
||||||
@JvmField
|
|
||||||
val IMMUTABLE = UastModifier("immutable")
|
|
||||||
@JvmField
|
|
||||||
val VARARG = UastModifier("vararg")
|
|
||||||
@JvmField
|
|
||||||
val OVERRIDE = UastModifier("override")
|
|
||||||
@JvmField
|
|
||||||
val JVM_FIELD = UastModifier("field")
|
|
||||||
|
|
||||||
// JVM-related modifiers are not listed here
|
|
||||||
val VALUES = listOf(ABSTRACT, STATIC, FINAL, IMMUTABLE, VARARG, OVERRIDE)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String{
|
|
||||||
return "UastModifier(name='$name')"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,13 +16,13 @@
|
|||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uast operator base inteface.
|
* Uast operator base interface.
|
||||||
*
|
*
|
||||||
* @see [UastPrefixOperator], [UastPostfixOperator], [UastBinaryOperator]
|
* @see [UastPrefixOperator], [UastPostfixOperator], [UastBinaryOperator]
|
||||||
*/
|
*/
|
||||||
interface UastOperator {
|
interface UastOperator {
|
||||||
/**
|
/**
|
||||||
* Returns the operator text to render in [UElement.renderString].
|
* Returns the operator text to render in [UElement.asRenderString].
|
||||||
*/
|
*/
|
||||||
val text: String
|
val text: String
|
||||||
}
|
}
|
||||||
+1
-1
@@ -16,7 +16,7 @@
|
|||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access types of [UQualifiedExpression].
|
* Access types of [UQualifiedReferenceExpression].
|
||||||
* Additional type examples: Kotlin safe call (?.).
|
* Additional type examples: Kotlin safe call (?.).
|
||||||
*/
|
*/
|
||||||
open class UastQualifiedExpressionAccessType(val name: String) {
|
open class UastQualifiedExpressionAccessType(val name: String) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kinds of [USpecialExpressionList].
|
* Kinds of [UExpressionList].
|
||||||
*/
|
*/
|
||||||
open class UastSpecialExpressionKind(val name: String) {
|
open class UastSpecialExpressionKind(val name: String) {
|
||||||
override fun toString(): String{
|
override fun toString(): String{
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.uast.kinds
|
|
||||||
|
|
||||||
open class UastVariableInitialierKind(val name: String) {
|
|
||||||
class Expression(name: String) : UastVariableInitialierKind(name)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmField
|
|
||||||
val EXPRESSION = Expression("expression")
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
val NO_INITIALIZER = UastVariableInitialierKind("no_initializer")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Kinds of [UVariable].
|
|
||||||
*/
|
|
||||||
open class UastVariableKind(val name: String) {
|
|
||||||
class Member(name: String) : UastVariableKind(name)
|
|
||||||
class LocalVariable(name: String) : UastVariableKind(name)
|
|
||||||
class ValueParameter(name: String) : UastVariableKind(name)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmField
|
|
||||||
val LOCAL_VARIABLE = LocalVariable("local")
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
val MEMBER = Member("member")
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
val VALUE_PARAMETER = ValueParameter("parameter")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String{
|
|
||||||
return "UastVariableKind(name='$name')"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,24 +15,26 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast
|
package org.jetbrains.uast
|
||||||
|
|
||||||
/**
|
import com.intellij.psi.PsiLocalVariable
|
||||||
* Uast visibility list.
|
import com.intellij.psi.PsiModifier
|
||||||
*/
|
import com.intellij.psi.PsiModifierListOwner
|
||||||
open class UastVisibility(val name: String) {
|
|
||||||
|
enum class UastVisibility(val text: String) {
|
||||||
|
PUBLIC("public"),
|
||||||
|
PRIVATE("private"),
|
||||||
|
PROTECTED("protected"),
|
||||||
|
PACKAGE_LOCAL("packageLocal"),
|
||||||
|
LOCAL("local");
|
||||||
|
|
||||||
|
override fun toString() = text
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
operator fun get(declaration: PsiModifierListOwner): UastVisibility {
|
||||||
val PUBLIC = UastVisibility("public")
|
if (declaration.hasModifierProperty(PsiModifier.PUBLIC)) return UastVisibility.PUBLIC
|
||||||
@JvmField
|
if (declaration.hasModifierProperty(PsiModifier.PROTECTED)) return UastVisibility.PROTECTED
|
||||||
val PRIVATE = UastVisibility("private")
|
if (declaration.hasModifierProperty(PsiModifier.PRIVATE)) return UastVisibility.PRIVATE
|
||||||
@JvmField
|
if (declaration is PsiLocalVariable) return UastVisibility.LOCAL
|
||||||
val PROTECTED = UastVisibility("protected")
|
return UastVisibility.PACKAGE_LOCAL
|
||||||
@JvmField
|
}
|
||||||
val LOCAL = UastVisibility("local")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isPublic() = this == PUBLIC
|
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
return "UastVisibility(name='$name')"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -22,6 +22,6 @@ import org.jetbrains.uast.UElement
|
|||||||
interface PsiElementBacked : UElement {
|
interface PsiElementBacked : UElement {
|
||||||
val psi: PsiElement?
|
val psi: PsiElement?
|
||||||
|
|
||||||
override val isValid: Boolean
|
override val isPsiValid: Boolean
|
||||||
get() = psi?.isValid ?: true
|
get() = psi?.isValid ?: true
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package org.jetbrains.uast.psi
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.Segment
|
||||||
|
import org.jetbrains.uast.UElement
|
||||||
|
|
||||||
|
interface UElementWithLocation : UElement, Segment
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.jetbrains.uast.psi
|
||||||
|
|
||||||
|
import com.intellij.lang.Language
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.impl.light.LightParameter
|
||||||
|
import org.jetbrains.uast.UastErrorType
|
||||||
|
|
||||||
|
class UastPsiParameterNotResolved(
|
||||||
|
declarationScope: PsiElement,
|
||||||
|
language: Language
|
||||||
|
) : LightParameter("error", UastErrorType, declarationScope, language)
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
@file:JvmMultifileClass
|
||||||
|
@file:JvmName("UastUtils")
|
||||||
|
package org.jetbrains.uast
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the topmost parent qualified expression for the call expression.
|
||||||
|
*
|
||||||
|
* Example 1:
|
||||||
|
* Code: variable.call(args)
|
||||||
|
* Call element: E = call(args)
|
||||||
|
* Qualified parent (return value): Q = [getQualifiedCallElement](E) = variable.call(args)
|
||||||
|
*
|
||||||
|
* Example 2:
|
||||||
|
* Code: call(args)
|
||||||
|
* Call element: E = call(args)
|
||||||
|
* Qualified parent (return value): Q = [getQualifiedCallElement](E) = call(args) (no qualifier)
|
||||||
|
*
|
||||||
|
* @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.containingElement as? UExpression, current) ?: current
|
||||||
|
else
|
||||||
|
previous
|
||||||
|
}
|
||||||
|
is UParenthesizedExpression -> findParent(current.expression, previous) ?: previous
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
return findParent(containingElement as? UExpression, this) ?: this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun UExpression.asQualifiedPath(): List<String>? {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
addIdentifiers(this)
|
||||||
|
return if (error) null else list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the list of qualified expressions.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* Code: obj.call(param).anotherCall(param2).getter
|
||||||
|
* Qualified chain: [obj, call(param), anotherCall(param2), getter]
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this == null) return emptyList()
|
||||||
|
val qualifiedExpression = this as? UQualifiedReferenceExpression ?: return listOf(this)
|
||||||
|
val chains = mutableListOf<UExpression>()
|
||||||
|
collect(qualifiedExpression, chains)
|
||||||
|
return chains
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the outermost qualified expression.
|
||||||
|
*
|
||||||
|
* @return the outermost qualified expression,
|
||||||
|
* this element if the parent expression is not a qualified expression,
|
||||||
|
* or null if the element is not a qualified expression.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* Code: a.b.c(asd).g
|
||||||
|
* Call element: c(asd)
|
||||||
|
* 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.containingElement, current)
|
||||||
|
is UParenthesizedExpression -> getOutermostQualified(current.containingElement, previous)
|
||||||
|
else -> if (previous is UQualifiedReferenceExpression) previous else null
|
||||||
|
}
|
||||||
|
|
||||||
|
return getOutermostQualified(this.containingElement, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the received expression is a qualified chain of identifiers, and the trailing part of such chain is [fqName].
|
||||||
|
*
|
||||||
|
* @param fqName the chain part to check against. Sequence of identifiers, separated by dot ('.'). Example: "com.example".
|
||||||
|
* @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
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the received expression is a qualified chain of identifiers, and the leading part of such chain is [fqName].
|
||||||
|
*
|
||||||
|
* @param fqName the chain part to check against. Sequence of identifiers, separated by dot ('.'). Example: "com.example".
|
||||||
|
* @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
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the received expression is a qualified chain of identifiers, and the trailing part of such chain is [fqName].
|
||||||
|
*
|
||||||
|
* @param fqName the chain part to check against. Sequence of identifiers, separated by dot ('.'). Example: "com.example".
|
||||||
|
* @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
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:JvmName("UastExpressionUtils")
|
||||||
|
package org.jetbrains.uast.util
|
||||||
|
|
||||||
|
import org.jetbrains.uast.*
|
||||||
|
|
||||||
|
fun UElement.isConstructorCall() = (this as? UCallExpression)?.kind == UastCallKind.CONSTRUCTOR_CALL
|
||||||
|
|
||||||
|
fun UElement.isMethodCall() = (this as? UCallExpression)?.kind == UastCallKind.METHOD_CALL
|
||||||
|
|
||||||
|
fun UElement.isNewArray() = isNewArrayWithDimensions() || isNewArrayWithInitializer()
|
||||||
|
|
||||||
|
fun UElement.isNewArrayWithDimensions() = (this as? UCallExpression)?.kind == UastCallKind.NEW_ARRAY_WITH_DIMENSIONS
|
||||||
|
|
||||||
|
fun UElement.isNewArrayWithInitializer() = (this as? UCallExpression)?.kind == UastCallKind.NEW_ARRAY_WITH_INITIALIZER
|
||||||
|
|
||||||
|
fun UElement.isNestedArrayInitializer() = (this as? UCallExpression)?.kind == UastCallKind.NESTED_ARRAY_INITIALIZER
|
||||||
|
|
||||||
|
fun UElement.isTypeCast() = (this as? UBinaryExpressionWithType)?.operationKind is UastBinaryExpressionWithTypeKind.TypeCast
|
||||||
|
|
||||||
|
fun UElement.isInstanceCheck() = (this as? UBinaryExpressionWithType)?.operationKind is UastBinaryExpressionWithTypeKind.InstanceCheck
|
||||||
|
|
||||||
|
fun UElement.isAssignment() = (this as? UBinaryExpression)?.operator is UastBinaryOperator.AssignOperator
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,49 +17,27 @@
|
|||||||
package org.jetbrains.uast.visitor
|
package org.jetbrains.uast.visitor
|
||||||
|
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
|
import org.jetbrains.uast.expressions.UTypeReferenceExpression
|
||||||
|
|
||||||
|
|
||||||
class DelegatingUastVisitor(private val visitors: List<UastVisitor>): UastVisitor {
|
class DelegatingUastVisitor(private val visitors: List<UastVisitor>): UastVisitor {
|
||||||
override fun visitElement(node: UElement): Boolean {
|
override fun visitElement(node: UElement): Boolean {
|
||||||
return visitors.all { it.visitElement(node) }
|
return visitors.all { it.visitElement(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFile(node: UFile): Boolean {
|
|
||||||
return visitors.all { it.visitFile(node) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitImportStatement(node: UImportStatement): Boolean {
|
|
||||||
return visitors.all { it.visitImportStatement(node) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitAnnotation(node: UAnnotation): Boolean {
|
|
||||||
return visitors.all { it.visitAnnotation(node) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCatchClause(node: UCatchClause): Boolean {
|
|
||||||
return visitors.all { it.visitCatchClause(node) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitType(node: UType): Boolean {
|
|
||||||
return visitors.all { it.visitType(node) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClass(node: UClass): Boolean {
|
|
||||||
return visitors.all { it.visitClass(node) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunction(node: UFunction): Boolean {
|
|
||||||
return visitors.all { it.visitFunction(node) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitVariable(node: UVariable): Boolean {
|
override fun visitVariable(node: UVariable): Boolean {
|
||||||
return visitors.all { it.visitVariable(node) }
|
return visitors.all { it.visitVariable(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitMethod(node: UMethod): Boolean {
|
||||||
|
return visitors.all { it.visitMethod(node) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitLabeledExpression(node: ULabeledExpression): Boolean {
|
override fun visitLabeledExpression(node: ULabeledExpression): Boolean {
|
||||||
return visitors.all { it.visitLabeledExpression(node) }
|
return visitors.all { it.visitLabeledExpression(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDeclarationsExpression(node: UDeclarationsExpression): Boolean {
|
override fun visitDeclarationsExpression(node: UVariableDeclarationsExpression): Boolean {
|
||||||
return visitors.all { it.visitDeclarationsExpression(node) }
|
return visitors.all { it.visitDeclarationsExpression(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,12 +45,16 @@ class DelegatingUastVisitor(private val visitors: List<UastVisitor>): UastVisito
|
|||||||
return visitors.all { it.visitBlockExpression(node) }
|
return visitors.all { it.visitBlockExpression(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitQualifiedExpression(node: UQualifiedExpression): Boolean {
|
override fun visitQualifiedReferenceExpression(node: UQualifiedReferenceExpression): Boolean {
|
||||||
return visitors.all { it.visitQualifiedExpression(node) }
|
return visitors.all { it.visitQualifiedReferenceExpression(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSimpleReferenceExpression(node: USimpleReferenceExpression): Boolean {
|
override fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression): Boolean {
|
||||||
return visitors.all { it.visitSimpleReferenceExpression(node) }
|
return visitors.all { it.visitSimpleNameReferenceExpression(node) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeReferenceExpression(node: UTypeReferenceExpression): Boolean {
|
||||||
|
return visitors.all { it.visitTypeReferenceExpression(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||||
@@ -103,8 +85,8 @@ class DelegatingUastVisitor(private val visitors: List<UastVisitor>): UastVisito
|
|||||||
return visitors.all { it.visitPostfixExpression(node) }
|
return visitors.all { it.visitPostfixExpression(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSpecialExpressionList(node: USpecialExpressionList): Boolean {
|
override fun visitExpressionList(node: UExpressionList): Boolean {
|
||||||
return visitors.all { it.visitSpecialExpressionList(node) }
|
return visitors.all { it.visitExpressionList(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitIfExpression(node: UIfExpression): Boolean {
|
override fun visitIfExpression(node: UIfExpression): Boolean {
|
||||||
@@ -139,6 +121,10 @@ class DelegatingUastVisitor(private val visitors: List<UastVisitor>): UastVisito
|
|||||||
return visitors.all { it.visitTryExpression(node) }
|
return visitors.all { it.visitTryExpression(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitCatchClause(node: UCatchClause): Boolean {
|
||||||
|
return visitors.all { it.visitCatchClause(node) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitLiteralExpression(node: ULiteralExpression): Boolean {
|
override fun visitLiteralExpression(node: ULiteralExpression): Boolean {
|
||||||
return visitors.all { it.visitLiteralExpression(node) }
|
return visitors.all { it.visitLiteralExpression(node) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,244 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.uast.visitor
|
|
||||||
|
|
||||||
import org.jetbrains.uast.*
|
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
|
||||||
|
|
||||||
class UastExtendableVisitor(
|
|
||||||
private val original: UastVisitor,
|
|
||||||
private val context: UastContext,
|
|
||||||
private val extensions: List<UastVisitorExtension>
|
|
||||||
) : UastVisitor {
|
|
||||||
private fun handleExtensions(node: UElement) {
|
|
||||||
if (node !is SynthesizedUElement) {
|
|
||||||
for (extension in extensions) {
|
|
||||||
extension.invoke(node, this, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitElement(node: UElement): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitElement(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFile(node: UFile): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitFile(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitImportStatement(node: UImportStatement): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitImportStatement(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitAnnotation(node: UAnnotation): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitAnnotation(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCatchClause(node: UCatchClause): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitCatchClause(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitType(node: UType): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitType(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClass(node: UClass): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitClass(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunction(node: UFunction): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitFunction(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitVariable(node: UVariable): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitVariable(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitLabeledExpression(node: ULabeledExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitLabeledExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitDeclarationsExpression(node: UDeclarationsExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitDeclarationsExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitBlockExpression(node: UBlockExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitBlockExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitQualifiedExpression(node: UQualifiedExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitQualifiedExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSimpleReferenceExpression(node: USimpleReferenceExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitSimpleReferenceExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitCallExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitBinaryExpression(node: UBinaryExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitBinaryExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitBinaryExpressionWithType(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitParenthesizedExpression(node: UParenthesizedExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitParenthesizedExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitUnaryExpression(node: UUnaryExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitUnaryExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitPrefixExpression(node: UPrefixExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitPrefixExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitPostfixExpression(node: UPostfixExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitPostfixExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSpecialExpressionList(node: USpecialExpressionList): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitSpecialExpressionList(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitIfExpression(node: UIfExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitIfExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSwitchExpression(node: USwitchExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitSwitchExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSwitchClauseExpression(node: USwitchClauseExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitSwitchClauseExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitWhileExpression(node: UWhileExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitWhileExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitDoWhileExpression(node: UDoWhileExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitDoWhileExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitForExpression(node: UForExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitForExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitForEachExpression(node: UForEachExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitForEachExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitTryExpression(node: UTryExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitTryExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitLiteralExpression(node: ULiteralExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitLiteralExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitThisExpression(node: UThisExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitThisExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSuperExpression(node: USuperExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitSuperExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitReturnExpression(node: UReturnExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return super.visitReturnExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitBreakExpression(node: UBreakExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitBreakExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitContinueExpression(node: UContinueExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitContinueExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitThrowExpression(node: UThrowExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitThrowExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitArrayAccessExpression(node: UArrayAccessExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitArrayAccessExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCallableReferenceExpression(node: UCallableReferenceExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitCallableReferenceExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClassLiteralExpression(node: UClassLiteralExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitClassLiteralExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitLambdaExpression(node: ULambdaExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitLambdaExpression(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitObjectLiteralExpression(node: UObjectLiteralExpression): Boolean {
|
|
||||||
handleExtensions(node)
|
|
||||||
return original.visitObjectLiteralExpression(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,109 +16,109 @@
|
|||||||
package org.jetbrains.uast.visitor
|
package org.jetbrains.uast.visitor
|
||||||
|
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
|
import org.jetbrains.uast.expressions.UTypeReferenceExpression
|
||||||
|
|
||||||
interface UastVisitor {
|
interface UastVisitor {
|
||||||
open fun visitElement(node: UElement): Boolean
|
fun visitElement(node: UElement): Boolean
|
||||||
|
|
||||||
open fun visitFile(node: UFile) = visitElement(node)
|
fun visitFile(node: UFile): Boolean = visitElement(node)
|
||||||
open fun visitImportStatement(node: UImportStatement) = visitElement(node)
|
fun visitImportStatement(node: UImportStatement): Boolean = visitElement(node)
|
||||||
open fun visitAnnotation(node: UAnnotation) = visitElement(node)
|
fun visitClass(node: UClass): Boolean = visitElement(node)
|
||||||
open fun visitCatchClause(node: UCatchClause) = visitElement(node)
|
fun visitInitializer(node: UClassInitializer): Boolean = visitElement(node)
|
||||||
open fun visitType(node: UType) = visitElement(node)
|
fun visitMethod(node: UMethod): Boolean = visitElement(node)
|
||||||
|
fun visitVariable(node: UVariable): Boolean = visitElement(node)
|
||||||
// Declarations
|
fun visitAnnotation(node: UAnnotation): Boolean = visitElement(node)
|
||||||
open fun visitClass(node: UClass) = visitElement(node)
|
|
||||||
open fun visitFunction(node: UFunction) = visitElement(node)
|
|
||||||
open fun visitVariable(node: UVariable) = visitElement(node)
|
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
open fun visitLabeledExpression(node: ULabeledExpression) = visitElement(node)
|
fun visitLabeledExpression(node: ULabeledExpression) = visitElement(node)
|
||||||
open fun visitDeclarationsExpression(node: UDeclarationsExpression) = visitElement(node)
|
fun visitDeclarationsExpression(node: UVariableDeclarationsExpression) = visitElement(node)
|
||||||
open fun visitBlockExpression(node: UBlockExpression) = visitElement(node)
|
fun visitBlockExpression(node: UBlockExpression) = visitElement(node)
|
||||||
open fun visitQualifiedExpression(node: UQualifiedExpression) = visitElement(node)
|
fun visitQualifiedReferenceExpression(node: UQualifiedReferenceExpression) = visitElement(node)
|
||||||
open fun visitSimpleReferenceExpression(node: USimpleReferenceExpression) = visitElement(node)
|
fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression) = visitElement(node)
|
||||||
open fun visitCallExpression(node: UCallExpression) = visitElement(node)
|
fun visitTypeReferenceExpression(node: UTypeReferenceExpression) = visitElement(node)
|
||||||
open fun visitBinaryExpression(node: UBinaryExpression) = visitElement(node)
|
fun visitCallExpression(node: UCallExpression) = visitElement(node)
|
||||||
open fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType) = visitElement(node)
|
fun visitBinaryExpression(node: UBinaryExpression) = visitElement(node)
|
||||||
open fun visitParenthesizedExpression(node: UParenthesizedExpression) = visitElement(node)
|
fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType) = visitElement(node)
|
||||||
open fun visitUnaryExpression(node: UUnaryExpression) = visitElement(node)
|
fun visitParenthesizedExpression(node: UParenthesizedExpression) = visitElement(node)
|
||||||
open fun visitPrefixExpression(node: UPrefixExpression) = visitElement(node)
|
fun visitUnaryExpression(node: UUnaryExpression) = visitElement(node)
|
||||||
open fun visitPostfixExpression(node: UPostfixExpression) = visitElement(node)
|
fun visitPrefixExpression(node: UPrefixExpression) = visitElement(node)
|
||||||
open fun visitSpecialExpressionList(node: USpecialExpressionList) = visitElement(node)
|
fun visitPostfixExpression(node: UPostfixExpression) = visitElement(node)
|
||||||
open fun visitIfExpression(node: UIfExpression) = visitElement(node)
|
fun visitExpressionList(node: UExpressionList) = visitElement(node)
|
||||||
open fun visitSwitchExpression(node: USwitchExpression) = visitElement(node)
|
fun visitIfExpression(node: UIfExpression) = visitElement(node)
|
||||||
open fun visitSwitchClauseExpression(node: USwitchClauseExpression) = visitElement(node)
|
fun visitSwitchExpression(node: USwitchExpression) = visitElement(node)
|
||||||
open fun visitWhileExpression(node: UWhileExpression) = visitElement(node)
|
fun visitSwitchClauseExpression(node: USwitchClauseExpression) = visitElement(node)
|
||||||
open fun visitDoWhileExpression(node: UDoWhileExpression) = visitElement(node)
|
fun visitWhileExpression(node: UWhileExpression) = visitElement(node)
|
||||||
open fun visitForExpression(node: UForExpression) = visitElement(node)
|
fun visitDoWhileExpression(node: UDoWhileExpression) = visitElement(node)
|
||||||
open fun visitForEachExpression(node: UForEachExpression) = visitElement(node)
|
fun visitForExpression(node: UForExpression) = visitElement(node)
|
||||||
open fun visitTryExpression(node: UTryExpression) = visitElement(node)
|
fun visitForEachExpression(node: UForEachExpression) = visitElement(node)
|
||||||
open fun visitLiteralExpression(node: ULiteralExpression) = visitElement(node)
|
fun visitTryExpression(node: UTryExpression) = visitElement(node)
|
||||||
open fun visitThisExpression(node: UThisExpression) = visitElement(node)
|
fun visitCatchClause(node: UCatchClause) = visitElement(node)
|
||||||
open fun visitSuperExpression(node: USuperExpression) = visitElement(node)
|
fun visitLiteralExpression(node: ULiteralExpression) = visitElement(node)
|
||||||
open fun visitReturnExpression(node: UReturnExpression) = visitElement(node)
|
fun visitThisExpression(node: UThisExpression) = visitElement(node)
|
||||||
open fun visitBreakExpression(node: UBreakExpression) = visitElement(node)
|
fun visitSuperExpression(node: USuperExpression) = visitElement(node)
|
||||||
open fun visitContinueExpression(node: UContinueExpression) = visitElement(node)
|
fun visitReturnExpression(node: UReturnExpression) = visitElement(node)
|
||||||
open fun visitThrowExpression(node: UThrowExpression) = visitElement(node)
|
fun visitBreakExpression(node: UBreakExpression) = visitElement(node)
|
||||||
open fun visitArrayAccessExpression(node: UArrayAccessExpression) = visitElement(node)
|
fun visitContinueExpression(node: UContinueExpression) = visitElement(node)
|
||||||
open fun visitCallableReferenceExpression(node: UCallableReferenceExpression) = visitElement(node)
|
fun visitThrowExpression(node: UThrowExpression) = visitElement(node)
|
||||||
open fun visitClassLiteralExpression(node: UClassLiteralExpression) = visitElement(node)
|
fun visitArrayAccessExpression(node: UArrayAccessExpression) = visitElement(node)
|
||||||
open fun visitLambdaExpression(node: ULambdaExpression) = visitElement(node)
|
fun visitCallableReferenceExpression(node: UCallableReferenceExpression) = visitElement(node)
|
||||||
open fun visitObjectLiteralExpression(node: UObjectLiteralExpression) = visitElement(node)
|
fun visitClassLiteralExpression(node: UClassLiteralExpression) = visitElement(node)
|
||||||
|
fun visitLambdaExpression(node: ULambdaExpression) = visitElement(node)
|
||||||
|
fun visitObjectLiteralExpression(node: UObjectLiteralExpression) = visitElement(node)
|
||||||
|
|
||||||
// After
|
// After
|
||||||
|
|
||||||
open fun afterVisitElement(node: UElement) {}
|
fun afterVisitElement(node: UElement) {}
|
||||||
|
|
||||||
open fun afterVisitFile(node: UFile) {}
|
fun afterVisitFile(node: UFile) { afterVisitElement(node) }
|
||||||
open fun afterVisitImportStatement(node: UImportStatement) {}
|
fun afterVisitImportStatement(node: UImportStatement) { afterVisitElement(node) }
|
||||||
open fun afterVisitAnnotation(node: UAnnotation) {}
|
fun afterVisitClass(node: UClass) { afterVisitElement(node) }
|
||||||
open fun afterVisitCatchClause(node: UCatchClause) {}
|
fun afterVisitInitializer(node: UClassInitializer) { afterVisitElement(node) }
|
||||||
open fun afterVisitType(node: UType) {}
|
fun afterVisitMethod(node: UMethod) { afterVisitElement(node) }
|
||||||
|
fun afterVisitVariable(node: UVariable) { afterVisitElement(node) }
|
||||||
// Declarations
|
fun afterVisitAnnotation(node: UAnnotation) { afterVisitElement(node) }
|
||||||
open fun afterVisitClass(node: UClass) {}
|
|
||||||
open fun afterVisitFunction(node: UFunction) {}
|
|
||||||
open fun afterVisitVariable(node: UVariable) {}
|
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
open fun afterVisitLabeledExpression(node: ULabeledExpression) {}
|
fun afterVisitLabeledExpression(node: ULabeledExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitDeclarationsExpression(node: UDeclarationsExpression) {}
|
fun afterVisitDeclarationsExpression(node: UVariableDeclarationsExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitBlockExpression(node: UBlockExpression) {}
|
fun afterVisitBlockExpression(node: UBlockExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitQualifiedExpression(node: UQualifiedExpression) {}
|
fun afterVisitQualifiedReferenceExpression(node: UQualifiedReferenceExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitSimpleReferenceExpression(node: USimpleReferenceExpression) {}
|
fun afterVisitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitCallExpression(node: UCallExpression) {}
|
fun afterVisitTypeReferenceExpression(node: UTypeReferenceExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitBinaryExpression(node: UBinaryExpression) {}
|
fun afterVisitCallExpression(node: UCallExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitBinaryExpressionWithType(node: UBinaryExpressionWithType) {}
|
fun afterVisitBinaryExpression(node: UBinaryExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitParenthesizedExpression(node: UParenthesizedExpression) {}
|
fun afterVisitBinaryExpressionWithType(node: UBinaryExpressionWithType) { afterVisitElement(node) }
|
||||||
open fun afterVisitUnaryExpression(node: UUnaryExpression) {}
|
fun afterVisitParenthesizedExpression(node: UParenthesizedExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitPrefixExpression(node: UPrefixExpression) {}
|
fun afterVisitUnaryExpression(node: UUnaryExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitPostfixExpression(node: UPostfixExpression) {}
|
fun afterVisitPrefixExpression(node: UPrefixExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitSpecialExpressionList(node: USpecialExpressionList) {}
|
fun afterVisitPostfixExpression(node: UPostfixExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitIfExpression(node: UIfExpression) {}
|
fun afterVisitExpressionList(node: UExpressionList) { afterVisitElement(node) }
|
||||||
open fun afterVisitSwitchExpression(node: USwitchExpression) {}
|
fun afterVisitIfExpression(node: UIfExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitSwitchClauseExpression(node: USwitchClauseExpression) {}
|
fun afterVisitSwitchExpression(node: USwitchExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitWhileExpression(node: UWhileExpression) {}
|
fun afterVisitSwitchClauseExpression(node: USwitchClauseExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitDoWhileExpression(node: UDoWhileExpression) {}
|
fun afterVisitWhileExpression(node: UWhileExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitForExpression(node: UForExpression) {}
|
fun afterVisitDoWhileExpression(node: UDoWhileExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitForEachExpression(node: UForEachExpression) {}
|
fun afterVisitForExpression(node: UForExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitTryExpression(node: UTryExpression) {}
|
fun afterVisitForEachExpression(node: UForEachExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitLiteralExpression(node: ULiteralExpression) {}
|
fun afterVisitTryExpression(node: UTryExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitThisExpression(node: UThisExpression) {}
|
fun afterVisitCatchClause(node: UCatchClause) { afterVisitElement(node) }
|
||||||
open fun afterVisitSuperExpression(node: USuperExpression) {}
|
fun afterVisitLiteralExpression(node: ULiteralExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitReturnExpression(node: UReturnExpression) {}
|
fun afterVisitThisExpression(node: UThisExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitBreakExpression(node: UBreakExpression) {}
|
fun afterVisitSuperExpression(node: USuperExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitContinueExpression(node: UContinueExpression) {}
|
fun afterVisitReturnExpression(node: UReturnExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitThrowExpression(node: UThrowExpression) {}
|
fun afterVisitBreakExpression(node: UBreakExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitArrayAccessExpression(node: UArrayAccessExpression) {}
|
fun afterVisitContinueExpression(node: UContinueExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitCallableReferenceExpression(node: UCallableReferenceExpression) {}
|
fun afterVisitThrowExpression(node: UThrowExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitClassLiteralExpression(node: UClassLiteralExpression) {}
|
fun afterVisitArrayAccessExpression(node: UArrayAccessExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitLambdaExpression(node: ULambdaExpression) {}
|
fun afterVisitCallableReferenceExpression(node: UCallableReferenceExpression) { afterVisitElement(node) }
|
||||||
open fun afterVisitObjectLiteralExpression(node: UObjectLiteralExpression) {}
|
fun afterVisitClassLiteralExpression(node: UClassLiteralExpression) { afterVisitElement(node) }
|
||||||
|
fun afterVisitLambdaExpression(node: ULambdaExpression) { afterVisitElement(node) }
|
||||||
|
fun afterVisitObjectLiteralExpression(node: UObjectLiteralExpression) { afterVisitElement(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AbstractUastVisitor : UastVisitor {
|
abstract class AbstractUastVisitor : UastVisitor {
|
||||||
override fun visitElement(node: UElement): Boolean = false
|
override fun visitElement(node: UElement): Boolean = false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object EmptyUastVisitor : AbstractUastVisitor()
|
object EmptyUastVisitor : AbstractUastVisitor()
|
||||||
@@ -8,5 +8,6 @@
|
|||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||||
|
<orderEntry type="library" exported="" name="intellij-core" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,15 +16,42 @@
|
|||||||
|
|
||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
import org.jetbrains.uast.UElement
|
import com.intellij.psi.*
|
||||||
|
import org.jetbrains.uast.UExpression
|
||||||
|
import org.jetbrains.uast.java.internal.JavaUElementWithComments
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
abstract class JavaAbstractUElement : UElement {
|
abstract class JavaAbstractUElement : JavaUElementWithComments {
|
||||||
|
private val psiElement: PsiElement?
|
||||||
|
get() = (this as? PsiElementBacked)?.psi
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this !is PsiElementBacked || other !is PsiElementBacked) {
|
if (this !is PsiElementBacked || other !is PsiElementBacked) {
|
||||||
return this === other
|
return this === other
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (other.javaClass != this.javaClass) return false
|
||||||
return this.psi == other.psi
|
return this.psi == other.psi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun asSourceString(): String {
|
||||||
|
if (this is PsiElementBacked) {
|
||||||
|
return this.psi?.text ?: super<JavaUElementWithComments>.asSourceString()
|
||||||
|
}
|
||||||
|
return super<JavaUElementWithComments>.asSourceString()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString() = asRenderString()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class JavaAbstractUExpression : JavaAbstractUElement(), UExpression {
|
||||||
|
override fun evaluate(): Any? {
|
||||||
|
val psi = (this as? PsiElementBacked)?.psi ?: return null
|
||||||
|
return JavaPsiFacade.getInstance(psi.project).constantEvaluationHelper.computeConstantExpression(psi)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExpressionType(): PsiType? {
|
||||||
|
val expression = (this as? PsiElementBacked)?.psi as? PsiExpression ?: return null
|
||||||
|
return expression.type
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2015 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,215 +16,274 @@
|
|||||||
|
|
||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
|
import com.intellij.lang.Language
|
||||||
|
import com.intellij.lang.java.JavaLanguage
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
import org.jetbrains.uast.java.expressions.JavaUSynchronizedExpression
|
import org.jetbrains.uast.java.expressions.JavaUSynchronizedExpression
|
||||||
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
object JavaUastLanguagePlugin : UastLanguagePlugin {
|
class JavaUastLanguagePlugin(override val project: Project) : UastLanguagePlugin {
|
||||||
override val converter: UastConverter = JavaConverter
|
override val priority = 0
|
||||||
override val visitorExtensions: List<UastVisitorExtension>
|
|
||||||
get() = emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object JavaConverter : UastConverter {
|
override fun isFileSupported(fileName: String) = fileName.endsWith(".java", ignoreCase = true)
|
||||||
override fun isFileSupported(name: String): Boolean {
|
|
||||||
return name.endsWith(".java", ignoreCase = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun convert(file: PsiJavaFile): UFile = JavaUFile(file)
|
override val language: Language
|
||||||
|
get() = JavaLanguage.INSTANCE
|
||||||
|
|
||||||
override fun convert(element: Any?, parent: UElement): UElement? {
|
override fun isExpressionValueUsed(element: UExpression): Boolean = when (element) {
|
||||||
if (element !is PsiElement) return null
|
is JavaUVariableDeclarationsExpression -> false
|
||||||
return convertPsiElement(element, parent)
|
is UnknownJavaExpression -> (element.containingElement as? UExpression)?.let { isExpressionValueUsed(it) } ?: false
|
||||||
}
|
else -> {
|
||||||
|
val statement = (element as? PsiElementBacked)?.psi as? PsiStatement
|
||||||
override fun convertWithParent(element: Any?): UElement? {
|
statement != null && statement.parent !is PsiExpressionStatement
|
||||||
if (element !is PsiElement) return null
|
|
||||||
if (element is PsiJavaFile) return JavaUFile(element)
|
|
||||||
|
|
||||||
val parent = element.parent ?: return null
|
|
||||||
val parentUElement = convertWithParent(parent) ?: return null
|
|
||||||
return convertPsiElement(element, parentUElement)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun convertPsiElement(element: PsiElement?, parent: UElement) = when (element) {
|
|
||||||
is PsiJavaFile -> JavaUFile(element)
|
|
||||||
is PsiClass -> JavaUClass(element, parent)
|
|
||||||
is PsiCodeBlock -> convert(element, parent)
|
|
||||||
is PsiMethod -> convert(element, parent)
|
|
||||||
is PsiField -> convert(element, parent)
|
|
||||||
is PsiVariable -> convert(element, parent)
|
|
||||||
is PsiClassInitializer -> convert(element, parent)
|
|
||||||
is PsiAnnotation -> convert(element, parent)
|
|
||||||
is PsiResourceExpression -> convert(element.expression, parent)
|
|
||||||
is PsiExpression -> convert(element, parent)
|
|
||||||
is PsiStatement -> convert(element, parent)
|
|
||||||
is PsiIdentifier -> JavaUSimpleReferenceExpression(element, element.text, parent)
|
|
||||||
is PsiImportStatementBase -> convert(element, parent)
|
|
||||||
is PsiParameter -> convert(element, parent)
|
|
||||||
is PsiTypeParameter -> convert(element, parent)
|
|
||||||
is PsiNameValuePair -> convert(element, parent)
|
|
||||||
is PsiType -> convert(element, parent)
|
|
||||||
is PsiArrayInitializerMemberValue -> JavaAnnotationArrayInitializerUCallExpression(element, parent)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun convert(importStatement: PsiImportStatementBase, parent: UElement): UImportStatement? = when (importStatement) {
|
|
||||||
is PsiImportStatement -> JavaUImportStatement(importStatement, parent)
|
|
||||||
is PsiImportStaticStatement -> JavaUStaticImportStatement(importStatement, parent)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun convert(type: PsiType?, parent: UElement) = JavaUType(type, parent)
|
|
||||||
|
|
||||||
internal fun convert(parameter: PsiParameter, parent: UElement) = JavaValueParameterUVariable(parameter, parent)
|
|
||||||
|
|
||||||
internal fun convert(block: PsiCodeBlock, parent: UElement) = JavaUCodeBlockExpression(block, parent)
|
|
||||||
|
|
||||||
internal fun convert(method: PsiMethod, parent: UElement) = JavaUFunction(method, parent)
|
|
||||||
|
|
||||||
internal fun convert(field: PsiField, parent: UElement) = JavaUVariable(field, parent)
|
|
||||||
|
|
||||||
internal fun convert(variable: PsiVariable, parent: UElement) = JavaUVariable(variable, parent)
|
|
||||||
|
|
||||||
internal fun convert(annotation: PsiAnnotation, parent: UElement) = JavaUAnnotation(annotation, parent)
|
|
||||||
|
|
||||||
internal fun convert(clazz: PsiClass, parent: UElement) = JavaUClass(clazz, parent)
|
|
||||||
|
|
||||||
internal fun convert(initializer: PsiClassInitializer, parent: UElement) = JavaClassInitializerUFunction(initializer, parent)
|
|
||||||
|
|
||||||
internal fun convert(parameter: PsiTypeParameter, parent: UElement) = JavaParameterUTypeReference(parameter, parent)
|
|
||||||
|
|
||||||
internal fun convert(pair: PsiNameValuePair, parent: UElement) = UNamedExpression(pair.name.orAnonymous(), parent).apply {
|
|
||||||
val value = pair.value
|
|
||||||
expression = convert(value, this) as? UExpression ?: UnknownJavaExpression(value ?: pair, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun convert(expression: PsiReferenceExpression, parent: UElement): UExpression {
|
|
||||||
return if (expression.isQualified) {
|
|
||||||
JavaUQualifiedExpression(expression, parent)
|
|
||||||
} else {
|
|
||||||
val name = expression.referenceName ?: "<error name>"
|
|
||||||
val element = expression.referenceNameElement ?: expression
|
|
||||||
JavaUSimpleReferenceExpression(element, name, parent)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun convert(expression: PsiQualifiedReferenceElement, parent: UElement): UExpression {
|
override fun getMethodCallExpression(
|
||||||
val referenceName = expression.referenceName ?: "<error name>"
|
element: PsiElement,
|
||||||
val referenceNameElement = expression.element ?: expression
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
return JavaUCompositeQualifiedExpression(parent).apply {
|
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||||
receiver = expression.qualifier?.let { convert(it, this) } as? UExpression ?: EmptyUExpression(parent)
|
if (element !is PsiElement) return null
|
||||||
selector = JavaUSimpleReferenceExpression(referenceNameElement, referenceName, this)
|
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 JavaUFile(element, this)
|
||||||
|
JavaConverter.getCached<UElement>(element)?.let { return it }
|
||||||
|
|
||||||
|
val parent = JavaConverter.unwrapElements(element.parent) ?: return null
|
||||||
|
val parentUElement = convertElementWithParent(parent, null) ?: return null
|
||||||
|
return convertElement(element, parentUElement, requiredType)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun convertDeclaration(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||||
|
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 -> element
|
||||||
|
is PsiClass -> el<UClass> { JavaUClass.create(element, parent) }
|
||||||
|
is PsiMethod -> el<UMethod> { JavaUMethod.create(element, this@JavaUastLanguagePlugin, parent) }
|
||||||
|
is PsiClassInitializer -> el<UClassInitializer> { JavaUClassInitializer(element, parent) }
|
||||||
|
is PsiVariable -> el<UVariable> { JavaUVariable.create(element, parent) }
|
||||||
|
is UAnnotation -> el<UAnnotation> { SimpleUAnnotation(element, parent) } //???
|
||||||
|
else -> null
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <reified T : UElement> Class<out UElement>?.el(f: () -> UElement?): UElement? {
|
||||||
|
return if (this == null || T::class.java == this) f() else null
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <reified T : UElement> Class<out UElement>?.expr(f: () -> UExpression): UExpression {
|
||||||
|
return if (this == null || T::class.java == this) f() else UastEmptyExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object JavaConverter {
|
||||||
|
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)
|
||||||
|
else -> element
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun convertPsiElement(el: PsiElement, parent: UElement?, requiredType: Class<out UElement>? = null): UElement? {
|
||||||
|
getCached<UElement>(el)?.let { return it }
|
||||||
|
|
||||||
|
return with (requiredType) { when (el) {
|
||||||
|
is PsiCodeBlock -> el<UBlockExpression> { convertBlock(el, parent) }
|
||||||
|
is PsiResourceExpression -> convertExpression(el.expression, parent, requiredType)
|
||||||
|
is PsiExpression -> convertExpression(el, parent, requiredType)
|
||||||
|
is PsiStatement -> convertStatement(el, parent, requiredType)
|
||||||
|
is PsiIdentifier -> el<USimpleNameReferenceExpression> { JavaUSimpleNameReferenceExpression(el, el.text, parent) }
|
||||||
|
is PsiNameValuePair -> el<UNamedExpression> { convertNameValue(el, parent) }
|
||||||
|
is PsiArrayInitializerMemberValue -> el<UCallExpression> { JavaAnnotationArrayInitializerUCallExpression(el, parent) }
|
||||||
|
else -> null
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun convertBlock(block: PsiCodeBlock, parent: UElement?): UBlockExpression =
|
||||||
|
getCached(block) ?: JavaUCodeBlockExpression(block, parent)
|
||||||
|
|
||||||
|
internal fun convertNameValue(pair: PsiNameValuePair, parent: UElement?): UNamedExpression {
|
||||||
|
return UNamedExpression.create(pair.name.orAnonymous(), parent) {
|
||||||
|
val value = pair.value as? PsiElement
|
||||||
|
value?.let { convertPsiElement(it, this, null) as? UExpression } ?: UnknownJavaExpression(value ?: pair, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun convertReference(expression: PsiReferenceExpression, parent: UElement?, requiredType: Class<out UElement>?): UExpression {
|
||||||
|
return with (requiredType) {
|
||||||
|
if (expression.isQualified) {
|
||||||
|
expr<UQualifiedReferenceExpression> { JavaUQualifiedReferenceExpression(expression, parent) }
|
||||||
|
} else {
|
||||||
|
val name = expression.referenceName ?: "<error name>"
|
||||||
|
expr<USimpleNameReferenceExpression> { JavaUSimpleNameReferenceExpression(expression, name, parent, expression) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertPolyadicExpression(
|
private fun convertPolyadicExpression(
|
||||||
expression: PsiPolyadicExpression,
|
expression: PsiPolyadicExpression,
|
||||||
parent: UElement,
|
parent: UElement?,
|
||||||
i: Int
|
i: Int
|
||||||
): UExpression {
|
): UBinaryExpression {
|
||||||
return if (i == 1) JavaSeparatedPolyadicUBinaryExpression(expression, parent).apply {
|
return if (i == 1) JavaSeparatedPolyadicUBinaryExpression(expression, parent).apply {
|
||||||
leftOperand = convert(expression.operands[0], this)
|
leftOperand = convertExpression(expression.operands[0], this)
|
||||||
rightOperand = convert(expression.operands[1], this)
|
rightOperand = convertExpression(expression.operands[1], this)
|
||||||
} else JavaSeparatedPolyadicUBinaryExpression(expression, parent).apply {
|
} else JavaSeparatedPolyadicUBinaryExpression(expression, parent).apply {
|
||||||
leftOperand = convertPolyadicExpression(expression, parent, i - 1)
|
leftOperand = convertPolyadicExpression(expression, parent, i - 1)
|
||||||
rightOperand = convert(expression.operands[i], this)
|
rightOperand = convertExpression(expression.operands[i], this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun convertExpression(el: PsiExpression, parent: UElement?, requiredType: Class<out UElement>? = null): UExpression {
|
||||||
|
getCached<UExpression>(el)?.let { return it }
|
||||||
|
|
||||||
internal fun convert(expression: PsiExpression, parent: UElement): UExpression = when (expression) {
|
return with (requiredType) { when (el) {
|
||||||
is PsiPolyadicExpression -> convertPolyadicExpression(expression, parent, expression.operands.size - 1)
|
is PsiPolyadicExpression -> expr<UBinaryExpression> { convertPolyadicExpression(el, parent, el.operands.size - 1) }
|
||||||
is PsiAssignmentExpression -> JavaUAssignmentExpression(expression, parent)
|
is PsiAssignmentExpression -> expr<UBinaryExpression> { JavaUAssignmentExpression(el, parent) }
|
||||||
is PsiConditionalExpression -> JavaUTernaryIfExpression(expression, parent)
|
is PsiConditionalExpression -> expr<UIfExpression> { JavaUTernaryIfExpression(el, parent) }
|
||||||
is PsiNewExpression -> {
|
is PsiNewExpression -> {
|
||||||
if (expression.anonymousClass != null) {
|
if (el.anonymousClass != null)
|
||||||
JavaUObjectLiteralExpression(expression, parent)
|
expr<UObjectLiteralExpression> { JavaUObjectLiteralExpression(el, parent) }
|
||||||
} else {
|
else
|
||||||
JavaConstructorUCallExpression(expression, parent)
|
expr<UCallExpression> { JavaConstructorUCallExpression(el, parent) }
|
||||||
}
|
}
|
||||||
}
|
is PsiMethodCallExpression -> {
|
||||||
is PsiMethodCallExpression -> {
|
if (el.methodExpression.qualifierExpression != null)
|
||||||
val qualifier = expression.methodExpression.qualifierExpression
|
expr<UQualifiedReferenceExpression> {
|
||||||
if (qualifier != null) {
|
JavaUCompositeQualifiedExpression(el, parent).apply {
|
||||||
JavaUCompositeQualifiedExpression(parent).apply {
|
receiver = convertExpression(el.methodExpression.qualifierExpression!!, this)
|
||||||
receiver = convert(qualifier, this)
|
selector = JavaUCallExpression(el, this)
|
||||||
selector = JavaUCallExpression(expression, this)
|
}
|
||||||
}
|
}
|
||||||
} else {
|
else
|
||||||
JavaUCallExpression(expression, parent)
|
expr<UCallExpression> { JavaUCallExpression(el, parent) }
|
||||||
}
|
}
|
||||||
}
|
is PsiArrayInitializerExpression -> expr<UCallExpression> { JavaArrayInitializerUCallExpression(el, parent) }
|
||||||
is PsiArrayInitializerExpression -> JavaArrayInitializerUCallExpression(expression, parent)
|
is PsiBinaryExpression -> expr<UBinaryExpression> { JavaUBinaryExpression(el, parent) }
|
||||||
is PsiBinaryExpression -> JavaUBinaryExpression(expression, parent)
|
is PsiParenthesizedExpression -> expr<UParenthesizedExpression> { JavaUParenthesizedExpression(el, parent) }
|
||||||
is PsiParenthesizedExpression -> JavaUParenthesizedExpression(expression, parent)
|
is PsiPrefixExpression -> expr<UPrefixExpression> { JavaUPrefixExpression(el, parent) }
|
||||||
is PsiPrefixExpression -> JavaUPrefixExpression(expression, parent)
|
is PsiPostfixExpression -> expr<UPostfixExpression> { JavaUPostfixExpression(el, parent) }
|
||||||
is PsiPostfixExpression -> JavaUPostfixExpression(expression, parent)
|
is PsiLiteralExpression -> expr<ULiteralExpression> { JavaULiteralExpression(el, parent) }
|
||||||
is PsiLiteralExpression -> JavaULiteralExpression(expression, parent)
|
is PsiReferenceExpression -> convertReference(el, parent, requiredType)
|
||||||
is PsiReferenceExpression -> convert(expression, parent)
|
is PsiThisExpression -> expr<UThisExpression> { JavaUThisExpression(el, parent) }
|
||||||
is PsiThisExpression -> JavaUThisExpression(expression, parent)
|
is PsiSuperExpression -> expr<USuperExpression> { JavaUSuperExpression(el, parent) }
|
||||||
is PsiSuperExpression -> JavaUSuperExpression(expression, parent)
|
is PsiInstanceOfExpression -> expr<UBinaryExpressionWithType> { JavaUInstanceCheckExpression(el, parent) }
|
||||||
is PsiInstanceOfExpression -> JavaUInstanceCheckExpression(expression, parent)
|
is PsiTypeCastExpression -> expr<UBinaryExpressionWithType> { JavaUTypeCastExpression(el, parent) }
|
||||||
is PsiTypeCastExpression -> JavaUTypeCastExpression(expression, parent)
|
is PsiClassObjectAccessExpression -> expr<UClassLiteralExpression> { JavaUClassLiteralExpression(el, parent) }
|
||||||
is PsiClassObjectAccessExpression -> JavaUClassLiteralExpression(expression, parent)
|
is PsiArrayAccessExpression -> expr<UArrayAccessExpression> { JavaUArrayAccessExpression(el, parent) }
|
||||||
is PsiArrayAccessExpression -> JavaUArrayAccessExpression(expression, parent)
|
is PsiLambdaExpression -> expr<ULambdaExpression> { JavaULambdaExpression(el, parent) }
|
||||||
is PsiLambdaExpression -> JavaULambdaExpression(expression, parent)
|
is PsiMethodReferenceExpression -> expr<UCallableReferenceExpression> { JavaUCallableReferenceExpression(el, parent) }
|
||||||
is PsiMethodReferenceExpression -> JavaUCallableReferenceExpression(expression, parent)
|
else -> UnknownJavaExpression(el, parent)
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun convertStatement(el: PsiStatement, parent: UElement?, requiredType: Class<out UElement>? = null): UExpression {
|
||||||
|
getCached<UExpression>(el)?.let { return it }
|
||||||
|
|
||||||
else -> UnknownJavaExpression(expression, parent)
|
return with (requiredType) { when (el) {
|
||||||
|
is PsiDeclarationStatement -> expr<UVariableDeclarationsExpression> { convertDeclarations(el.declaredElements, parent!!) }
|
||||||
|
is PsiExpressionListStatement -> expr<UVariableDeclarationsExpression> { convertDeclarations(el.expressionList.expressions, parent!!) }
|
||||||
|
is PsiBlockStatement -> expr<UBlockExpression> { JavaUBlockExpression(el, parent) }
|
||||||
|
is PsiLabeledStatement -> expr<ULabeledExpression> { JavaULabeledExpression(el, parent) }
|
||||||
|
is PsiExpressionStatement -> convertExpression(el.expression, parent, requiredType)
|
||||||
|
is PsiIfStatement -> expr<UIfExpression> { JavaUIfExpression(el, parent) }
|
||||||
|
is PsiSwitchStatement -> expr<USwitchExpression> { JavaUSwitchExpression(el, parent) }
|
||||||
|
is PsiSwitchLabelStatement -> expr<USwitchClauseExpression> {
|
||||||
|
if (el.isDefaultCase)
|
||||||
|
DefaultUSwitchClauseExpression(parent)
|
||||||
|
else JavaUCaseSwitchClauseExpression(el, parent)
|
||||||
|
}
|
||||||
|
is PsiWhileStatement -> expr<UWhileExpression> { JavaUWhileExpression(el, parent) }
|
||||||
|
is PsiDoWhileStatement -> expr<UDoWhileExpression> { JavaUDoWhileExpression(el, parent) }
|
||||||
|
is PsiForStatement -> expr<UForExpression> { JavaUForExpression(el, parent) }
|
||||||
|
is PsiForeachStatement -> expr<UForEachExpression> { JavaUForEachExpression(el, parent) }
|
||||||
|
is PsiBreakStatement -> expr<UBreakExpression> { JavaUBreakExpression(el, parent) }
|
||||||
|
is PsiContinueStatement -> expr<UContinueExpression> { JavaUContinueExpression(el, parent) }
|
||||||
|
is PsiReturnStatement -> expr<UReturnExpression> { JavaUReturnExpression(el, parent) }
|
||||||
|
is PsiAssertStatement -> expr<UCallExpression> { JavaUAssertExpression(el, parent) }
|
||||||
|
is PsiThrowStatement -> expr<UThrowExpression> { JavaUThrowExpression(el, parent) }
|
||||||
|
is PsiSynchronizedStatement -> expr<UBlockExpression> { JavaUSynchronizedExpression(el, parent) }
|
||||||
|
is PsiTryStatement -> expr<UTryExpression> { JavaUTryExpression(el, parent) }
|
||||||
|
else -> UnknownJavaExpression(el, parent)
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun convert(statement: PsiStatement, parent: UElement): UExpression = when (statement) {
|
private fun convertDeclarations(elements: Array<out PsiElement>, parent: UElement): UVariableDeclarationsExpression {
|
||||||
is PsiDeclarationStatement -> convertDeclarations(statement.declaredElements, parent)
|
return JavaUVariableDeclarationsExpression(parent).apply {
|
||||||
is PsiExpressionListStatement -> convertDeclarations(statement.expressionList.expressions, parent)
|
val variables = mutableListOf<UVariable>()
|
||||||
is PsiBlockStatement -> JavaUBlockExpression(statement, parent)
|
|
||||||
is PsiLabeledStatement -> JavaULabeledExpression(statement, parent)
|
|
||||||
is PsiExpressionStatement -> convert(statement.expression, parent)
|
|
||||||
is PsiIfStatement -> JavaUIfExpression(statement, parent)
|
|
||||||
is PsiSwitchStatement -> JavaUSwitchExpression(statement, parent)
|
|
||||||
is PsiSwitchLabelStatement -> {
|
|
||||||
if (statement.isDefaultCase)
|
|
||||||
DefaultUSwitchClauseExpression(parent)
|
|
||||||
else JavaUCaseSwitchClauseExpression(statement, parent)
|
|
||||||
}
|
|
||||||
is PsiWhileStatement -> JavaUWhileExpression(statement, parent)
|
|
||||||
is PsiDoWhileStatement -> JavaUDoWhileExpression(statement, parent)
|
|
||||||
is PsiForStatement -> JavaUForExpression(statement, parent)
|
|
||||||
is PsiForeachStatement -> JavaUForEachExpression(statement, parent)
|
|
||||||
is PsiBreakStatement -> JavaUBreakExpression(statement, parent)
|
|
||||||
is PsiContinueStatement -> JavaUContinueExpression(statement, parent)
|
|
||||||
is PsiReturnStatement -> JavaUReturnExpression(statement, parent)
|
|
||||||
is PsiAssertStatement -> JavaUAssertExpression(statement, parent)
|
|
||||||
is PsiThrowStatement -> JavaUThrowExpression(statement, parent)
|
|
||||||
is PsiSynchronizedStatement -> JavaUSynchronizedExpression(statement, parent)
|
|
||||||
is PsiTryStatement -> JavaUTryExpression(statement, parent)
|
|
||||||
|
|
||||||
else -> UnknownJavaExpression(statement, parent)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun convertOrEmpty(statement: PsiStatement?, parent: UElement): UExpression {
|
|
||||||
return if (statement != null) convert(statement, parent) else EmptyUExpression(parent)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun convertOrEmpty(expression: PsiExpression?, parent: UElement): UExpression {
|
|
||||||
return if (expression != null) convert(expression, parent) else EmptyUExpression(parent)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun convertOrNull(expression: PsiExpression?, parent: UElement): UExpression? {
|
|
||||||
return if (expression != null) convert(expression, parent) else null
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun convertOrEmpty(block: PsiCodeBlock?, parent: UElement): UExpression {
|
|
||||||
return if (block != null) convert(block, parent) else EmptyUExpression(parent)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun convertDeclarations(elements: Array<out PsiElement>, parent: UElement): SimpleUDeclarationsExpression {
|
|
||||||
val uelements = arrayListOf<UElement>()
|
|
||||||
return SimpleUDeclarationsExpression(parent, uelements).apply {
|
|
||||||
for (element in elements) {
|
for (element in elements) {
|
||||||
convert(element, this)?.let { uelements += it }
|
if (element !is PsiVariable) continue
|
||||||
|
variables += JavaUVariable.create(element, this)
|
||||||
}
|
}
|
||||||
|
this.variables = variables
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun convertOrEmpty(statement: PsiStatement?, parent: UElement?): UExpression {
|
||||||
|
return statement?.let { convertStatement(it, parent, null) } ?: UastEmptyExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun convertOrEmpty(expression: PsiExpression?, parent: UElement?): UExpression {
|
||||||
|
return expression?.let { convertExpression(it, parent) } ?: 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+9
-2
@@ -16,14 +16,21 @@
|
|||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
import com.intellij.psi.PsiDoWhileStatement
|
import com.intellij.psi.PsiDoWhileStatement
|
||||||
|
import com.intellij.psi.impl.source.tree.ChildRole
|
||||||
import org.jetbrains.uast.UDoWhileExpression
|
import org.jetbrains.uast.UDoWhileExpression
|
||||||
import org.jetbrains.uast.UElement
|
import org.jetbrains.uast.UElement
|
||||||
|
import org.jetbrains.uast.UIdentifier
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
class JavaUDoWhileExpression(
|
class JavaUDoWhileExpression(
|
||||||
override val psi: PsiDoWhileStatement,
|
override val psi: PsiDoWhileStatement,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), UDoWhileExpression, PsiElementBacked {
|
) : JavaAbstractUExpression(), UDoWhileExpression, PsiElementBacked {
|
||||||
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
||||||
override val body by lz { JavaConverter.convertOrEmpty(psi.body, 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)
|
||||||
}
|
}
|
||||||
+10
-3
@@ -16,16 +16,23 @@
|
|||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
import com.intellij.psi.PsiForeachStatement
|
import com.intellij.psi.PsiForeachStatement
|
||||||
|
import com.intellij.psi.impl.source.tree.ChildRole
|
||||||
import org.jetbrains.uast.UElement
|
import org.jetbrains.uast.UElement
|
||||||
import org.jetbrains.uast.UForEachExpression
|
import org.jetbrains.uast.UForEachExpression
|
||||||
|
import org.jetbrains.uast.UIdentifier
|
||||||
|
import org.jetbrains.uast.UParameter
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
class JavaUForEachExpression(
|
class JavaUForEachExpression(
|
||||||
override val psi: PsiForeachStatement,
|
override val psi: PsiForeachStatement,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), UForEachExpression, PsiElementBacked {
|
) : JavaAbstractUExpression(), UForEachExpression, PsiElementBacked {
|
||||||
override val variable by lz { JavaConverter.convert(psi.iterationParameter, this) }
|
override val variable: UParameter
|
||||||
|
get() = JavaUParameter(psi.iterationParameter, this)
|
||||||
|
|
||||||
override val iteratedValue by lz { JavaConverter.convertOrEmpty(psi.iteratedValue, this) }
|
override val iteratedValue by lz { JavaConverter.convertOrEmpty(psi.iteratedValue, this) }
|
||||||
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
||||||
|
|
||||||
|
override val forIdentifier: UIdentifier
|
||||||
|
get() = UIdentifier(psi.getChildByRole(ChildRole.FOR_KEYWORD), this)
|
||||||
}
|
}
|
||||||
+10
-5
@@ -16,16 +16,21 @@
|
|||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
import com.intellij.psi.PsiForStatement
|
import com.intellij.psi.PsiForStatement
|
||||||
|
import com.intellij.psi.impl.source.tree.ChildRole
|
||||||
import org.jetbrains.uast.UElement
|
import org.jetbrains.uast.UElement
|
||||||
import org.jetbrains.uast.UForExpression
|
import org.jetbrains.uast.UForExpression
|
||||||
|
import org.jetbrains.uast.UIdentifier
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
class JavaUForExpression(
|
class JavaUForExpression(
|
||||||
override val psi: PsiForStatement,
|
override val psi: PsiForStatement,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), UForExpression, PsiElementBacked {
|
) : JavaAbstractUExpression(), UForExpression, PsiElementBacked {
|
||||||
override val declaration by lz { psi.initialization?.let { JavaConverter.convert(it, this) } }
|
override val declaration by lz { psi.initialization?.let { JavaConverter.convertStatement(it, this) } }
|
||||||
override val condition by lz { psi.condition?.let { JavaConverter.convert(it, this) } }
|
override val condition by lz { psi.condition?.let { JavaConverter.convertExpression(it, this) } }
|
||||||
override val update by lz { psi.update?.let { JavaConverter.convert(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 body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
||||||
|
|
||||||
|
override val forIdentifier: UIdentifier
|
||||||
|
get() = UIdentifier(psi.getChildByRole(ChildRole.FOR_KEYWORD), this)
|
||||||
}
|
}
|
||||||
+12
-4
@@ -16,18 +16,26 @@
|
|||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
import com.intellij.psi.PsiIfStatement
|
import com.intellij.psi.PsiIfStatement
|
||||||
|
import com.intellij.psi.impl.source.tree.ChildRole
|
||||||
import org.jetbrains.uast.UElement
|
import org.jetbrains.uast.UElement
|
||||||
|
import org.jetbrains.uast.UIdentifier
|
||||||
import org.jetbrains.uast.UIfExpression
|
import org.jetbrains.uast.UIfExpression
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
class JavaUIfExpression(
|
class JavaUIfExpression(
|
||||||
override val psi: PsiIfStatement,
|
override val psi: PsiIfStatement,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), UIfExpression, PsiElementBacked {
|
) : JavaAbstractUExpression(), UIfExpression, PsiElementBacked {
|
||||||
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
||||||
override val thenBranch by lz { JavaConverter.convertOrEmpty(psi.thenBranch, this) }
|
override val thenExpression by lz { JavaConverter.convertOrEmpty(psi.thenBranch, this) }
|
||||||
override val elseBranch by lz { JavaConverter.convertOrEmpty(psi.elseBranch, this) }
|
override val elseExpression by lz { JavaConverter.convertOrEmpty(psi.elseBranch, this) }
|
||||||
|
|
||||||
override val isTernary: Boolean
|
override val isTernary: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
|
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) }
|
||||||
}
|
}
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast.java
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import org.jetbrains.uast.*
|
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
|
||||||
|
|
||||||
open class JavaUSpecialExpressionList(
|
|
||||||
override val psi: PsiElement,
|
|
||||||
override val kind: UastSpecialExpressionKind, // original element
|
|
||||||
override val parent: UElement
|
|
||||||
) : JavaAbstractUElement(), USpecialExpressionList, PsiElementBacked {
|
|
||||||
class Empty(psi: PsiElement, expressionType: UastSpecialExpressionKind, parent: UElement) :
|
|
||||||
JavaUSpecialExpressionList(psi, expressionType, parent) {
|
|
||||||
init { expressions = emptyList() }
|
|
||||||
}
|
|
||||||
|
|
||||||
override lateinit var expressions: List<UExpression>
|
|
||||||
}
|
|
||||||
+12
-8
@@ -17,31 +17,35 @@ package org.jetbrains.uast.java
|
|||||||
|
|
||||||
import com.intellij.psi.PsiSwitchLabelStatement
|
import com.intellij.psi.PsiSwitchLabelStatement
|
||||||
import com.intellij.psi.PsiSwitchStatement
|
import com.intellij.psi.PsiSwitchStatement
|
||||||
|
import com.intellij.psi.impl.source.tree.ChildRole
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
class JavaUSwitchExpression(
|
class JavaUSwitchExpression(
|
||||||
override val psi: PsiSwitchStatement,
|
override val psi: PsiSwitchStatement,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), USwitchExpression, PsiElementBacked {
|
) : JavaAbstractUExpression(), USwitchExpression, PsiElementBacked {
|
||||||
override val expression by lz { JavaConverter.convertOrEmpty(psi.expression, this) }
|
override val expression by lz { JavaConverter.convertOrEmpty(psi.expression, this) }
|
||||||
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
||||||
|
|
||||||
|
override val switchIdentifier: UIdentifier
|
||||||
|
get() = UIdentifier(psi.getChildByRole(ChildRole.SWITCH_KEYWORD), this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class JavaUCaseSwitchClauseExpression(
|
class JavaUCaseSwitchClauseExpression(
|
||||||
override val psi: PsiSwitchLabelStatement,
|
override val psi: PsiSwitchLabelStatement,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), USwitchClauseExpression, PsiElementBacked {
|
) : JavaAbstractUExpression(), USwitchClauseExpression, PsiElementBacked {
|
||||||
override val caseValues by lz {
|
override val caseValues by lz {
|
||||||
val value = psi.caseValue ?: return@lz null
|
val value = psi.caseValue ?: return@lz null
|
||||||
listOf(JavaConverter.convert(value, this))
|
listOf(JavaConverter.convertExpression(value, this))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultUSwitchClauseExpression(override val parent: UElement) : USwitchClauseExpression {
|
class DefaultUSwitchClauseExpression(override val containingElement: UElement?) : USwitchClauseExpression {
|
||||||
override val caseValues: List<UExpression>?
|
override val caseValues: List<UExpression>?
|
||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
override fun logString() = "DefaultUSwitchClauseExpression"
|
override fun asLogString() = "DefaultUSwitchClauseExpression"
|
||||||
override fun renderString() = "else -> "
|
override fun asRenderString() = "else -> "
|
||||||
}
|
}
|
||||||
+12
-5
@@ -17,17 +17,24 @@ package org.jetbrains.uast.java
|
|||||||
|
|
||||||
import com.intellij.psi.PsiConditionalExpression
|
import com.intellij.psi.PsiConditionalExpression
|
||||||
import org.jetbrains.uast.UElement
|
import org.jetbrains.uast.UElement
|
||||||
|
import org.jetbrains.uast.UIdentifier
|
||||||
import org.jetbrains.uast.UIfExpression
|
import org.jetbrains.uast.UIfExpression
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
class JavaUTernaryIfExpression(
|
class JavaUTernaryIfExpression(
|
||||||
override val psi: PsiConditionalExpression,
|
override val psi: PsiConditionalExpression,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), UIfExpression, PsiElementBacked, JavaUElementWithType, JavaEvaluatableUElement {
|
) : JavaAbstractUExpression(), UIfExpression, PsiElementBacked {
|
||||||
override val condition by lz { JavaConverter.convert(psi.condition, this) }
|
override val condition by lz { JavaConverter.convertExpression(psi.condition, this) }
|
||||||
override val thenBranch by lz { JavaConverter.convertOrEmpty(psi.thenExpression, this) }
|
override val thenExpression by lz { JavaConverter.convertOrEmpty(psi.thenExpression, this) }
|
||||||
override val elseBranch by lz { JavaConverter.convertOrEmpty(psi.elseExpression, this) }
|
override val elseExpression by lz { JavaConverter.convertOrEmpty(psi.elseExpression, this) }
|
||||||
|
|
||||||
override val isTernary: Boolean
|
override val isTernary: Boolean
|
||||||
get() = true
|
get() = true
|
||||||
|
|
||||||
|
override val ifIdentifier: UIdentifier
|
||||||
|
get() = UIdentifier(null, this)
|
||||||
|
|
||||||
|
override val elseIdentifier: UIdentifier?
|
||||||
|
get() = UIdentifier(null, this)
|
||||||
}
|
}
|
||||||
+34
-14
@@ -15,30 +15,50 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
import com.intellij.psi.PsiCatchSection
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiTryStatement
|
import com.intellij.psi.impl.source.tree.ChildRole
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.UCatchClause
|
||||||
|
import org.jetbrains.uast.UElement
|
||||||
|
import org.jetbrains.uast.UIdentifier
|
||||||
|
import org.jetbrains.uast.UTryExpression
|
||||||
|
import org.jetbrains.uast.expressions.UTypeReferenceExpression
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
class JavaUTryExpression(
|
class JavaUTryExpression(
|
||||||
override val psi: PsiTryStatement,
|
override val psi: PsiTryStatement,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), UTryExpression, PsiElementBacked {
|
) : JavaAbstractUExpression(), UTryExpression, PsiElementBacked {
|
||||||
override val tryClause by lz { JavaConverter.convertOrEmpty(psi.tryBlock, this) }
|
override val tryClause by lz { JavaConverter.convertOrEmpty(psi.tryBlock, this) }
|
||||||
override val catchClauses by lz { psi.catchSections.map { JavaUCatchClause(it, this) } }
|
override val catchClauses by lz { psi.catchSections.map { JavaUCatchClause(it, this) } }
|
||||||
override val finallyClause by lz { psi.finallyBlock?.let { JavaConverter.convert(it, this) } }
|
override val finallyClause by lz { psi.finallyBlock?.let { JavaConverter.convertBlock(it, this) } }
|
||||||
override val resources by lz {
|
override val resources: List<PsiResourceListElement>?
|
||||||
val vars = psi.resourceList ?: return@lz null
|
get() = psi.resourceList?.toList() ?: emptyList<PsiResourceListElement>()
|
||||||
val resources = vars.map { JavaConverter.convert(it, this) ?: UDeclarationNotResolved }
|
override val isResources: Boolean
|
||||||
if (resources.isEmpty()) null else resources
|
get() = psi.resourceList != null
|
||||||
}
|
|
||||||
|
override val tryIdentifier: UIdentifier
|
||||||
|
get() = UIdentifier(psi.getChildByRole(ChildRole.TRY_KEYWORD), this)
|
||||||
|
|
||||||
|
override val finallyIdentifier: UIdentifier?
|
||||||
|
get() = psi.getChildByRole(ChildRole.FINALLY_KEYWORD)?.let { UIdentifier(it, this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
class JavaUCatchClause(
|
class JavaUCatchClause(
|
||||||
override val psi: PsiCatchSection,
|
override val psi: PsiCatchSection,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), UCatchClause, PsiElementBacked {
|
) : JavaAbstractUElement(), UCatchClause, PsiElementBacked {
|
||||||
override val body by lz { JavaConverter.convertOrEmpty(psi.catchBlock, this) }
|
override val body by lz { JavaConverter.convertOrEmpty(psi.catchBlock, this) }
|
||||||
override val parameters by lz { psi.parameter?.let { listOf(JavaConverter.convert(it, this)) } ?: emptyList() }
|
|
||||||
override val types by lz { psi.preciseCatchTypes.map { JavaConverter.convert(it, this) } }
|
override val parameters by lz {
|
||||||
|
(psi.parameter?.let { listOf(it) } ?: emptyList()).map { JavaUParameter(it, this) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override val typeReferences by lz {
|
||||||
|
val typeElement = psi.parameter?.typeElement ?: return@lz emptyList<UTypeReferenceExpression>()
|
||||||
|
if (typeElement.type is PsiDisjunctionType) {
|
||||||
|
typeElement.children.filterIsInstance<PsiTypeElement>().map { JavaUTypeReferenceExpression(it, this) }
|
||||||
|
} else {
|
||||||
|
listOf(JavaUTypeReferenceExpression(typeElement, this))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+7
-2
@@ -16,14 +16,19 @@
|
|||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
import com.intellij.psi.PsiWhileStatement
|
import com.intellij.psi.PsiWhileStatement
|
||||||
|
import com.intellij.psi.impl.source.tree.ChildRole
|
||||||
import org.jetbrains.uast.UElement
|
import org.jetbrains.uast.UElement
|
||||||
|
import org.jetbrains.uast.UIdentifier
|
||||||
import org.jetbrains.uast.UWhileExpression
|
import org.jetbrains.uast.UWhileExpression
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import org.jetbrains.uast.psi.PsiElementBacked
|
||||||
|
|
||||||
class JavaUWhileExpression(
|
class JavaUWhileExpression(
|
||||||
override val psi: PsiWhileStatement,
|
override val psi: PsiWhileStatement,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), UWhileExpression, PsiElementBacked {
|
) : JavaAbstractUExpression(), UWhileExpression, PsiElementBacked {
|
||||||
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
override val condition by lz { JavaConverter.convertOrEmpty(psi.condition, this) }
|
||||||
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
override val body by lz { JavaConverter.convertOrEmpty(psi.body, this) }
|
||||||
|
|
||||||
|
override val whileIdentifier: UIdentifier
|
||||||
|
get() = UIdentifier(psi.getChildByRole(ChildRole.WHILE_KEYWORD), this)
|
||||||
}
|
}
|
||||||
-63
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast.java
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiClassInitializer
|
|
||||||
import com.intellij.psi.PsiModifier
|
|
||||||
import org.jetbrains.uast.*
|
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
|
||||||
|
|
||||||
class JavaClassInitializerUFunction(
|
|
||||||
override val psi: PsiClassInitializer,
|
|
||||||
override val parent: UElement
|
|
||||||
) : JavaAbstractUElement(), UFunction, PsiElementBacked, NoAnnotations {
|
|
||||||
override val kind: UastFunctionKind.UastInitializerKind
|
|
||||||
get() {
|
|
||||||
return if (psi.hasModifierProperty(PsiModifier.STATIC))
|
|
||||||
JavaFunctionKinds.STATIC_INITIALIZER
|
|
||||||
else
|
|
||||||
JavaFunctionKinds.INSTANCE_INITIALIZER
|
|
||||||
}
|
|
||||||
|
|
||||||
override val valueParameters: List<UVariable>
|
|
||||||
get() = emptyList()
|
|
||||||
|
|
||||||
override val valueParameterCount: Int
|
|
||||||
get() = 0
|
|
||||||
|
|
||||||
override val typeParameters: List<UTypeReference>
|
|
||||||
get() = emptyList()
|
|
||||||
|
|
||||||
override val typeParameterCount: Int
|
|
||||||
get() = 0
|
|
||||||
|
|
||||||
override val returnType: UType?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
override val body by lz { JavaConverter.convert(psi.body, this) }
|
|
||||||
|
|
||||||
override val visibility: UastVisibility
|
|
||||||
get() = UastVisibility.LOCAL
|
|
||||||
|
|
||||||
override val nameElement: UElement?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
override val name: String
|
|
||||||
get() = "<static>"
|
|
||||||
|
|
||||||
override fun getSuperFunctions(context: UastContext) = emptyList<UFunction>()
|
|
||||||
override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier)
|
|
||||||
}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast.java
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiTypeParameter
|
|
||||||
import org.jetbrains.uast.UClass
|
|
||||||
import org.jetbrains.uast.UElement
|
|
||||||
import org.jetbrains.uast.UTypeReference
|
|
||||||
import org.jetbrains.uast.UastContext
|
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
|
||||||
|
|
||||||
class JavaParameterUTypeReference(
|
|
||||||
override val psi: PsiTypeParameter,
|
|
||||||
override val parent: UElement
|
|
||||||
) : JavaAbstractUElement(), UTypeReference, PsiElementBacked {
|
|
||||||
override val name: String
|
|
||||||
get() = psi.name.orAnonymous()
|
|
||||||
|
|
||||||
override val nameElement by lz { psi.nameIdentifier?.let { JavaDumbUElement(it, this) } }
|
|
||||||
|
|
||||||
override fun resolve(context: UastContext) = psi.reference?.resolve()?.let { JavaConverter.convertWithParent(it) } as? UClass
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast.java
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiAnnotation
|
|
||||||
import org.jetbrains.uast.UAnnotation
|
|
||||||
import org.jetbrains.uast.UClass
|
|
||||||
import org.jetbrains.uast.UElement
|
|
||||||
import org.jetbrains.uast.UastContext
|
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
|
||||||
|
|
||||||
class JavaUAnnotation(
|
|
||||||
override val psi: PsiAnnotation,
|
|
||||||
override val parent: UElement
|
|
||||||
) : JavaAbstractUElement(), UAnnotation, PsiElementBacked {
|
|
||||||
override val name: String
|
|
||||||
get() = psi.nameReferenceElement?.referenceName.orAnonymous()
|
|
||||||
|
|
||||||
override val fqName: String?
|
|
||||||
get() = psi.qualifiedName
|
|
||||||
|
|
||||||
override val valueArguments by lz {
|
|
||||||
psi.parameterList.attributes.map {
|
|
||||||
JavaConverter.convert(it, this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun resolve(context: UastContext) = context.convert(psi.reference?.resolve()) as? UClass
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,199 +13,54 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
import com.intellij.ide.util.JavaAnonymousClassesHelper
|
import com.intellij.psi.PsiAnonymousClass
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.PsiClass
|
||||||
import com.intellij.psi.util.ClassUtil
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
|
||||||
import com.intellij.psi.util.PsiTypesUtil
|
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
import org.jetbrains.uast.kinds.UastVariableInitialierKind
|
import org.jetbrains.uast.java.internal.JavaUElementWithComments
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
|
||||||
|
|
||||||
class JavaUClass(
|
abstract class AbstractJavaUClass : UClass, JavaUElementWithComments {
|
||||||
override val psi: PsiClass,
|
override val uastDeclarations by lz {
|
||||||
override val parent: UElement,
|
mutableListOf<UDeclaration>().apply {
|
||||||
val newExpression: PsiNewExpression? = null
|
addAll(uastFields)
|
||||||
) : JavaAbstractUElement(), UClass, PsiElementBacked {
|
addAll(uastInitializers)
|
||||||
override val name: String
|
addAll(uastMethods)
|
||||||
get() = psi.name.orAnonymous()
|
addAll(uastNestedClasses)
|
||||||
|
|
||||||
override val nameElement by lz {
|
|
||||||
if (psi is PsiAnonymousClass && newExpression != null) {
|
|
||||||
newExpression.classOrAnonymousClassReference?.referenceNameElement?.let { JavaDumbUElement(it, this) }
|
|
||||||
} else {
|
|
||||||
JavaConverter.convert(psi.nameIdentifier, this)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val fqName: String?
|
override val uastAnchor: UElement?
|
||||||
get() = psi.qualifiedName
|
get() = UIdentifier(psi.nameIdentifier, this)
|
||||||
|
|
||||||
override val kind by lz {
|
override val uastAnnotations by lz { psi.annotations.map { SimpleUAnnotation(it, this) } }
|
||||||
when {
|
|
||||||
psi.isEnum -> UastClassKind.ENUM
|
override val uastFields: List<UVariable> by lz { psi.fields.map { getLanguagePlugin().convert<UVariable>(it, this) } }
|
||||||
psi.isAnnotationType -> UastClassKind.ANNOTATION
|
override val uastInitializers: List<UClassInitializer> by lz { psi.initializers.map { getLanguagePlugin().convert<UClassInitializer>(it, this) } }
|
||||||
psi.isInterface -> UastClassKind.INTERFACE
|
override val uastMethods: List<UMethod> by lz { psi.methods.map { getLanguagePlugin().convert<UMethod>(it, this) } }
|
||||||
psi is PsiAnonymousClass -> UastClassKind.OBJECT
|
override val uastNestedClasses: List<UClass> by lz { psi.innerClasses.map { getLanguagePlugin().convert<UClass>(it, this) } }
|
||||||
else -> UastClassKind.CLASS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val defaultType by lz { JavaConverter.convert(PsiTypesUtil.getClassType(psi), this) }
|
override fun equals(other: Any?) = this === other
|
||||||
|
override fun hashCode() = psi.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
override val companions: List<UClass>
|
class JavaUClass private constructor(psi: PsiClass, override val containingElement: UElement?) : AbstractJavaUClass(), PsiClass by psi {
|
||||||
get() = emptyList()
|
override val psi = unwrap<UClass, PsiClass>(psi)
|
||||||
|
|
||||||
override val isAnonymous: Boolean
|
companion object {
|
||||||
get() = psi is PsiAnonymousClass
|
fun create(psi: PsiClass, containingElement: UElement?): UClass {
|
||||||
|
return if (psi is PsiAnonymousClass)
|
||||||
override val internalName by lz { getInternalName(psi) }
|
JavaUAnonymousClass(psi, containingElement)
|
||||||
|
else
|
||||||
override val superTypes by lz {
|
JavaUClass(psi, containingElement)
|
||||||
psi.extendsListTypes.map { JavaConverter.convert(it, this) } + psi.implementsListTypes.map { JavaConverter.convert(it, this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSuperClass(context: UastContext) = context.convert(psi.superClass) as? UClass
|
|
||||||
|
|
||||||
override val visibility: UastVisibility
|
|
||||||
get() = psi.getVisibility()
|
|
||||||
|
|
||||||
override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier)
|
|
||||||
override val annotations by lz { psi.modifierList.getAnnotations(this) }
|
|
||||||
|
|
||||||
override val declarations by lz {
|
|
||||||
val declarations = arrayListOf<UDeclaration>()
|
|
||||||
psi.fields.mapTo(declarations) { JavaConverter.convert(it, this) }
|
|
||||||
|
|
||||||
if (psi is PsiAnonymousClass && newExpression != null) {
|
|
||||||
declarations += JavaUAnonymousClassConstructor(psi, newExpression, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
psi.methods.mapTo(declarations) { JavaConverter.convert(it, this) }
|
|
||||||
psi.innerClasses.mapTo(declarations) { JavaConverter.convert(it, this) }
|
|
||||||
psi.initializers.mapTo(declarations) { JavaConverter.convert(it, this) }
|
|
||||||
declarations
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isSubclassOf(fqName: String): Boolean {
|
|
||||||
return psi.supers.any { base -> psi.isInheritor(base, false) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
/* Primarily copied from IntellijLintUtils and ClassContext classes from the Android IDEA plugin */
|
|
||||||
private fun getInternalName(psiClass: PsiClass): String? {
|
|
||||||
if (psiClass is PsiAnonymousClass) {
|
|
||||||
val parent = PsiTreeUtil.getParentOfType(psiClass, PsiClass::class.java)
|
|
||||||
if (parent != null) {
|
|
||||||
val internalName = getInternalName(parent) ?: return null
|
|
||||||
return internalName + JavaAnonymousClassesHelper.getName(psiClass)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var sig = ClassUtil.getJVMClassName(psiClass)
|
|
||||||
if (sig == null) {
|
|
||||||
val qualifiedName = psiClass.qualifiedName
|
|
||||||
if (qualifiedName != null) {
|
|
||||||
return getInternalName(qualifiedName)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
else if (sig.indexOf('.') != -1) {
|
|
||||||
// Workaround -- ClassUtil doesn't treat this correctly!
|
|
||||||
// .replace('.', '/');
|
|
||||||
sig = getInternalName(sig)
|
|
||||||
}
|
|
||||||
return sig
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getInternalName(fqcn: String): String {
|
|
||||||
if (fqcn.indexOf('.') == -1) {
|
|
||||||
return fqcn
|
|
||||||
}
|
|
||||||
|
|
||||||
// If class name contains $, it's not an ambiguous inner class name.
|
|
||||||
if (fqcn.indexOf('$') != -1) {
|
|
||||||
return fqcn.replace('.', '/')
|
|
||||||
}
|
|
||||||
// Let's assume that components that start with Caps are class names.
|
|
||||||
val sb = StringBuilder(fqcn.length)
|
|
||||||
var prev: String? = null
|
|
||||||
for (part in fqcn.split('.')) {
|
|
||||||
if (prev != null && !prev.isEmpty()) {
|
|
||||||
if (Character.isUpperCase(prev[0])) {
|
|
||||||
sb.append('$')
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sb.append('/')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb.append(part)
|
|
||||||
prev = part
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JavaUAnonymousClassConstructor(
|
class JavaUAnonymousClass(
|
||||||
override val psi: PsiAnonymousClass,
|
psi: PsiAnonymousClass,
|
||||||
newExpression: PsiNewExpression,
|
override val containingElement: UElement?
|
||||||
override val parent: UElement
|
) : AbstractJavaUClass(), UAnonymousClass, PsiAnonymousClass by psi {
|
||||||
) : JavaAbstractUElement(), UFunction, PsiElementBacked, NoAnnotations, NoModifiers {
|
override val psi: PsiAnonymousClass = unwrap<UAnonymousClass, PsiAnonymousClass>(psi)
|
||||||
override val kind = UastFunctionKind.CONSTRUCTOR
|
|
||||||
|
|
||||||
override val valueParameterCount by lz { newExpression.argumentList?.expressions?.size ?: 0 }
|
|
||||||
|
|
||||||
override val valueParameters by lz {
|
|
||||||
val args = newExpression.argumentList ?: return@lz emptyList<UVariable>()
|
|
||||||
args.expressions.mapIndexed { i, psiExpression -> JavaUAnonymousClassConstructorParameter(args, i, this) }
|
|
||||||
}
|
|
||||||
override val typeParameters by lz { psi.typeParameters.map { JavaConverter.convert(it, this) } }
|
|
||||||
|
|
||||||
override val typeParameterCount: Int
|
|
||||||
get() = psi.typeParameters.size
|
|
||||||
|
|
||||||
override val returnType: UType?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
override val body: UExpression?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
override val visibility: UastVisibility
|
|
||||||
get() = UastVisibility.LOCAL
|
|
||||||
|
|
||||||
override fun getSuperFunctions(context: UastContext) = emptyList<UFunction>()
|
|
||||||
|
|
||||||
override val nameElement: UElement?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
override val name: String
|
|
||||||
get() = "<init>"
|
|
||||||
}
|
|
||||||
|
|
||||||
private class JavaUAnonymousClassConstructorParameter(
|
|
||||||
val psi: PsiExpressionList,
|
|
||||||
val index: Int,
|
|
||||||
override val parent: UElement
|
|
||||||
) : JavaAbstractUElement(), UVariable, NoAnnotations, NoModifiers {
|
|
||||||
override val initializer by lz { JavaConverter.convert(psi.expressions[index], this) }
|
|
||||||
|
|
||||||
override val initializerKind: UastVariableInitialierKind
|
|
||||||
get() = UastVariableInitialierKind.EXPRESSION
|
|
||||||
|
|
||||||
override val kind: UastVariableKind
|
|
||||||
get() = UastVariableKind.VALUE_PARAMETER
|
|
||||||
|
|
||||||
override val type by lz { JavaConverter.convert(psi.expressionTypes[index], this) }
|
|
||||||
|
|
||||||
override val nameElement: UElement?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
override val name: String
|
|
||||||
get() = "p$index"
|
|
||||||
|
|
||||||
override val visibility: UastVisibility
|
|
||||||
get() = UastVisibility.LOCAL
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiClassInitializer
|
||||||
|
import org.jetbrains.uast.*
|
||||||
|
import org.jetbrains.uast.java.internal.JavaUElementWithComments
|
||||||
|
|
||||||
|
class JavaUClassInitializer(
|
||||||
|
psi: PsiClassInitializer,
|
||||||
|
override val containingElement: UElement?
|
||||||
|
) : UClassInitializer, JavaUElementWithComments, PsiClassInitializer by psi {
|
||||||
|
override val psi = unwrap<UClassInitializer, PsiClassInitializer>(psi)
|
||||||
|
|
||||||
|
override val uastAnchor: UElement?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
override val uastBody by lz {
|
||||||
|
getLanguagePlugin().convertElement(psi.body, this, null) as? UExpression ?: UastEmptyExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
override val uastAnnotations by lz { psi.annotations.map { SimpleUAnnotation(it, this) } }
|
||||||
|
|
||||||
|
override fun equals(other: Any?) = this === other
|
||||||
|
override fun hashCode() = psi.hashCode()
|
||||||
|
}
|
||||||
@@ -1,32 +1,32 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiComment
|
||||||
import com.intellij.psi.PsiJavaFile
|
import com.intellij.psi.PsiJavaFile
|
||||||
|
import com.intellij.psi.PsiRecursiveElementWalkingVisitor
|
||||||
|
import org.jetbrains.uast.UComment
|
||||||
import org.jetbrains.uast.UFile
|
import org.jetbrains.uast.UFile
|
||||||
import org.jetbrains.uast.UImportStatement
|
import org.jetbrains.uast.UastLanguagePlugin
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
import java.util.*
|
||||||
|
|
||||||
class JavaUFile(override val psi: PsiJavaFile): JavaAbstractUElement(), UFile, PsiElementBacked {
|
class JavaUFile(override val psi: PsiJavaFile, override val languagePlugin: UastLanguagePlugin) : UFile {
|
||||||
override val packageFqName by lz { psi.packageName }
|
override val packageName: String
|
||||||
|
get() = psi.packageName
|
||||||
override val importStatements: List<UImportStatement> by lz {
|
|
||||||
val importList = psi.importList ?: return@lz emptyList<UImportStatement>()
|
override val imports by lz {
|
||||||
importList.importStatements.map { JavaConverter.convert(it, this) }.filterNotNull()
|
psi.importList?.allImportStatements?.map { JavaUImportStatement(it, this) } ?: listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val declarations by lz { psi.classes.map { JavaUClass(it, this) } }
|
override val classes by lz { psi.classes.map { JavaUClass.create(it, this) } }
|
||||||
|
|
||||||
|
override val allCommentsInFile by lz {
|
||||||
|
val comments = ArrayList<UComment>(0)
|
||||||
|
psi.accept(object : PsiRecursiveElementWalkingVisitor() {
|
||||||
|
override fun visitComment(comment: PsiComment) {
|
||||||
|
comments += UComment(comment, this@JavaUFile)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
comments
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?) = (other as? JavaUFile)?.psi == psi
|
||||||
}
|
}
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast.java
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiArrayType
|
|
||||||
import com.intellij.psi.PsiClassType
|
|
||||||
import com.intellij.psi.PsiMethod
|
|
||||||
import com.intellij.psi.PsiType
|
|
||||||
import org.jetbrains.uast.*
|
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
|
||||||
|
|
||||||
class JavaUFunction(
|
|
||||||
override val psi: PsiMethod,
|
|
||||||
override val parent: UElement
|
|
||||||
) : JavaAbstractUElement(), UFunction, PsiElementBacked {
|
|
||||||
override val kind: UastFunctionKind
|
|
||||||
get() = if (psi.isConstructor) UastFunctionKind.CONSTRUCTOR else UastFunctionKind.FUNCTION
|
|
||||||
|
|
||||||
override val name: String
|
|
||||||
get() = if (psi.isConstructor) "<init>" else psi.name
|
|
||||||
|
|
||||||
override val nameElement by lz { JavaDumbUElement(psi.nameIdentifier, this) }
|
|
||||||
|
|
||||||
override val valueParameters by lz { psi.parameterList.parameters.map { JavaConverter.convert(it, this) } }
|
|
||||||
|
|
||||||
override val valueParameterCount: Int
|
|
||||||
get() = psi.parameterList.parametersCount
|
|
||||||
|
|
||||||
override val typeParameters by lz { psi.typeParameters.map { JavaConverter.convert(it, this) } }
|
|
||||||
|
|
||||||
override val typeParameterCount: Int
|
|
||||||
get() = psi.typeParameters.size
|
|
||||||
|
|
||||||
override val returnType by lz { psi.returnType?.let { JavaConverter.convert(it, this) } }
|
|
||||||
|
|
||||||
override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier)
|
|
||||||
|
|
||||||
val thrownExceptions: List<UType> by lz {
|
|
||||||
psi.throwsList.referencedTypes.map { JavaConverter.convert(it, this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override val annotations by lz { psi.modifierList.getAnnotations(this) }
|
|
||||||
|
|
||||||
override val visibility: UastVisibility
|
|
||||||
get() = psi.getVisibility()
|
|
||||||
|
|
||||||
override val body by lz { psi.body?.let { JavaConverter.convert(it, this) } }
|
|
||||||
|
|
||||||
override val bytecodeDescriptor by lz { getDescriptor(psi) }
|
|
||||||
|
|
||||||
override fun getSuperFunctions(context: UastContext): List<UFunction> {
|
|
||||||
return psi.findSuperMethods().map { context.convert(it) as? UFunction }.filterNotNull()
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
fun getDescriptor(psi: PsiMethod): String? {
|
|
||||||
val parameterTypes = psi.parameterList.parameters.map {
|
|
||||||
renderType(it.type) ?: return null
|
|
||||||
}
|
|
||||||
val returnType = renderType(psi.returnType) ?: return null
|
|
||||||
return parameterTypes.joinToString("", "(", ")") + returnType
|
|
||||||
}
|
|
||||||
|
|
||||||
fun renderType(type: PsiType?): String? = when (type) {
|
|
||||||
null -> null
|
|
||||||
PsiType.CHAR -> "C"
|
|
||||||
PsiType.DOUBLE -> "D"
|
|
||||||
PsiType.FLOAT -> "F"
|
|
||||||
PsiType.INT -> "I"
|
|
||||||
PsiType.LONG -> "J"
|
|
||||||
PsiType.SHORT -> "S"
|
|
||||||
PsiType.BOOLEAN -> "Z"
|
|
||||||
PsiType.VOID -> "V"
|
|
||||||
is PsiArrayType -> renderType(type.componentType)?.let { "[$it" }
|
|
||||||
is PsiClassType -> type.resolve()?.qualifiedName?.replace('.', '/')?.let { "L$it;" }
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +1,15 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast.java
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
import com.intellij.psi.PsiImportStatement
|
import com.intellij.psi.PsiImportStatementBase
|
||||||
import org.jetbrains.uast.UDeclaration
|
|
||||||
import org.jetbrains.uast.UElement
|
import org.jetbrains.uast.UElement
|
||||||
import org.jetbrains.uast.UImportStatement
|
import org.jetbrains.uast.UImportStatement
|
||||||
import org.jetbrains.uast.UastContext
|
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
|
||||||
|
|
||||||
class JavaUImportStatement(
|
class JavaUImportStatement(
|
||||||
override val psi: PsiImportStatement,
|
override val psi: PsiImportStatementBase,
|
||||||
override val parent: UElement
|
override val containingElement: UElement?
|
||||||
) : JavaAbstractUElement(), UImportStatement, PsiElementBacked {
|
) : UImportStatement {
|
||||||
override val fqNameToImport: String?
|
override val isOnDemand: Boolean
|
||||||
get() = psi.qualifiedName
|
|
||||||
|
|
||||||
override val isStarImport: Boolean
|
|
||||||
get() = psi.isOnDemand
|
get() = psi.isOnDemand
|
||||||
|
override val importReference by lz { psi.importReference?.let { JavaDumbUElement(it, this) } }
|
||||||
override fun resolve(context: UastContext): UDeclaration? {
|
override fun resolve() = psi.resolve()
|
||||||
if (psi.isOnDemand) return null
|
|
||||||
val resolvedElement = psi.resolve() ?: return null
|
|
||||||
return context.convert(resolvedElement) as? UDeclaration
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.uast.java
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiAnnotationMethod
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
|
import com.intellij.psi.PsiNameIdentifierOwner
|
||||||
|
import org.jetbrains.uast.*
|
||||||
|
import org.jetbrains.uast.java.internal.JavaUElementWithComments
|
||||||
|
|
||||||
|
open class JavaUMethod(
|
||||||
|
psi: PsiMethod,
|
||||||
|
override val containingElement: UElement?
|
||||||
|
) : UMethod, JavaUElementWithComments, PsiMethod by psi {
|
||||||
|
override val psi = unwrap<UMethod, PsiMethod>(psi)
|
||||||
|
|
||||||
|
override val uastBody by lz {
|
||||||
|
val body = psi.body ?: return@lz null
|
||||||
|
getLanguagePlugin().convertElement(body, this) as? UExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
override val uastAnnotations by lz { psi.annotations.map { SimpleUAnnotation(it, this) } }
|
||||||
|
|
||||||
|
override val uastParameters by lz {
|
||||||
|
psi.parameterList.parameters.map { JavaUParameter(it, this) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override val uastAnchor: UElement
|
||||||
|
get() = UIdentifier((psi.originalElement as? PsiNameIdentifierOwner)?.nameIdentifier ?: psi.nameIdentifier, this)
|
||||||
|
|
||||||
|
override fun equals(other: Any?) = this === other
|
||||||
|
override fun hashCode() = psi.hashCode()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun create(psi: PsiMethod, languagePlugin: UastLanguagePlugin, containingElement: UElement?) = when (psi) {
|
||||||
|
is PsiAnnotationMethod -> JavaUAnnotationMethod(psi, languagePlugin, containingElement)
|
||||||
|
else -> JavaUMethod(psi, containingElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JavaUAnnotationMethod(
|
||||||
|
override val psi: PsiAnnotationMethod,
|
||||||
|
languagePlugin: UastLanguagePlugin,
|
||||||
|
containingElement: UElement?
|
||||||
|
) : JavaUMethod(psi, containingElement), UAnnotationMethod {
|
||||||
|
override val uastDefaultValue by lz {
|
||||||
|
val defaultValue = psi.defaultValue ?: return@lz null
|
||||||
|
languagePlugin.convertElement(defaultValue, this, null) as? UExpression
|
||||||
|
}
|
||||||
|
}
|
||||||
-40
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.uast.java
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiImportStaticStatement
|
|
||||||
import org.jetbrains.uast.UDeclaration
|
|
||||||
import org.jetbrains.uast.UElement
|
|
||||||
import org.jetbrains.uast.UImportStatement
|
|
||||||
import org.jetbrains.uast.UastContext
|
|
||||||
import org.jetbrains.uast.psi.PsiElementBacked
|
|
||||||
|
|
||||||
class JavaUStaticImportStatement(
|
|
||||||
override val psi: PsiImportStaticStatement,
|
|
||||||
override val parent: UElement
|
|
||||||
) : JavaAbstractUElement(), UImportStatement, PsiElementBacked {
|
|
||||||
override val fqNameToImport: String?
|
|
||||||
get() = psi.referenceName
|
|
||||||
|
|
||||||
override val isStarImport: Boolean
|
|
||||||
get() = psi.isOnDemand
|
|
||||||
|
|
||||||
override fun resolve(context: UastContext): UDeclaration? {
|
|
||||||
if (psi.isOnDemand) return null
|
|
||||||
val resolvedElement = psi.resolve() ?: return null
|
|
||||||
return context.convert(resolvedElement) as? UDeclaration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user