Uast: Allow to search for a static members (in Kotlin static members are located inside the companion objects).

Companion objects support.
This commit is contained in:
Yan Zhulanow
2016-03-10 19:42:17 +03:00
parent f1e5c85ba3
commit ed10829091
15 changed files with 160 additions and 61 deletions
@@ -16,6 +16,8 @@
@file:JvmName("UastUtils")
package org.jetbrains.uast
import org.jetbrains.uast.kinds.UastClassKind
tailrec fun UElement?.getContainingClass(): UClass? {
val parent = this?.parent ?: return null
if (parent is UClass) return parent
@@ -126,4 +128,21 @@ fun <T: UElement> UElement.getParentOfType(clazz: Class<T>): T? {
@Suppress("UNCHECKED_CAST")
return findParent(this) as T
}
fun <T> UClass.findStaticMemberOfType(name: String, type: Class<out T>): T? {
for (companion in companions) {
val classKind = companion.kind as? UastClassKind.UastCompanionObject ?: continue
if (!classKind.default) continue
val member = companion.declarations.firstOrNull { it.name == name && type.isInstance(it) }
@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
}
@@ -15,13 +15,14 @@
*/
package org.jetbrains.uast
import org.jetbrains.uast.kinds.UastClassKind
interface UClass : UDeclaration, UFqNamed, UModifierOwner, UAnnotated {
val isEnum: Boolean
val isInterface: Boolean
val isObject: Boolean
val isAnonymous: Boolean
val isAnnotation: Boolean
val visibility: UastVisibility
val kind: UastClassKind
val companions: List<UClass>
val internalName: String?
@@ -52,14 +53,7 @@ interface UClass : UDeclaration, UFqNamed, UModifierOwner, UAnnotated {
}
override fun renderString(): String {
val keyword = when {
isEnum -> "enum"
isInterface -> "interface"
isObject -> "object"
else -> "class"
}
val modifiers = listOf(UastModifier.ABSTRACT, UastModifier.FINAL, UastModifier.INNER)
val modifiers = listOf(UastModifier.ABSTRACT, UastModifier.FINAL, UastModifier.STATIC)
.filter { hasModifier(it) }.joinToString(" ") { it.name }.let { if (it.isBlank()) it else "$it " }
val name = if (isAnonymous) "" else " $name"
@@ -70,22 +64,20 @@ interface UClass : UDeclaration, UFqNamed, UModifierOwner, UAnnotated {
append("\n}")
}
return "${visibility.name} " + modifiers + keyword + name + " " + declarations
return "${visibility.name} " + modifiers + kind.text + name + " " + declarations
}
override fun logString() = "UClass ($name, enum = $isEnum, interface = $isInterface, object = $isObject)\n" + declarations.logString()
override fun logString() = "UClass ($name, kind = ${kind.text})\n" + declarations.logString()
}
object UClassNotResolved : UClass {
override val isEnum = false
override val isInterface = false
override val isObject = false
override val isAnonymous = true
override val isAnnotation = false
override val kind = UastClassKind.CLASS
override val visibility = UastVisibility.PRIVATE
override val superTypes = emptyList<UType>()
override val declarations = emptyList<UDeclaration>()
override fun isSubclassOf(name: String) = false
override val companions = emptyList<UClass>()
override val nameElement = null
override val parent = null
@@ -0,0 +1,38 @@
/*
* 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 UastClassKind(val text: String) {
class UastCompanionObject(val default: Boolean) : UastClassKind("companion object")
companion object {
@JvmField
val CLASS = UastClassKind("class")
@JvmField
val INTERFACE = UastClassKind("interface")
@JvmField
val ANNOTATION = UastClassKind("annotation")
@JvmField
val ENUM = UastClassKind("enum")
@JvmField
val OBJECT = UastClassKind("object")
}
}
@@ -20,7 +20,7 @@ class UastModifier(val name: String) {
@JvmField
val ABSTRACT = UastModifier("abstract")
@JvmField
val INNER = UastModifier("inner")
val STATIC = UastModifier("static")
@JvmField
val FINAL = UastModifier("final")
}