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,215 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.uast.expressions.KotlinUBreakExpression
|
||||
import org.jetbrains.kotlin.uast.expressions.KotlinUContinueExpression
|
||||
import org.jetbrains.kotlin.uast.kinds.KotlinSpecialExpressionKinds
|
||||
import org.jetbrains.kotlin.uast.extensions.PropertyAsCallAndroidUastVisitorExtension
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
object KotlinUastLanguagePlugin : UastLanguagePlugin {
|
||||
override val converter: UastConverter = KotlinConverter
|
||||
override val visitorExtensions = listOf(PropertyAsCallAndroidUastVisitorExtension())
|
||||
}
|
||||
|
||||
internal object KotlinConverter : UastConverter {
|
||||
override fun isFileSupported(name: String) = name.endsWith(".kt", false) || name.endsWith(".kts", false)
|
||||
|
||||
override fun convert(element: Any?, parent: UElement): UElement? {
|
||||
if (element !is KtElement) return null
|
||||
return convertKtElement(element, parent)
|
||||
}
|
||||
|
||||
override fun convertWithParent(element: Any?): UElement? {
|
||||
if (element !is KtElement) return null
|
||||
if (element is KtFile) return KotlinUFile(element)
|
||||
|
||||
val parent = element.parent ?: return null
|
||||
val parentUElement = convertWithParent(parent) ?: return null
|
||||
return convertKtElement(element, parentUElement)
|
||||
}
|
||||
|
||||
private fun convertKtElement(element: KtElement?, parent: UElement): UElement? = when (element) {
|
||||
is KtFile -> KotlinUFile(element)
|
||||
is KtAnnotationEntry -> KotlinUAnnotation(element, parent)
|
||||
is KtAnnotation -> KotlinUAnnotationList(element, parent).apply {
|
||||
annotations = element.entries.map { KotlinUAnnotation(it, this) }
|
||||
}
|
||||
is KtDeclaration -> convert(element, parent)
|
||||
is KtParameterList -> KotlinUDeclarationsExpression(parent).apply {
|
||||
declarations = element.parameters.map { convert(it, this) }
|
||||
}
|
||||
is KtClassBody -> KotlinUSpecialExpressionList(element, KotlinSpecialExpressionKinds.CLASS_BODY, parent).apply {
|
||||
expressions = emptyList()
|
||||
}
|
||||
is KtImportDirective -> KotlinUImportStatement(element, parent)
|
||||
is KtCatchClause -> KotlinUCatchClause(element, parent)
|
||||
is KtExpression -> KotlinConverter.convert(element, parent)
|
||||
else -> {
|
||||
if (element is LeafPsiElement && element.elementType == KtTokens.IDENTIFIER) {
|
||||
asSimpleReference(element, parent)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convert(element: KtDeclaration, parent: UElement): UDeclaration? = when (element) {
|
||||
is KtClassOrObject -> convert(element, parent)
|
||||
is KtAnonymousInitializer -> KotlinAnonymousInitializerUFunction(element, parent)
|
||||
is KtConstructor<*> -> KotlinConstructorUFunction(element, parent)
|
||||
is KtFunction -> KotlinUFunction(element, parent)
|
||||
is KtVariableDeclaration -> KotlinUVariable(element, parent)
|
||||
is KtParameter -> convert(element, parent)
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun convertStringTemplateExpression(
|
||||
expression: KtStringTemplateExpression,
|
||||
parent: UElement,
|
||||
i: Int
|
||||
): UExpression {
|
||||
return if (i == 1) KotlinStringTemplateUBinaryExpression(expression, parent).apply {
|
||||
leftOperand = convert(expression.entries[0], this)
|
||||
rightOperand = convert(expression.entries[1], this)
|
||||
} else KotlinStringTemplateUBinaryExpression(expression, parent).apply {
|
||||
leftOperand = convertStringTemplateExpression(expression, parent, i - 1)
|
||||
rightOperand = convert(expression.entries[i], this)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convert(entry: KtStringTemplateEntry, parent: UElement): UExpression = when (entry) {
|
||||
is KtStringTemplateEntryWithExpression -> convertOrEmpty(entry.expression, parent)
|
||||
is KtEscapeStringTemplateEntry -> KotlinStringULiteralExpression(entry, parent, entry.unescapedValue)
|
||||
else -> {
|
||||
KotlinStringULiteralExpression(entry, parent)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convert(expression: KtExpression, parent: UElement): UExpression = when (expression) {
|
||||
is KtFunction -> convertDeclaration(expression, parent)
|
||||
is KtVariableDeclaration -> convertDeclaration(expression, parent)
|
||||
is KtClass -> convertDeclaration(expression, parent)
|
||||
|
||||
is KtStringTemplateExpression -> {
|
||||
if (expression.entries.isEmpty())
|
||||
KotlinStringULiteralExpression(expression, parent, "")
|
||||
else if (expression.entries.size == 1)
|
||||
convert(expression.entries[0], parent)
|
||||
else
|
||||
convertStringTemplateExpression(expression, parent, expression.entries.size - 1)
|
||||
}
|
||||
is KtDestructuringDeclaration -> KotlinUDeclarationsExpression(parent).apply {
|
||||
val tempAssignment = KotlinDestructuringUVariable(expression, this)
|
||||
val destructuringAssignments = expression.entries.mapIndexed { i, entry ->
|
||||
KotlinDestructuredUVariable(entry, this).apply {
|
||||
initializer = KotlinUComponentQualifiedExpression(entry, this).apply {
|
||||
receiver = KotlinStringUSimpleReferenceExpression(tempAssignment.name, this)
|
||||
selector = KotlinUComponentFunctionCallExpression(entry, i + 1, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
declarations = listOf(tempAssignment) + destructuringAssignments
|
||||
}
|
||||
is KtLabeledExpression -> KotlinULabeledExpression(expression, parent)
|
||||
is KtClassLiteralExpression -> KotlinUClassLiteralExpression(expression, parent)
|
||||
is KtObjectLiteralExpression -> KotlinUObjectLiteralExpression(expression, parent)
|
||||
is KtStringTemplateEntry -> convertOrEmpty(expression.expression, parent)
|
||||
is KtDotQualifiedExpression -> KotlinUQualifiedExpression(expression, parent)
|
||||
is KtSafeQualifiedExpression -> KotlinUSafeQualifiedExpression(expression, parent)
|
||||
is KtSimpleNameExpression -> KotlinUSimpleReferenceExpression(expression, expression.getReferencedName(), parent)
|
||||
is KtCallExpression -> KotlinUFunctionCallExpression(expression, parent)
|
||||
is KtBinaryExpression -> KotlinUBinaryExpression(expression, parent)
|
||||
is KtParenthesizedExpression -> KotlinUParenthesizedExpression(expression, parent)
|
||||
is KtPrefixExpression -> KotlinUPrefixExpression(expression, parent)
|
||||
is KtPostfixExpression -> KotlinUPostfixExpression(expression, parent)
|
||||
is KtThisExpression -> KotlinUThisExpression(expression, parent)
|
||||
is KtSuperExpression -> KotlinUSuperExpression(expression, parent)
|
||||
is KtCallableReferenceExpression -> KotlinUCallableReferenceExpression(expression, parent)
|
||||
is KtIsExpression -> KotlinUTypeCheckExpression(expression, parent)
|
||||
is KtIfExpression -> KotlinUIfExpression(expression, parent)
|
||||
is KtWhileExpression -> KotlinUWhileExpression(expression, parent)
|
||||
is KtDoWhileExpression -> KotlinUDoWhileExpression(expression, parent)
|
||||
is KtForExpression -> KotlinUForEachExpression(expression, parent)
|
||||
is KtWhenExpression -> KotlinUSwitchExpression(expression, parent)
|
||||
is KtBreakExpression -> KotlinUBreakExpression(expression, parent)
|
||||
is KtContinueExpression -> KotlinUContinueExpression(expression, parent)
|
||||
is KtReturnExpression -> KotlinUReturnExpression(expression, parent)
|
||||
is KtThrowExpression -> KotlinUThrowExpression(expression, parent)
|
||||
is KtBlockExpression -> KotlinUBlockExpression(expression, parent)
|
||||
is KtConstantExpression -> KotlinULiteralExpression(expression, parent)
|
||||
is KtTryExpression -> KotlinUTryExpression(expression, parent)
|
||||
is KtArrayAccessExpression -> KotlinUArrayAccessExpression(expression, parent)
|
||||
is KtLambdaExpression -> KotlinULambdaExpression(expression, parent)
|
||||
is KtBinaryExpressionWithTypeRHS -> KotlinUBinaryExpressionWithType(expression, parent)
|
||||
|
||||
else -> UnknownKotlinExpression(expression, parent)
|
||||
}
|
||||
|
||||
internal fun convert(element: KtParameter, parent: UElement) : UVariable {
|
||||
return KotlinParameterUVariable(element, parent)
|
||||
}
|
||||
|
||||
internal fun convert(element: KtClassOrObject, parent: UElement) : UClass {
|
||||
return KotlinUClass(element, parent)
|
||||
}
|
||||
|
||||
internal fun convert(element: KotlinType, project: Project, parent: UElement?): UType {
|
||||
return KotlinUType(element, project, parent)
|
||||
}
|
||||
|
||||
internal fun convert(typeReference: KtTypeReference?, parent: UElement): UType {
|
||||
if (typeReference == null) return UastErrorType
|
||||
val bindingContext = typeReference.analyze(BodyResolveMode.PARTIAL)
|
||||
val type = bindingContext[BindingContext.TYPE, typeReference] ?: return UastErrorType
|
||||
return KotlinUType(type, typeReference.project, parent, typeReference.typeElement)
|
||||
}
|
||||
|
||||
internal fun convertTypeReference(typeReference: KtTypeReference, parent: UElement): UTypeReference {
|
||||
return KotlinUTypeReference(typeReference, parent)
|
||||
}
|
||||
|
||||
internal fun asSimpleReference(element: PsiElement?, parent: UElement): USimpleReferenceExpression? {
|
||||
if (element == null) return null
|
||||
return KotlinNameUSimpleReferenceExpression(element, KtPsiUtil.unquoteIdentifier(element.text), parent)
|
||||
}
|
||||
|
||||
internal fun convertOrEmpty(expression: KtExpression?, parent: UElement): UExpression {
|
||||
return if (expression != null) convert(expression, parent) else EmptyUExpression(parent)
|
||||
}
|
||||
|
||||
internal fun convertOrNull(expression: KtExpression?, parent: UElement): UExpression? {
|
||||
return if (expression != null) convert(expression, parent) else null
|
||||
}
|
||||
|
||||
private fun convertDeclaration(declaration: KtDeclaration, parent: UElement): UExpression {
|
||||
val udeclarations = mutableListOf<UElement>()
|
||||
return SimpleUDeclarationsExpression(parent, udeclarations).apply {
|
||||
convert(declaration, this)?.let { udeclarations += it }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.kotlin.uast
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinDumbUElement(
|
||||
override val psi: PsiElement?,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UElement, PsiElementBacked {
|
||||
override fun logString() = "KotlinDumbUElement"
|
||||
override fun renderString() = "<stub@$psi>"
|
||||
}
|
||||
-42
@@ -1,42 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinParameterUTypeReference(
|
||||
override val psi: KtTypeParameter,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UTypeReference, PsiElementBacked {
|
||||
override fun resolve(context: UastContext): UClass? {
|
||||
val descriptor = psi.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE_PARAMETER, psi]
|
||||
?.typeConstructor?.declarationDescriptor as? ClassDescriptor ?: return null
|
||||
return context.convert(descriptor.toSource()) as? UClass
|
||||
}
|
||||
|
||||
override val nameElement: UElement?
|
||||
get() = KotlinDumbUElement(psi, this)
|
||||
|
||||
override val name: String
|
||||
get() = psi.name.orAnonymous()
|
||||
}
|
||||
@@ -1,61 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.psi.KtUserType
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUAnnotation(
|
||||
override val psi: KtAnnotationEntry,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UAnnotation, PsiElementBacked {
|
||||
override val fqName: String?
|
||||
get() = resolveToDescriptor()?.fqNameSafe?.asString()
|
||||
|
||||
override val name: String
|
||||
get() = (psi.typeReference?.typeElement as? KtUserType)?.referencedName.orAnonymous()
|
||||
|
||||
override val valueArguments by lz {
|
||||
psi.valueArguments.map {
|
||||
val name = it.getArgumentName()?.asName?.identifier.orAnonymous()
|
||||
UNamedExpression(name, this).apply {
|
||||
expression = KotlinConverter.convertOrEmpty(it.getArgumentExpression(), this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveToDescriptor(): ClassDescriptor? {
|
||||
val bindingContext = psi.analyze(BodyResolveMode.PARTIAL)
|
||||
val resolvedCall = psi.calleeExpression?.getResolvedCall(bindingContext) ?: return null
|
||||
return (resolvedCall.resultingDescriptor as? ClassConstructorDescriptor)?.containingDeclaration
|
||||
}
|
||||
|
||||
override fun resolve(context: UastContext): UClass? {
|
||||
val classDescriptor = resolveToDescriptor() ?: return null
|
||||
val source = classDescriptor.toSource() ?: return null
|
||||
return context.convert(source) as? UClass
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtAnnotation
|
||||
import org.jetbrains.uast.UAnnotation
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.acceptList
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
class KotlinUAnnotationList(
|
||||
override val psi: KtAnnotation,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UElement, PsiElementBacked {
|
||||
lateinit var annotations: List<UAnnotation>
|
||||
|
||||
override fun logString() = "KotlinUAnnotationList"
|
||||
override fun renderString() = annotations.joinToString(" ") { it.renderString() }
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitElement(this)) return
|
||||
annotations.acceptList(visitor)
|
||||
visitor.afterVisitElement(this)
|
||||
}
|
||||
}
|
||||
@@ -1,133 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUClass(
|
||||
override val psi: KtClassOrObject,
|
||||
override val parent: UElement,
|
||||
override val isAnonymous: Boolean = false
|
||||
) : KotlinAbstractUElement(), UClass, PsiElementBacked {
|
||||
override val name: String
|
||||
get() = psi.name.orAnonymous()
|
||||
|
||||
override val nameElement by lz {
|
||||
val namePsiElement = psi.nameIdentifier
|
||||
?: if (psi is KtObjectDeclaration && psi.isObjectLiteral()) psi.getObjectKeyword() else null
|
||||
KotlinConverter.asSimpleReference(namePsiElement, this)
|
||||
}
|
||||
|
||||
override val fqName: String?
|
||||
get() = psi.fqName?.asString()
|
||||
|
||||
override val kind by lz {
|
||||
when {
|
||||
psi.isAnnotation() -> UastClassKind.ANNOTATION
|
||||
(psi as? KtObjectDeclaration)?.isCompanion() ?: false -> KotlinClassKinds.COMPANION_OBJECT
|
||||
psi is KtObjectDeclaration -> UastClassKind.OBJECT
|
||||
(psi as? KtClass)?.isInterface() ?: false -> UastClassKind.INTERFACE
|
||||
(psi as? KtClass)?.isEnum() ?: false -> UastClassKind.ENUM
|
||||
else -> UastClassKind.CLASS
|
||||
}
|
||||
}
|
||||
|
||||
override val defaultType by lz {
|
||||
val type = resolveToDescriptor()?.defaultType ?: return@lz UastErrorType
|
||||
KotlinConverter.convert(type, psi.project, this)
|
||||
}
|
||||
|
||||
override val companions by lz {
|
||||
(psi as? KtClass)?.getCompanionObjects()?.map { KotlinConverter.convert(it, this) } ?: emptyList()
|
||||
}
|
||||
|
||||
override val internalName by lz {
|
||||
val descriptor = resolveToDescriptor() ?: return@lz null
|
||||
val typeMapper = KotlinTypeMapper(BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider,
|
||||
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false)
|
||||
typeMapper.mapClass(descriptor).internalName
|
||||
}
|
||||
|
||||
override fun getSuperClass(context: UastContext): UClass? {
|
||||
val descriptor = resolveToDescriptor() ?: return null
|
||||
if (KotlinBuiltIns.isAny(descriptor)) return null
|
||||
val source = descriptor.getSuperClassOrAny().toSource() ?: return null
|
||||
return context.convert(source) as? UClass
|
||||
}
|
||||
|
||||
override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier)
|
||||
|
||||
override val declarations by lz {
|
||||
val primaryConstructor = if (psi is KtObjectDeclaration && psi.isObjectLiteral()) {
|
||||
KotlinObjectLiteralConstructorUFunction(psi, this)
|
||||
} else {
|
||||
psi.getPrimaryConstructor()?.let { KotlinConverter.convert(it, this) } ?: run {
|
||||
if (psi.getSecondaryConstructors().isEmpty())
|
||||
KotlinDefaultPrimaryConstructorUFunction(psi, this)
|
||||
else
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
val anonymousInitializers = psi.getAnonymousInitializers().map { KotlinConverter.convert(it, this) }.filterNotNull()
|
||||
val declarations = psi.declarations.map { KotlinConverter.convert(it, this) }.filterNotNull()
|
||||
|
||||
if (primaryConstructor != null)
|
||||
listOf(primaryConstructor) + declarations + anonymousInitializers
|
||||
else
|
||||
declarations + anonymousInitializers
|
||||
}
|
||||
|
||||
override val superTypes by lz {
|
||||
val superTypes = resolveToDescriptor()?.typeConstructor?.supertypes ?: return@lz emptyList<UType>()
|
||||
superTypes.map { KotlinConverter.convert(it, psi.project, this) }
|
||||
}
|
||||
|
||||
override val annotations by lz { psi.getUastAnnotations(this) }
|
||||
|
||||
override val visibility by lz { psi.getVisibility() }
|
||||
|
||||
override fun isSubclassOf(fqName: String): Boolean {
|
||||
val descriptor = psi.resolveToDescriptorIfAny() as? ClassDescriptor ?: return false
|
||||
return descriptor.defaultType.supertypes().any {
|
||||
it.constructor.declarationDescriptor?.fqNameSafe?.asString() == fqName
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveToDescriptor(): ClassDescriptor? {
|
||||
val bindingContext = psi.analyze(BodyResolveMode.PARTIAL)
|
||||
return bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, psi] as? ClassDescriptor
|
||||
}
|
||||
}
|
||||
@@ -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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.uast.UFile
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUFile(override val psi: KtFile): KotlinAbstractUElement(), UFile, PsiElementBacked {
|
||||
override val packageFqName: String?
|
||||
get() = psi.packageFqName.asString()
|
||||
|
||||
override val declarations by lz { psi.declarations.map { KotlinConverter.convert(it, this) }.filterNotNull() }
|
||||
override val importStatements by lz { psi.importDirectives.map { KotlinUImportStatement(it, this) } }
|
||||
}
|
||||
-36
@@ -1,36 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UImportStatement
|
||||
import org.jetbrains.uast.UastContext
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUImportStatement(
|
||||
override val psi: KtImportDirective,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UImportStatement, PsiElementBacked {
|
||||
override val fqNameToImport = psi.importedFqName?.asString()
|
||||
|
||||
override val isStarImport: Boolean
|
||||
get() = psi.isAllUnder
|
||||
|
||||
//TODO support
|
||||
override fun resolve(context: UastContext) = null
|
||||
}
|
||||
@@ -1,81 +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.kotlin.uast
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUType(
|
||||
val type: KotlinType,
|
||||
val project: Project,
|
||||
override val parent: UElement?,
|
||||
override val psi: PsiElement? = null
|
||||
) : KotlinAbstractUElement(), UType, PsiElementBacked {
|
||||
override val name: String
|
||||
get() = type.toString()
|
||||
|
||||
override val fqName: String?
|
||||
get() = type.constructor.declarationDescriptor?.fqNameSafe?.asString()
|
||||
|
||||
override fun resolve(context: UastContext): UClass? {
|
||||
val descriptor = type.constructor.declarationDescriptor ?: return null
|
||||
val sourceElement = descriptor.toSource() ?: return null
|
||||
return context.convert(sourceElement) as? UClass
|
||||
}
|
||||
|
||||
override val isBoolean: Boolean
|
||||
get() = checkType(KotlinBuiltIns.FQ_NAMES._boolean)
|
||||
|
||||
override val isInt: Boolean
|
||||
get() = checkType(KotlinBuiltIns.FQ_NAMES._int)
|
||||
|
||||
override val isShort: Boolean
|
||||
get() = checkType(KotlinBuiltIns.FQ_NAMES._short)
|
||||
|
||||
override val isLong: Boolean
|
||||
get() = checkType(KotlinBuiltIns.FQ_NAMES._long)
|
||||
|
||||
override val isFloat: Boolean
|
||||
get() = checkType(KotlinBuiltIns.FQ_NAMES._float)
|
||||
|
||||
override val isDouble: Boolean
|
||||
get() = checkType(KotlinBuiltIns.FQ_NAMES._double)
|
||||
|
||||
override val isChar: Boolean
|
||||
get() = checkType(KotlinBuiltIns.FQ_NAMES._char)
|
||||
|
||||
override val isByte: Boolean
|
||||
get() = checkType(KotlinBuiltIns.FQ_NAMES._byte)
|
||||
|
||||
private fun checkType(fqNameUnsafe: FqNameUnsafe): Boolean {
|
||||
val descriptor = type.constructor.declarationDescriptor
|
||||
return descriptor is ClassDescriptor
|
||||
&& descriptor.getName() == fqNameUnsafe.shortName()
|
||||
&& fqNameUnsafe == DescriptorUtils.getFqName(descriptor)
|
||||
}
|
||||
|
||||
//TODO support descriptor annotations
|
||||
override val annotations = emptyList<UAnnotation>()
|
||||
}
|
||||
-42
@@ -1,42 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUTypeReference(
|
||||
override val psi: KtTypeReference,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UTypeReference, PsiElementBacked {
|
||||
override fun resolve(context: UastContext): UClass? {
|
||||
val descriptor = psi.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, psi]
|
||||
?.constructor?.declarationDescriptor as? ClassDescriptor ?: return null
|
||||
return context.convert(descriptor.toSource()) as? UClass
|
||||
}
|
||||
|
||||
override val nameElement: UElement?
|
||||
get() = KotlinDumbUElement(psi, this)
|
||||
|
||||
override val name: String
|
||||
get() = psi.name.orAnonymous()
|
||||
}
|
||||
@@ -1,199 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.uast.kinds.KotlinVariableInitializerKinds
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kinds.UastVariableInitialierKind
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
open class KotlinUVariable(
|
||||
override val psi: KtVariableDeclaration,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UVariable, PsiElementBacked {
|
||||
override val name: String
|
||||
get() = psi.name.orAnonymous()
|
||||
|
||||
override val nameElement by lz { KotlinDumbUElement(psi.nameIdentifier, this) }
|
||||
|
||||
override val initializer by lz {
|
||||
val expression = (psi as? KtProperty)?.delegateExpression ?: psi.initializer
|
||||
KotlinConverter.convertOrEmpty(expression, this)
|
||||
}
|
||||
|
||||
override val initializerKind by lz {
|
||||
if ((psi as? KtProperty)?.delegateExpression != null)
|
||||
KotlinVariableInitializerKinds.DELEGATION
|
||||
else if (psi.initializer != null)
|
||||
UastVariableInitialierKind.EXPRESSION
|
||||
else
|
||||
UastVariableInitialierKind.NO_INITIALIZER
|
||||
}
|
||||
|
||||
override val type by lz {
|
||||
val descriptor = psi.resolveToDescriptorIfAny() as? CallableDescriptor ?: return@lz UastErrorType
|
||||
val type = descriptor.returnType ?: return@lz UastErrorType
|
||||
KotlinConverter.convert(type, psi.project, this)
|
||||
}
|
||||
|
||||
override val accessors: List<UFunction>? by lz {
|
||||
(psi as? KtProperty)?.accessors?.map { VariableAccessorFunction(it, this) }
|
||||
}
|
||||
|
||||
override val kind: UastVariableKind
|
||||
get() = when (psi.parent) {
|
||||
is KtClassBody -> UastVariableKind.MEMBER
|
||||
is KtClassOrObject -> UastVariableKind.MEMBER
|
||||
else -> UastVariableKind.LOCAL_VARIABLE
|
||||
}
|
||||
|
||||
override val visibility: UastVisibility
|
||||
get() = psi.getVisibility()
|
||||
|
||||
override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier)
|
||||
override val annotations by lz { psi.getUastAnnotations(this) }
|
||||
|
||||
private class VariableAccessorFunction(
|
||||
override val psi: KtPropertyAccessor,
|
||||
override val parent: UVariable
|
||||
) : KotlinAbstractUElement(), UFunction, PsiElementBacked {
|
||||
override val kind: UastFunctionKind
|
||||
get() = if (psi.isGetter)
|
||||
UastFunctionKind.GETTER
|
||||
else if (psi.isSetter)
|
||||
UastFunctionKind.SETTER
|
||||
else
|
||||
UastFunctionKind.FUNCTION
|
||||
|
||||
override val valueParameters by lz { psi.valueParameters.map { KotlinConverter.convert(it, this) } }
|
||||
|
||||
override val valueParameterCount: Int
|
||||
get() = psi.valueParameters.size
|
||||
|
||||
override val typeParameters: List<UTypeReference>
|
||||
get() = emptyList()
|
||||
|
||||
override val typeParameterCount: Int
|
||||
get() = 0
|
||||
|
||||
override val returnType: UType?
|
||||
get() = if (psi.isSetter) null else parent.type
|
||||
|
||||
override val body by lz { KotlinConverter.convertOrNull(psi.bodyExpression, this) }
|
||||
|
||||
override val visibility: UastVisibility
|
||||
get() = psi.getVisibility()
|
||||
|
||||
override fun getSuperFunctions(context: UastContext) = emptyList<UFunction>()
|
||||
|
||||
override val nameElement by lz { KotlinDumbUElement(psi.namePlaceholder, this) }
|
||||
|
||||
override val name: String
|
||||
get() = when {
|
||||
psi.isSetter -> "<set>"
|
||||
psi.isGetter -> "<get>"
|
||||
else -> "<accessor>"
|
||||
}
|
||||
|
||||
override fun hasModifier(modifier: UastModifier) = false
|
||||
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinDestructuredUVariable(
|
||||
val entry: KtDestructuringDeclarationEntry,
|
||||
parent: UElement
|
||||
) : KotlinUVariable(entry, parent) {
|
||||
override lateinit var initializer: UExpression
|
||||
internal set
|
||||
|
||||
override val type by lz {
|
||||
val bindingContext = entry.analyze(BodyResolveMode.PARTIAL)
|
||||
val resolvedCall = bindingContext[BindingContext.COMPONENT_RESOLVED_CALL, entry] ?: return@lz UastErrorType
|
||||
val returnType = resolvedCall.resultingDescriptor.returnType ?: return@lz UastErrorType
|
||||
KotlinConverter.convert(returnType, entry.project, this)
|
||||
}
|
||||
|
||||
override val visibility: UastVisibility
|
||||
get() = UastVisibility.LOCAL
|
||||
}
|
||||
|
||||
class KotlinDestructuringUVariable(
|
||||
override val psi: KtDestructuringDeclaration,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UVariable, PsiElementBacked {
|
||||
override val name = "var" + psi.text.hashCode()
|
||||
|
||||
override val initializer by lz { KotlinConverter.convertOrEmpty(psi.initializer, this) }
|
||||
|
||||
override val initializerKind: UastVariableInitialierKind
|
||||
get() = if (initializer != null)
|
||||
UastVariableInitialierKind.EXPRESSION
|
||||
else
|
||||
UastVariableInitialierKind.NO_INITIALIZER
|
||||
|
||||
override val kind = UastVariableKind.LOCAL_VARIABLE
|
||||
override val type: UType
|
||||
get() = initializer.getExpressionType() ?: UastErrorType
|
||||
|
||||
override val nameElement = null
|
||||
override fun hasModifier(modifier: UastModifier) = false
|
||||
override val annotations = emptyList<UAnnotation>()
|
||||
|
||||
override val visibility: UastVisibility
|
||||
get() = UastVisibility.LOCAL
|
||||
}
|
||||
|
||||
class KotlinParameterUVariable(
|
||||
override val psi: KtParameter,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UVariable, PsiElementBacked {
|
||||
override val name: String
|
||||
get() = psi.name.orAnonymous()
|
||||
|
||||
override val nameElement by lz { KotlinDumbUElement(psi.nameIdentifier, this) }
|
||||
|
||||
override val initializer by lz { KotlinConverter.convert(psi.defaultValue, this) as? UExpression }
|
||||
|
||||
override val initializerKind: UastVariableInitialierKind
|
||||
get() = if (initializer != null)
|
||||
UastVariableInitialierKind.EXPRESSION
|
||||
else
|
||||
UastVariableInitialierKind.NO_INITIALIZER
|
||||
|
||||
override val kind = UastVariableKind.VALUE_PARAMETER
|
||||
|
||||
override val type by lz {
|
||||
val bindingContext = psi.analyze(BodyResolveMode.PARTIAL)
|
||||
val param = bindingContext[BindingContext.VALUE_PARAMETER, psi] ?: return@lz UastErrorType
|
||||
KotlinConverter.convert(param.type, psi.project, this)
|
||||
}
|
||||
|
||||
override val visibility: UastVisibility
|
||||
get() = UastVisibility.LOCAL
|
||||
|
||||
override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier)
|
||||
override val annotations = psi.getUastAnnotations(this)
|
||||
}
|
||||
@@ -1,263 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kinds.UastVariableInitialierKind
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
abstract class KotlinAbstractUFunction : KotlinAbstractUElement(), UFunction, PsiElementBacked {
|
||||
override abstract val psi: KtFunction
|
||||
|
||||
override val name by lz { psi.name.orAnonymous() }
|
||||
|
||||
override val valueParameterCount: Int
|
||||
get() = psi.valueParameters.size
|
||||
|
||||
override val valueParameters by lz { psi.valueParameters.map { KotlinConverter.convert(it, this) } }
|
||||
|
||||
override fun getSuperFunctions(context: UastContext): List<UFunction> {
|
||||
if (this.isTopLevel()) return emptyList()
|
||||
val bindingContext = psi.analyze(BodyResolveMode.PARTIAL)
|
||||
val clazz = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, psi] as? FunctionDescriptor ?: return emptyList()
|
||||
return clazz.overriddenDescriptors.map {
|
||||
context.convert(it.toSource()) as? UFunction
|
||||
}.filterNotNull()
|
||||
}
|
||||
|
||||
override val bytecodeDescriptor by lz {
|
||||
val bindingContext = psi.analyze(BodyResolveMode.PARTIAL)
|
||||
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, psi] as? FunctionDescriptor ?: return@lz null
|
||||
|
||||
fun KotlinType?.isAnonymous(): Boolean {
|
||||
if (this == null) return true
|
||||
return false
|
||||
}
|
||||
|
||||
if (descriptor.valueParameters.any { it.type.isAnonymous() } || descriptor.returnType.isAnonymous()) {
|
||||
return@lz null
|
||||
}
|
||||
|
||||
val typeMapper = KotlinTypeMapper(BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider,
|
||||
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false)
|
||||
typeMapper.mapAsmMethod(descriptor).descriptor
|
||||
}
|
||||
|
||||
override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier)
|
||||
override val annotations by lz { psi.getUastAnnotations(this) }
|
||||
|
||||
override val body by lz { KotlinConverter.convertOrNull(psi.bodyExpression, this) }
|
||||
override val visibility by lz { psi.getVisibility() }
|
||||
}
|
||||
|
||||
class KotlinConstructorUFunction(
|
||||
override val psi: KtConstructor<*>,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUFunction(), PsiElementBacked {
|
||||
override val name: String
|
||||
get() = "<init>"
|
||||
|
||||
override val nameElement by lz {
|
||||
val constructorKeyword = psi.getConstructorKeyword()?.let { KotlinDumbUElement(it, this) }
|
||||
constructorKeyword ?: this.getContainingFunction()?.nameElement
|
||||
}
|
||||
|
||||
override val kind = UastFunctionKind.CONSTRUCTOR
|
||||
|
||||
override val typeParameterCount = 0
|
||||
override val typeParameters = emptyList<UTypeReference>()
|
||||
|
||||
override val returnType = null
|
||||
}
|
||||
|
||||
class KotlinUFunction(
|
||||
override val psi: KtFunction,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUFunction(), PsiElementBacked {
|
||||
override val nameElement by lz { psi.nameIdentifier?.let { KotlinDumbUElement(it, this) } }
|
||||
|
||||
override val kind = UastFunctionKind.FUNCTION
|
||||
|
||||
override val returnType by lz {
|
||||
val descriptor = psi.resolveToDescriptorIfAny() as? FunctionDescriptor ?: return@lz null
|
||||
val type = descriptor.returnType ?: return@lz null
|
||||
KotlinConverter.convert(type, psi.project, this)
|
||||
}
|
||||
|
||||
override val typeParameterCount: Int
|
||||
get() = psi.typeParameters.size
|
||||
|
||||
override val typeParameters by lz { psi.typeParameters.map { KotlinParameterUTypeReference(it, this) } }
|
||||
}
|
||||
|
||||
class KotlinAnonymousInitializerUFunction(
|
||||
override val psi: KtAnonymousInitializer,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UFunction, PsiElementBacked {
|
||||
override val kind = KotlinFunctionKinds.INIT_BLOCK
|
||||
|
||||
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 { KotlinConverter.convertOrNull(psi.body, this) }
|
||||
|
||||
override val visibility: UastVisibility
|
||||
get() = UastVisibility.PRIVATE
|
||||
|
||||
override fun getSuperFunctions(context: UastContext) = emptyList<UFunction>()
|
||||
|
||||
override val nameElement by lz { KotlinDumbUElement(psi.node.findChildByType(KtTokens.INIT_KEYWORD)?.psi ?: psi, this) }
|
||||
|
||||
override val name: String
|
||||
get() = "<init>"
|
||||
|
||||
override fun hasModifier(modifier: UastModifier) = false
|
||||
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
}
|
||||
|
||||
open class KotlinDefaultPrimaryConstructorUFunction(
|
||||
override val psi: KtClassOrObject,
|
||||
override val parent: UClass
|
||||
) : KotlinAbstractUElement(), UFunction, PsiElementBacked, NoModifiers, NoAnnotations {
|
||||
override val kind: UastFunctionKind
|
||||
get() = UastFunctionKind.CONSTRUCTOR
|
||||
|
||||
override val nameElement by lz { KotlinDumbUElement(psi.nameIdentifier, this) }
|
||||
override val name: String
|
||||
get() = "<init>"
|
||||
|
||||
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: UExpression?
|
||||
get() = null
|
||||
|
||||
override val visibility: UastVisibility
|
||||
get() = parent.visibility
|
||||
|
||||
override fun getSuperFunctions(context: UastContext) = emptyList<UFunction>()
|
||||
}
|
||||
|
||||
open class KotlinObjectLiteralConstructorUFunction(
|
||||
override val psi: KtObjectDeclaration,
|
||||
override val parent: UClass
|
||||
) : KotlinAbstractUElement(), UFunction, PsiElementBacked, NoModifiers, NoAnnotations {
|
||||
private val resolvedCall by lz {
|
||||
val bindingContext = psi.analyze(BodyResolveMode.PARTIAL)
|
||||
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, psi] as? ClassDescriptor
|
||||
val primaryConstructor = descriptor?.unsubstitutedPrimaryConstructor ?: return@lz null
|
||||
bindingContext[BindingContext.CONSTRUCTOR_RESOLVED_DELEGATION_CALL, primaryConstructor]
|
||||
}
|
||||
|
||||
override val kind: UastFunctionKind
|
||||
get() = UastFunctionKind.CONSTRUCTOR
|
||||
|
||||
override val nameElement by lz { KotlinDumbUElement(psi.nameIdentifier, this) }
|
||||
override val name: String
|
||||
get() = "<init>"
|
||||
|
||||
|
||||
override val valueParameters by lz {
|
||||
val params = resolvedCall?.valueArguments?.keys ?: return@lz emptyList<UVariable>()
|
||||
params.map { param ->
|
||||
object : UVariable {
|
||||
override val initializer: UExpression?
|
||||
get() = null
|
||||
override val initializerKind: UastVariableInitialierKind
|
||||
get() = UastVariableInitialierKind.NO_INITIALIZER
|
||||
override val kind: UastVariableKind
|
||||
get() = UastVariableKind.VALUE_PARAMETER
|
||||
override val type: UType
|
||||
get() = KotlinConverter.convert(param.type, psi.project, this)
|
||||
override val nameElement: UElement?
|
||||
get() = null
|
||||
override val parent: UElement
|
||||
get() = this@KotlinObjectLiteralConstructorUFunction
|
||||
override val name: String
|
||||
get() = param.name.asString()
|
||||
override val visibility: UastVisibility
|
||||
get() = UastVisibility.LOCAL
|
||||
|
||||
override fun hasModifier(modifier: UastModifier) = when(modifier) {
|
||||
UastModifier.VARARG -> param.varargElementType != null
|
||||
else -> false
|
||||
}
|
||||
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val valueParameterCount: Int
|
||||
get() = resolvedCall?.valueArgumentsByIndex?.size ?: 0
|
||||
|
||||
override val typeParameters: List<UTypeReference>
|
||||
get() = emptyList()
|
||||
|
||||
override val typeParameterCount: Int
|
||||
get() = 0
|
||||
|
||||
override val returnType: UType?
|
||||
get() = null
|
||||
|
||||
override val body: UExpression?
|
||||
get() = null
|
||||
|
||||
override val visibility: UastVisibility
|
||||
get() = parent.visibility
|
||||
|
||||
override fun getSuperFunctions(context: UastContext) = emptyList<UFunction>()
|
||||
}
|
||||
-35
@@ -1,35 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUCallableReferenceExpression(
|
||||
override val psi: KtCallableReferenceExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UCallableReferenceExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val qualifierExpression by lz { KotlinConverter.convertOrEmpty(psi.receiverExpression, this) }
|
||||
override val qualifierType: UType? get() = null // TODO
|
||||
override val callableName: String
|
||||
get() = psi.callableReference.getReferencedName()
|
||||
|
||||
override fun resolve(context: UastContext): UDeclaration? {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
-30
@@ -1,30 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtClassLiteralExpression
|
||||
import org.jetbrains.uast.UClassLiteralExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UType
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUClassLiteralExpression(
|
||||
override val psi: KtClassLiteralExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UClassLiteralExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val type: UType? get() = null // TODO
|
||||
}
|
||||
-123
@@ -1,123 +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.kotlin.uast
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUFunctionCallExpression(
|
||||
override val psi: KtCallExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UCallExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
private val resolvedCall by lz { psi.getResolvedCall(psi.analyze(BodyResolveMode.PARTIAL)) }
|
||||
|
||||
override val receiverType by lz {
|
||||
val resolvedCall = this.resolvedCall ?: return@lz null
|
||||
val receiver = resolvedCall.extensionReceiver ?: resolvedCall.dispatchReceiver ?: return@lz null
|
||||
KotlinConverter.convert(receiver.type, psi.project, null)
|
||||
}
|
||||
|
||||
override val functionName: String? by lz { resolvedCall?.resultingDescriptor?.name?.asString().orAnonymous() }
|
||||
override fun matchesFunctionName(name: String) = functionName == name
|
||||
|
||||
override val functionNameElement by lz { psi.calleeExpression?.let { KotlinConverter.convert(it, this) } }
|
||||
|
||||
override val classReference by lz {
|
||||
KotlinClassViaConstructorUSimpleReferenceExpression(psi, functionName.orAnonymous("class"), this)
|
||||
}
|
||||
|
||||
override val functionReference by lz {
|
||||
val calleeExpression = psi.calleeExpression ?: return@lz null
|
||||
val name = (calleeExpression as? KtSimpleNameExpression)?.getReferencedName() ?: return@lz null
|
||||
KotlinNameUSimpleReferenceExpression(calleeExpression, name, this)
|
||||
}
|
||||
|
||||
override val valueArgumentCount: Int
|
||||
get() = psi.valueArguments.size
|
||||
|
||||
override val valueArguments by lz { psi.valueArguments.map { KotlinConverter.convertOrEmpty(it.getArgumentExpression(), this) } }
|
||||
|
||||
override val typeArgumentCount: Int
|
||||
get() = psi.typeArguments.size
|
||||
|
||||
override val typeArguments by lz { psi.typeArguments.map { KotlinConverter.convert(it.typeReference, this) } }
|
||||
|
||||
override val kind by lz {
|
||||
when (resolvedCall?.resultingDescriptor) {
|
||||
is ConstructorDescriptor -> UastCallKind.CONSTRUCTOR_CALL
|
||||
else -> UastCallKind.FUNCTION_CALL
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolve(context: UastContext): UFunction? {
|
||||
val descriptor = resolvedCall?.resultingDescriptor ?: return null
|
||||
val source = descriptor.toSource() ?: return null
|
||||
|
||||
if (descriptor is ConstructorDescriptor && descriptor.isPrimary
|
||||
&& source is KtClassOrObject && source.getPrimaryConstructor() == null
|
||||
&& source.getSecondaryConstructors().isEmpty()) {
|
||||
return (context.convert(source) as? UClass)?.constructors?.firstOrNull()
|
||||
}
|
||||
|
||||
return context.convert(source) as? UFunction
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinUComponentFunctionCallExpression(
|
||||
override val psi: PsiElement,
|
||||
n: Int,
|
||||
override val parent: UElement
|
||||
) : UCallExpression, PsiElementBacked {
|
||||
override val receiverType: UType?
|
||||
get() = null
|
||||
|
||||
override val valueArgumentCount: Int
|
||||
get() = 0
|
||||
|
||||
override val valueArguments: List<UExpression>
|
||||
get() = emptyList()
|
||||
|
||||
override val typeArgumentCount: Int
|
||||
get() = 0
|
||||
|
||||
override val typeArguments: List<UType>
|
||||
get() = emptyList()
|
||||
|
||||
override val classReference: USimpleReferenceExpression?
|
||||
get() = null
|
||||
|
||||
override val functionName = "component$n"
|
||||
|
||||
override val functionReference by lz { KotlinStringUSimpleReferenceExpression(functionName, this) }
|
||||
|
||||
override val functionNameElement: UElement?
|
||||
get() = null
|
||||
|
||||
override val kind: UastCallKind
|
||||
get() = UastCallKind.FUNCTION_CALL
|
||||
|
||||
override fun resolve(context: UastContext): UFunction? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UObjectLiteralExpression
|
||||
import org.jetbrains.uast.UType
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUObjectLiteralExpression(
|
||||
override val psi: KtObjectLiteralExpression,
|
||||
override val parent: UElement
|
||||
) : UObjectLiteralExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val declaration by lz { KotlinUClass(psi.objectDeclaration, this, true) }
|
||||
override fun getExpressionType(): UType? {
|
||||
val obj = psi.objectDeclaration
|
||||
val bindingContext = obj.analyze(BodyResolveMode.PARTIAL)
|
||||
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, obj] as? ClassDescriptor ?: return null
|
||||
return KotlinConverter.convert(descriptor.getSuperClassOrAny().defaultType, psi.project, null)
|
||||
}
|
||||
}
|
||||
-75
@@ -1,75 +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.kotlin.uast
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
open class KotlinUSimpleReferenceExpression(
|
||||
override val psi: PsiElement,
|
||||
override val identifier: String,
|
||||
override val parent: UElement,
|
||||
private val descriptor: DeclarationDescriptor? = null
|
||||
) : KotlinAbstractUElement(), USimpleReferenceExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override fun resolve(context: UastContext): UDeclaration? {
|
||||
val resultingDescriptor = descriptor ?: run {
|
||||
val ktElement = psi as? KtElement ?: return null
|
||||
val bindingContext = ktElement.analyze(BodyResolveMode.PARTIAL)
|
||||
val resolvedCall = ktElement.getResolvedCall(bindingContext) ?: return null
|
||||
resolvedCall.resultingDescriptor
|
||||
}
|
||||
|
||||
val source = resultingDescriptor.toSource() ?: return null
|
||||
return context.convert(source) as? UDeclaration
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinNameUSimpleReferenceExpression(
|
||||
psi: PsiElement,
|
||||
identifier: String,
|
||||
parent: UElement,
|
||||
descriptor: DeclarationDescriptor? = null
|
||||
) : KotlinUSimpleReferenceExpression(psi, identifier, parent, descriptor)
|
||||
|
||||
class KotlinClassViaConstructorUSimpleReferenceExpression(
|
||||
override val psi: KtCallExpression,
|
||||
override val identifier: String,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), USimpleReferenceExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override fun resolve(context: UastContext): UDeclaration? {
|
||||
val resolvedCall = psi.getResolvedCall(psi.analyze(BodyResolveMode.PARTIAL))
|
||||
val resultingDescriptor = resolvedCall?.resultingDescriptor as? ConstructorDescriptor ?: return null
|
||||
val clazz = resultingDescriptor.containingDeclaration
|
||||
val source = clazz.toSource() ?: return null
|
||||
return context.convert(source) as? UClass
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinStringUSimpleReferenceExpression(
|
||||
override val identifier: String,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), USimpleReferenceExpression {
|
||||
override fun resolve(context: UastContext) = null
|
||||
}
|
||||
-103
@@ -1,103 +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.kotlin.uast.extensions
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.references.SyntheticPropertyAccessorReference
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.uast.*
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
class PropertyAsCallAndroidUastVisitorExtension : UastVisitorExtension {
|
||||
override fun invoke(element: UElement, visitor: UastVisitor, context: UastContext) {
|
||||
val expr = element as? KotlinUSimpleReferenceExpression ?: return
|
||||
if (expr is KotlinNameUSimpleReferenceExpression) return
|
||||
|
||||
val ktElement = expr.psi as? KtElement ?: return
|
||||
val bindingContext = ktElement.analyze(BodyResolveMode.PARTIAL)
|
||||
|
||||
val referenceToAccessor = ktElement.references.firstOrNull { it is SyntheticPropertyAccessorReference } ?: return
|
||||
val accessorDescriptor = (referenceToAccessor as SyntheticPropertyAccessorReference)
|
||||
.resolveToDescriptors(bindingContext).firstOrNull() ?: return
|
||||
|
||||
val resolvedCall = ktElement.getResolvedCall(bindingContext) ?: return
|
||||
|
||||
val setterValue = if (referenceToAccessor is SyntheticPropertyAccessorReference.Setter)
|
||||
findAssignment(ktElement, ktElement.parent)?.right ?: return
|
||||
else
|
||||
null
|
||||
|
||||
val callExpression: UCallExpression = object : UCallExpression, PsiElementBacked, SynthesizedUElement {
|
||||
override val parent = element.parent
|
||||
override val psi = ktElement
|
||||
|
||||
override val receiverType by lz {
|
||||
val type = (resolvedCall.extensionReceiver ?: resolvedCall.dispatchReceiver)?.type ?: return@lz null
|
||||
KotlinConverter.convert(type, psi.project, null)
|
||||
}
|
||||
|
||||
override val functionReference = KotlinNameUSimpleReferenceExpression(
|
||||
expr.psi, expr.identifier, expr.parent, accessorDescriptor)
|
||||
|
||||
override val classReference = null
|
||||
override val functionName = accessorDescriptor.name.asString()
|
||||
override val functionNameElement by lz { KotlinDumbUElement(ktElement, this) }
|
||||
|
||||
override val valueArgumentCount: Int
|
||||
get() = if (setterValue != null) 1 else 0
|
||||
|
||||
override val valueArguments by lz {
|
||||
if (setterValue != null)
|
||||
listOf(KotlinConverter.convert(setterValue, this))
|
||||
else
|
||||
emptyList()
|
||||
}
|
||||
|
||||
override val typeArgumentCount: Int
|
||||
get() = resolvedCall.typeArguments.size
|
||||
|
||||
override val typeArguments by lz {
|
||||
resolvedCall.typeArguments.map { KotlinUType(it.value, ktElement.project, this) }
|
||||
}
|
||||
|
||||
override val kind = UastCallKind.FUNCTION_CALL
|
||||
|
||||
override fun resolve(context: UastContext): UFunction? {
|
||||
val source = accessorDescriptor.toSource()
|
||||
if (source != null) {
|
||||
(context.convert(source) as? UFunction)?.let { return it }
|
||||
}
|
||||
return element.resolveIfCan(context) as? UFunction
|
||||
}
|
||||
}
|
||||
|
||||
visitor.visitCallExpression(callExpression)
|
||||
}
|
||||
|
||||
private tailrec fun findAssignment(prev: PsiElement?, element: PsiElement?): KtBinaryExpression? = when (element) {
|
||||
is KtBinaryExpression -> if (element.left == prev && element.operationToken == KtTokens.EQ) element else null
|
||||
is KtQualifiedExpression -> findAssignment(element, element.parent)
|
||||
is KtSimpleNameExpression -> findAssignment(element, element.parent)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
-128
@@ -1,128 +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.kotlin.uast
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
|
||||
import org.jetbrains.kotlin.idea.util.findAnnotation
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.uast.kinds.KotlinUastVisibilities
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
private val JVM_STATIC_FQNAME = "kotlin.jvm.JvmStatic"
|
||||
private val JVM_FIELD_FQNAME = "kotlin.jvm.JvmField"
|
||||
|
||||
private val MODIFIER_MAP = mapOf(
|
||||
UastModifier.ABSTRACT to KtTokens.ABSTRACT_KEYWORD,
|
||||
UastModifier.OVERRIDE to KtTokens.OVERRIDE_KEYWORD
|
||||
)
|
||||
|
||||
internal fun KtDeclaration.getVisibility() = when (visibilityModifierType()) {
|
||||
KtTokens.PRIVATE_KEYWORD -> UastVisibility.PRIVATE
|
||||
KtTokens.PROTECTED_KEYWORD -> UastVisibility.PROTECTED
|
||||
KtTokens.INTERNAL_KEYWORD -> KotlinUastVisibilities.INTERNAL
|
||||
else -> UastVisibility.PUBLIC
|
||||
}
|
||||
|
||||
internal fun KtModifierListOwner.hasModifier(modifier: UastModifier): Boolean {
|
||||
if (modifier == UastModifier.STATIC) {
|
||||
// Object literals can't be static
|
||||
if (this is KtObjectDeclaration && this.isObjectLiteral()) {
|
||||
return false
|
||||
}
|
||||
if (this is KtClassOrObject && !hasModifier(KtTokens.INNER_KEYWORD)) {
|
||||
return true
|
||||
}
|
||||
if (this is KtDeclaration && (parent is KtObjectDeclaration ||
|
||||
parent is KtClassBody && parent?.parent is KtObjectDeclaration)) {
|
||||
return hasAnyAnnotation(JVM_STATIC_FQNAME, JVM_FIELD_FQNAME)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if (modifier == UastModifier.JVM_FIELD) {
|
||||
var bindingContext: BindingContext? = null
|
||||
fun getOrCreateBindingContext(): BindingContext {
|
||||
if (bindingContext == null) {
|
||||
bindingContext = analyze(BodyResolveMode.PARTIAL)
|
||||
}
|
||||
return bindingContext!!
|
||||
}
|
||||
|
||||
if (this is KtProperty) {
|
||||
val context = getOrCreateBindingContext()
|
||||
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, this] as? PropertyDescriptor ?: return false
|
||||
return context[BindingContext.BACKING_FIELD_REQUIRED, descriptor] ?: false
|
||||
}
|
||||
}
|
||||
if (modifier == UastModifier.FINAL) return hasModifier(KtTokens.FINAL_KEYWORD)
|
||||
if (modifier == UastModifier.IMMUTABLE && this is KtVariableDeclaration && !this.isVar) return true
|
||||
|
||||
val javaModifier = MODIFIER_MAP[modifier] ?: return false
|
||||
return hasModifier(javaModifier)
|
||||
}
|
||||
|
||||
private fun KtElement.hasAnyAnnotation(vararg annotationFqNames: String): Boolean {
|
||||
if (this !is KtAnnotated) return false
|
||||
|
||||
val bindingContext = analyze(BodyResolveMode.PARTIAL)
|
||||
for (annotationFqName in annotationFqNames) {
|
||||
val annotationEntry = findAnnotation(FqName(annotationFqName)) ?: continue
|
||||
val annotationDescriptor = bindingContext[BindingContext.ANNOTATION, annotationEntry] ?: continue
|
||||
val classifierDescriptor = annotationDescriptor.type.constructor.declarationDescriptor ?: continue
|
||||
val fqName = DescriptorUtils.getFqName(classifierDescriptor).asString()
|
||||
return fqName == annotationFqName
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
internal fun KtElement?.resolveCallToUDeclaration(context: UastContext): UDeclaration? {
|
||||
if (this == null) return null
|
||||
val resolvedCall = this.getResolvedCall(analyze(BodyResolveMode.PARTIAL)) ?: return null
|
||||
val source = (resolvedCall.resultingDescriptor).toSource() ?: return null
|
||||
return context.convert(source) as? UDeclaration
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
internal inline fun String?.orAnonymous(kind: String = ""): String {
|
||||
return this ?: "<anonymous" + (if (kind.isNotBlank()) " $kind" else "") + ">"
|
||||
}
|
||||
|
||||
internal fun KtAnnotated.getUastAnnotations(parent: UElement) = annotationEntries.map { KotlinUAnnotation(it, parent) }
|
||||
|
||||
internal fun DeclarationDescriptor.toSource() = try {
|
||||
DescriptorToSourceUtils.descriptorToDeclaration(this)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
internal fun <T> lz(initializer: () -> T) = lazy(LazyThreadSafetyMode.NONE, initializer)
|
||||
@@ -1,25 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.uast.UastClassKind
|
||||
|
||||
|
||||
object KotlinClassKinds {
|
||||
@JvmField
|
||||
val COMPANION_OBJECT = UastClassKind("companion object")
|
||||
}
|
||||
@@ -1,23 +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.kotlin.uast
|
||||
|
||||
import org.jetbrains.uast.UastFunctionKind
|
||||
|
||||
object KotlinFunctionKinds {
|
||||
val INIT_BLOCK = UastFunctionKind.UastInitializerKind("<init>")
|
||||
}
|
||||
@@ -1,24 +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.kotlin.uast.kinds
|
||||
|
||||
import org.jetbrains.uast.UastVisibility
|
||||
|
||||
object KotlinUastVisibilities {
|
||||
@JvmField
|
||||
val INTERNAL = UastVisibility("internal")
|
||||
}
|
||||
-24
@@ -1,24 +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.kotlin.uast.kinds
|
||||
|
||||
import org.jetbrains.uast.kinds.UastVariableInitialierKind
|
||||
|
||||
object KotlinVariableInitializerKinds {
|
||||
@JvmField
|
||||
val DELEGATION = UastVariableInitialierKind("delegation")
|
||||
}
|
||||
+7
-2
@@ -14,9 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
abstract class KotlinAbstractUElement : UElement {
|
||||
@@ -27,4 +30,6 @@ abstract class KotlinAbstractUElement : UElement {
|
||||
|
||||
return this.psi == other.psi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class KotlinAbstractUExpression : KotlinAbstractUElement(), UExpression
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright 2010-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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightParameter
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.java.JavaUastLanguagePlugin
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
|
||||
import org.jetbrains.uast.kotlin.expressions.KotlinUBreakExpression
|
||||
import org.jetbrains.uast.kotlin.expressions.KotlinUContinueExpression
|
||||
import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds
|
||||
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
|
||||
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
interface KotlinUastBindingContextProviderService {
|
||||
fun getBindingContext(element: KtElement): BindingContext
|
||||
fun getTypeMapper(element: KtElement): KotlinTypeMapper?
|
||||
}
|
||||
|
||||
class KotlinUastLanguagePlugin(override val project: Project) : UastLanguagePlugin {
|
||||
override val priority = 10
|
||||
|
||||
private val javaPlugin by lz { UastLanguagePlugin.getInstances(project).first { it is JavaUastLanguagePlugin } }
|
||||
|
||||
override val language: Language
|
||||
get() = KotlinLanguage.INSTANCE
|
||||
|
||||
override fun isFileSupported(fileName: String): Boolean {
|
||||
return fileName.endsWith(".kt", false) || fileName.endsWith(".kts", false)
|
||||
}
|
||||
|
||||
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
if (element !is PsiElement) return null
|
||||
return convertDeclaration(element, parent, requiredType) ?: KotlinConverter.convertPsiElement(element, parent, requiredType)
|
||||
}
|
||||
|
||||
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
|
||||
if (element !is PsiElement) return null
|
||||
if (element is PsiFile) return convertDeclaration(element, null, requiredType)
|
||||
|
||||
val parent = element.parent ?: return null
|
||||
val parentUElement = convertElementWithParent(parent, null) ?: return null
|
||||
return convertElement(element, parentUElement, requiredType)
|
||||
}
|
||||
|
||||
override fun getMethodCallExpression(
|
||||
element: PsiElement,
|
||||
containingClassFqName: String?,
|
||||
methodName: String
|
||||
): UastLanguagePlugin.ResolvedMethod? {
|
||||
if (element !is KtCallExpression) return null
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return null
|
||||
val resultingDescriptor = resolvedCall.resultingDescriptor
|
||||
if (resultingDescriptor !is FunctionDescriptor || resultingDescriptor.name.asString() != methodName) return null
|
||||
|
||||
val parent = element.parent ?: return null
|
||||
val parentUElement = convertElementWithParent(parent, null) ?: return null
|
||||
|
||||
val uExpression = KotlinUFunctionCallExpression(element, parentUElement, resolvedCall)
|
||||
val method = uExpression.resolve() ?: return null
|
||||
if (method.name != methodName) return null
|
||||
return UastLanguagePlugin.ResolvedMethod(uExpression, method)
|
||||
}
|
||||
|
||||
override fun getConstructorCallExpression(
|
||||
element: PsiElement,
|
||||
fqName: String
|
||||
): UastLanguagePlugin.ResolvedConstructor? {
|
||||
if (element !is KtCallExpression) return null
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return null
|
||||
val resultingDescriptor = resolvedCall.resultingDescriptor
|
||||
if (resultingDescriptor !is ConstructorDescriptor
|
||||
|| resultingDescriptor.returnType.constructor.declarationDescriptor?.name?.asString() != fqName) {
|
||||
return null
|
||||
}
|
||||
|
||||
val parent = element.parent ?: return null
|
||||
val parentUElement = convertElementWithParent(parent, null) ?: return null
|
||||
|
||||
val uExpression = KotlinUFunctionCallExpression(element, parentUElement, resolvedCall)
|
||||
val method = uExpression.resolve() ?: return null
|
||||
val containingClass = method.containingClass ?: return null
|
||||
return UastLanguagePlugin.ResolvedConstructor(uExpression, method, containingClass)
|
||||
}
|
||||
|
||||
private fun convertDeclaration(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
if (element is UElement) return element
|
||||
|
||||
if (element.isValid) element.getUserData(KOTLIN_CACHED_UELEMENT_KEY)?.let { ref ->
|
||||
ref.get()?.let { return it }
|
||||
}
|
||||
|
||||
val original = element.originalElement
|
||||
return when (original) {
|
||||
is KtLightMethod -> KotlinUMethod.create(original, parent)
|
||||
is KtLightClass -> KotlinUClass.create(original, parent)
|
||||
is KtLightField, is KtLightParameter, is UastKotlinPsiParameter, is UastKotlinPsiVariable -> {
|
||||
KotlinUVariable.create(original as PsiVariable, parent)
|
||||
}
|
||||
|
||||
is KtClassOrObject -> original.toLightClass()?.let { lightClass -> KotlinUClass.create(lightClass, parent) }
|
||||
is KtFunction -> {
|
||||
val lightMethod = LightClassUtil.getLightClassMethod(original) ?: return null
|
||||
convertDeclaration(lightMethod, parent, requiredType)
|
||||
}
|
||||
is KtPropertyAccessor -> javaPlugin.convertOpt<UMethod>(
|
||||
LightClassUtil.getLightClassAccessorMethod(original), parent)
|
||||
is KtProperty -> javaPlugin.convertOpt<UField>(
|
||||
LightClassUtil.getLightClassBackingField(original), parent)
|
||||
?: convertDeclaration(element.parent, parent, requiredType)
|
||||
|
||||
is KtFile -> KotlinUFile(original, this)
|
||||
is FakeFileForLightClass -> KotlinUFile(original.navigationElement, this)
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun isExpressionValueUsed(element: UExpression): Boolean {
|
||||
return when (element) {
|
||||
is KotlinUSimpleReferenceExpression.KotlinAccessorCallExpression -> element.setterValue != null
|
||||
is KotlinAbstractUExpression -> {
|
||||
val ktElement = ((element as? PsiElementBacked)?.psi as? KtElement) ?: return false
|
||||
ktElement.analyze()[BindingContext.USED_AS_EXPRESSION, ktElement] ?: false
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 KotlinConverter {
|
||||
internal fun convertPsiElement(element: PsiElement?, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
return with (requiredType) { when (element) {
|
||||
is KtParameterList -> el<UVariableDeclarationsExpression> {
|
||||
KotlinUVariableDeclarationsExpression(parent).apply {
|
||||
variables = element.parameters.mapIndexed { i, p ->
|
||||
KotlinUVariable.create(UastKotlinPsiParameter.create(p, element, parent!!, i), this)
|
||||
}
|
||||
}
|
||||
}
|
||||
is KtClassBody -> KotlinUExpressionList(element, KotlinSpecialExpressionKinds.CLASS_BODY, parent).apply {
|
||||
expressions = emptyList()
|
||||
}
|
||||
is KtCatchClause -> el<UCatchClause> { KotlinUCatchClause(element, parent) }
|
||||
is KtExpression -> KotlinConverter.convertExpression(element, parent, requiredType)
|
||||
else -> {
|
||||
if (element is LeafPsiElement && element.elementType == KtTokens.IDENTIFIER) {
|
||||
el<UIdentifier> { UIdentifier(element, parent) }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
private fun convertVariablesDeclaration(
|
||||
psi: KtVariableDeclaration,
|
||||
parent: UElement?
|
||||
): UVariableDeclarationsExpression {
|
||||
val parentPsiElement = (parent as? PsiElementBacked)?.psi
|
||||
val variable = KotlinUVariable.create(UastKotlinPsiVariable.create(psi, parentPsiElement, parent!!), parent)
|
||||
return KotlinUVariableDeclarationsExpression(parent).apply { variables = listOf(variable) }
|
||||
}
|
||||
|
||||
private fun convertStringTemplateExpression(
|
||||
expression: KtStringTemplateExpression,
|
||||
parent: UElement?,
|
||||
i: Int
|
||||
): UExpression {
|
||||
return if (i == 1) KotlinStringTemplateUBinaryExpression(expression, parent).apply {
|
||||
leftOperand = convert(expression.entries[0], this)
|
||||
rightOperand = convert(expression.entries[1], this)
|
||||
} else KotlinStringTemplateUBinaryExpression(expression, parent).apply {
|
||||
leftOperand = convertStringTemplateExpression(expression, parent, i - 1)
|
||||
rightOperand = convert(expression.entries[i], this)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convert(entry: KtStringTemplateEntry, parent: UElement?): UExpression = when (entry) {
|
||||
is KtStringTemplateEntryWithExpression -> convertOrEmpty(entry.expression, parent)
|
||||
is KtEscapeStringTemplateEntry -> KotlinStringULiteralExpression(entry, parent, entry.unescapedValue)
|
||||
else -> {
|
||||
KotlinStringULiteralExpression(entry, parent)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convertExpression(expression: KtExpression, parent: UElement?, requiredType: Class<out UElement>? = null): UExpression {
|
||||
return with (requiredType) { when (expression) {
|
||||
is KtVariableDeclaration -> expr<UVariableDeclarationsExpression> { convertVariablesDeclaration(expression, parent) }
|
||||
|
||||
is KtStringTemplateExpression -> expr<ULiteralExpression> {
|
||||
if (expression.entries.isEmpty())
|
||||
KotlinStringULiteralExpression(expression, parent, "")
|
||||
else if (expression.entries.size == 1)
|
||||
convert(expression.entries[0], parent)
|
||||
else
|
||||
convertStringTemplateExpression(expression, parent, expression.entries.size - 1)
|
||||
}
|
||||
is KtDestructuringDeclaration -> expr<UVariableDeclarationsExpression> {
|
||||
KotlinUVariableDeclarationsExpression(parent).apply {
|
||||
val tempAssignment = KotlinUVariable.create(UastKotlinPsiVariable.create(expression, parent!!), parent)
|
||||
val destructuringAssignments = expression.entries.mapIndexed { i, entry ->
|
||||
val psiFactory = KtPsiFactory(expression.project)
|
||||
val initializer = psiFactory.createExpression("${tempAssignment.name}.component${i + 1}()")
|
||||
KotlinUVariable.create(UastKotlinPsiVariable.create(
|
||||
entry, tempAssignment.psi, parent, initializer), parent)
|
||||
}
|
||||
variables = listOf(tempAssignment) + destructuringAssignments
|
||||
}
|
||||
}
|
||||
is KtLabeledExpression -> expr<ULabeledExpression> { KotlinULabeledExpression(expression, parent) }
|
||||
is KtClassLiteralExpression -> expr<UClassLiteralExpression> { KotlinUClassLiteralExpression(expression, parent) }
|
||||
is KtObjectLiteralExpression -> expr<UObjectLiteralExpression> { KotlinUObjectLiteralExpression(expression, parent) }
|
||||
is KtStringTemplateEntry -> expression.expression?.let { convertExpression(it, parent, requiredType) } ?: UastEmptyExpression
|
||||
is KtDotQualifiedExpression -> expr<UQualifiedReferenceExpression> { KotlinUQualifiedReferenceExpression(expression, parent) }
|
||||
is KtSafeQualifiedExpression -> expr<UQualifiedReferenceExpression> { KotlinUSafeQualifiedExpression(expression, parent) }
|
||||
is KtSimpleNameExpression -> expr<USimpleNameReferenceExpression> {
|
||||
KotlinUSimpleReferenceExpression(expression, expression.getReferencedName(), parent)
|
||||
}
|
||||
is KtCallExpression -> expr<UCallExpression> { KotlinUFunctionCallExpression(expression, parent) }
|
||||
is KtBinaryExpression -> expr<UBinaryExpression> { KotlinUBinaryExpression(expression, parent) }
|
||||
is KtParenthesizedExpression -> expr<UParenthesizedExpression> { KotlinUParenthesizedExpression(expression, parent) }
|
||||
is KtPrefixExpression -> expr<UPrefixExpression> { KotlinUPrefixExpression(expression, parent) }
|
||||
is KtPostfixExpression -> expr<UPostfixExpression> { KotlinUPostfixExpression(expression, parent) }
|
||||
is KtThisExpression -> expr<UThisExpression> { KotlinUThisExpression(expression, parent) }
|
||||
is KtSuperExpression -> expr<USuperExpression> { KotlinUSuperExpression(expression, parent) }
|
||||
is KtCallableReferenceExpression -> expr<UCallableReferenceExpression> { KotlinUCallableReferenceExpression(expression, parent) }
|
||||
is KtIsExpression -> expr<UBinaryExpressionWithType> { KotlinUTypeCheckExpression(expression, parent) }
|
||||
is KtIfExpression -> expr<UIfExpression> { KotlinUIfExpression(expression, parent) }
|
||||
is KtWhileExpression -> expr<UWhileExpression> { KotlinUWhileExpression(expression, parent) }
|
||||
is KtDoWhileExpression -> expr<UDoWhileExpression> { KotlinUDoWhileExpression(expression, parent) }
|
||||
is KtForExpression -> expr<UForEachExpression> { KotlinUForEachExpression(expression, parent) }
|
||||
is KtWhenExpression -> expr<USwitchExpression> { KotlinUSwitchExpression(expression, parent) }
|
||||
is KtBreakExpression -> expr<UBreakExpression> { KotlinUBreakExpression(expression, parent) }
|
||||
is KtContinueExpression -> expr<UContinueExpression> { KotlinUContinueExpression(expression, parent) }
|
||||
is KtReturnExpression -> expr<UReturnExpression> { KotlinUReturnExpression(expression, parent) }
|
||||
is KtThrowExpression -> expr<UThrowExpression> { KotlinUThrowExpression(expression, parent) }
|
||||
is KtBlockExpression -> expr<UBlockExpression> { KotlinUBlockExpression(expression, parent) }
|
||||
is KtConstantExpression -> expr<ULiteralExpression> { KotlinULiteralExpression(expression, parent) }
|
||||
is KtTryExpression -> expr<UTryExpression> { KotlinUTryExpression(expression, parent) }
|
||||
is KtArrayAccessExpression -> expr<UArrayAccessExpression> { KotlinUArrayAccessExpression(expression, parent) }
|
||||
is KtLambdaExpression -> expr<ULambdaExpression> { KotlinULambdaExpression(expression, parent) }
|
||||
is KtBinaryExpressionWithTypeRHS -> expr<UBinaryExpressionWithType> { KotlinUBinaryExpressionWithType(expression, parent) }
|
||||
|
||||
else -> UnknownKotlinExpression(expression, parent)
|
||||
}}
|
||||
}
|
||||
|
||||
internal fun convertOrEmpty(expression: KtExpression?, parent: UElement?): UExpression {
|
||||
return if (expression != null) convertExpression(expression, parent, null) else UastEmptyExpression
|
||||
}
|
||||
|
||||
internal fun convertOrNull(expression: KtExpression?, parent: UElement?): UExpression? {
|
||||
return if (expression != null) convertExpression(expression, parent, null) else null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiAnonymousClass
|
||||
import com.intellij.psi.PsiClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.java.AbstractJavaUClass
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
|
||||
|
||||
class KotlinUClass private constructor(
|
||||
psi: KtLightClass,
|
||||
override val containingElement: UElement?
|
||||
) : AbstractJavaUClass(), PsiClass by psi {
|
||||
val ktClass = psi.kotlinOrigin
|
||||
override val psi = unwrap<UClass, PsiClass>(psi)
|
||||
|
||||
override val uastAnchor: UElement
|
||||
get() = UIdentifier(psi.nameIdentifier, this)
|
||||
|
||||
override val uastMethods: List<UMethod> by lz {
|
||||
val primaryConstructor = ktClass?.getPrimaryConstructor()?.toLightMethods()?.firstOrNull()
|
||||
val initBlocks = ktClass?.getAnonymousInitializers() ?: emptyList()
|
||||
|
||||
psi.methods.map {
|
||||
if (it is KtLightMethod && it.isConstructor && initBlocks.isNotEmpty()
|
||||
&& (primaryConstructor == null || it == primaryConstructor)) {
|
||||
object : KotlinUMethod(it, this@KotlinUClass) {
|
||||
override val uastBody by lz {
|
||||
val initializers = ktClass?.getAnonymousInitializers() ?: return@lz UastEmptyExpression
|
||||
val containingMethod = this
|
||||
|
||||
object : UBlockExpression {
|
||||
override val containingElement: UElement?
|
||||
get() = containingMethod
|
||||
|
||||
override val expressions by lz {
|
||||
initializers.map {
|
||||
getLanguagePlugin().convertOpt<UExpression>(it.body, this) ?: UastEmptyExpression
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
getLanguagePlugin().convert<UMethod>(it, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(psi: KtLightClass, containingElement: UElement?): UClass {
|
||||
return if (psi is PsiAnonymousClass)
|
||||
KotlinUAnonymousClass(psi, containingElement)
|
||||
else
|
||||
KotlinUClass(psi, containingElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinUAnonymousClass(
|
||||
psi: PsiAnonymousClass,
|
||||
override val containingElement: UElement?
|
||||
) : AbstractJavaUClass(), UAnonymousClass, PsiAnonymousClass by psi {
|
||||
override val psi: PsiAnonymousClass = unwrap<UAnonymousClass, PsiAnonymousClass>(psi)
|
||||
|
||||
override val uastAnchor: UElement?
|
||||
get() {
|
||||
val ktClassOrObject = (psi.originalElement as? KtLightClass)?.kotlinOrigin as? KtObjectDeclaration ?: return null
|
||||
return UIdentifier(ktClassOrObject.getObjectKeyword(), this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.PsiRecursiveElementWalkingVisitor
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.uast.*
|
||||
import java.util.*
|
||||
|
||||
class KotlinUFile(override val psi: KtFile, override val languagePlugin: UastLanguagePlugin) : UFile {
|
||||
override val packageName: String
|
||||
get() = psi.packageFqName.asString()
|
||||
|
||||
override val allCommentsInFile by lz {
|
||||
val comments = ArrayList<UComment>(0)
|
||||
psi.accept(object : PsiRecursiveElementWalkingVisitor() {
|
||||
override fun visitComment(comment: PsiComment) {
|
||||
comments += UComment(comment, this@KotlinUFile)
|
||||
}
|
||||
})
|
||||
comments
|
||||
}
|
||||
|
||||
override val imports by lz { psi.importDirectives.map { KotlinUImportStatement(it, this) } }
|
||||
override val classes by lz { psi.classes.map { languagePlugin.convert<UClass>(it, this) } }
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UImportStatement
|
||||
import org.jetbrains.uast.USimpleNameReferenceExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUImportStatement(
|
||||
override val psi: KtImportDirective,
|
||||
override val containingElement: UElement?
|
||||
) : UImportStatement {
|
||||
override val isOnDemand: Boolean
|
||||
get() = psi.isAllUnder
|
||||
|
||||
private val importRef by lz { psi.importedReference?.let { ImportReference(it, psi.name ?: psi.text, this) } }
|
||||
|
||||
override val importReference: UElement?
|
||||
get() = importRef
|
||||
|
||||
override fun resolve() = importRef?.resolve()
|
||||
|
||||
private class ImportReference(
|
||||
override val psi: KtExpression,
|
||||
override val identifier: String,
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), USimpleNameReferenceExpression, PsiElementBacked {
|
||||
override val resolvedName: String?
|
||||
get() = identifier
|
||||
|
||||
override fun resolve() = psi.getQualifiedElementSelector()?.mainReference?.resolve()?.getMaybeLightElement(this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin.declarations
|
||||
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.java.JavaUMethod
|
||||
import org.jetbrains.uast.kotlin.lz
|
||||
import org.jetbrains.uast.kotlin.unwrap
|
||||
|
||||
open class KotlinUMethod(
|
||||
psi: KtLightMethod,
|
||||
containingElement: UElement?
|
||||
) : JavaUMethod(psi, containingElement) {
|
||||
override val psi: KtLightMethod = unwrap<UMethod, KtLightMethod>(psi)
|
||||
private val kotlinOrigin = (psi.originalElement as KtLightElement<*, *>).kotlinOrigin
|
||||
|
||||
override val uastBody by lz {
|
||||
val bodyExpression = (kotlinOrigin as? KtFunction)?.bodyExpression ?: return@lz null
|
||||
getLanguagePlugin().convertElement(bodyExpression, this) as? UExpression
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(psi: KtLightMethod, containingElement: UElement?) = when (psi) {
|
||||
is KtLightMethodImpl.KtLightAnnotationMethod -> KotlinUAnnotationMethod(psi, containingElement)
|
||||
else -> KotlinUMethod(psi, containingElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinUAnnotationMethod(
|
||||
override val psi: KtLightMethodImpl.KtLightAnnotationMethod,
|
||||
containingElement: UElement?
|
||||
) : KotlinUMethod(psi, containingElement), UAnnotationMethod {
|
||||
override val uastDefaultValue by lz {
|
||||
val annotationParameter = psi.kotlinOrigin as? KtParameter ?: return@lz null
|
||||
val defaultValue = annotationParameter.defaultValue ?: return@lz null
|
||||
getLanguagePlugin().convertElement(defaultValue, this) as? UExpression
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.psi.KtVariableDeclaration
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.expressions.UReferenceExpression
|
||||
import org.jetbrains.uast.expressions.UTypeReferenceExpression
|
||||
import org.jetbrains.uast.java.AbstractJavaUVariable
|
||||
import org.jetbrains.uast.java.JavaAbstractUExpression
|
||||
import org.jetbrains.uast.java.annotations
|
||||
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
|
||||
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
abstract class AbstractKotlinUVariable : AbstractJavaUVariable() {
|
||||
override val uastInitializer: UExpression?
|
||||
get() {
|
||||
val psi = psi
|
||||
val initializerExpression = when (psi) {
|
||||
is UastKotlinPsiVariable -> psi.ktInitializer
|
||||
is UastKotlinPsiParameter -> psi.ktDefaultValue
|
||||
is KtLightElement<*, *> -> (psi.kotlinOrigin as? KtVariableDeclaration)?.initializer
|
||||
else -> null
|
||||
} ?: return null
|
||||
return getLanguagePlugin().convertElement(initializerExpression, this) as? UExpression ?: UastEmptyExpression
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinUVariable(
|
||||
psi: PsiVariable,
|
||||
override val containingElement: UElement?
|
||||
) : AbstractKotlinUVariable(), UVariable, PsiVariable by psi {
|
||||
override val psi = unwrap<UVariable, PsiVariable>(psi)
|
||||
|
||||
override val uastAnnotations by lz { psi.annotations.map { SimpleUAnnotation(it, this) } }
|
||||
override val typeReference by lz { getLanguagePlugin().convertOpt<UTypeReferenceExpression>(psi.typeElement, this) }
|
||||
|
||||
companion object {
|
||||
fun create(psi: PsiVariable, containingElement: UElement?): UVariable {
|
||||
return when (psi) {
|
||||
is PsiEnumConstant -> KotlinUEnumConstant(psi, containingElement)
|
||||
is PsiLocalVariable -> KotlinULocalVariable(psi, containingElement)
|
||||
is PsiParameter -> KotlinUParameter(psi, containingElement)
|
||||
is PsiField -> KotlinUField(psi, containingElement)
|
||||
else -> KotlinUVariable(psi, containingElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class KotlinUParameter(
|
||||
psi: PsiParameter,
|
||||
override val containingElement: UElement?
|
||||
) : AbstractKotlinUVariable(), UParameter, PsiParameter by psi {
|
||||
override val psi = unwrap<UParameter, PsiParameter>(psi)
|
||||
}
|
||||
|
||||
open class KotlinUField(
|
||||
psi: PsiField,
|
||||
override val containingElement: UElement?
|
||||
) : AbstractKotlinUVariable(), UField, PsiField by psi {
|
||||
override val psi = unwrap<UField, PsiField>(psi)
|
||||
}
|
||||
|
||||
open class KotlinULocalVariable(
|
||||
psi: PsiLocalVariable,
|
||||
override val containingElement: UElement?
|
||||
) : AbstractKotlinUVariable(), ULocalVariable, PsiLocalVariable by psi {
|
||||
override val psi = unwrap<ULocalVariable, PsiLocalVariable>(psi)
|
||||
}
|
||||
|
||||
open class KotlinUEnumConstant(
|
||||
psi: PsiEnumConstant,
|
||||
override val containingElement: UElement?
|
||||
) : AbstractKotlinUVariable(), UEnumConstant, PsiEnumConstant by psi {
|
||||
override val psi = unwrap<UEnumConstant, PsiEnumConstant>(psi)
|
||||
|
||||
override val kind: UastCallKind
|
||||
get() = UastCallKind.CONSTRUCTOR_CALL
|
||||
override val receiver: UExpression?
|
||||
get() = null
|
||||
override val receiverType: PsiType?
|
||||
get() = null
|
||||
override val methodIdentifier: UIdentifier?
|
||||
get() = null
|
||||
override val classReference: UReferenceExpression?
|
||||
get() = KotlinEnumConstantClassReference(psi, this)
|
||||
override val typeArgumentCount: Int
|
||||
get() = 0
|
||||
override val typeArguments: List<PsiType>
|
||||
get() = emptyList()
|
||||
override val valueArgumentCount: Int
|
||||
get() = psi.argumentList?.expressions?.size ?: 0
|
||||
|
||||
override val valueArguments by lz {
|
||||
psi.argumentList?.expressions?.map {
|
||||
getLanguagePlugin().convertElement(it, this) as? UExpression ?: UastEmptyExpression
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
override val returnType: PsiType?
|
||||
get() = psi.type
|
||||
|
||||
override fun resolve() = psi.resolveMethod()
|
||||
|
||||
override val methodName: String?
|
||||
get() = null
|
||||
|
||||
private class KotlinEnumConstantClassReference(
|
||||
override val psi: PsiEnumConstant,
|
||||
override val containingElement: UElement?
|
||||
) : JavaAbstractUExpression(), USimpleNameReferenceExpression, PsiElementBacked {
|
||||
override fun resolve() = psi.containingClass
|
||||
override val resolvedName: String?
|
||||
get() = psi.containingClass?.name
|
||||
override val identifier: String
|
||||
get() = psi.containingClass?.name ?: "<error>"
|
||||
}
|
||||
}
|
||||
+9
-7
@@ -14,19 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
|
||||
import org.jetbrains.uast.UBinaryExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.UastBinaryOperator
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinStringTemplateUBinaryExpression(
|
||||
override val psi: KtStringTemplateExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UBinaryExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UBinaryExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override lateinit var leftOperand: UExpression
|
||||
internal set
|
||||
|
||||
@@ -34,4 +31,9 @@ class KotlinStringTemplateUBinaryExpression(
|
||||
internal set
|
||||
|
||||
override val operator = UastBinaryOperator.PLUS
|
||||
|
||||
override val operatorIdentifier: UIdentifier?
|
||||
get() = null
|
||||
|
||||
override fun resolveOperator() = null
|
||||
}
|
||||
+4
-4
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.uast.UArrayAccessExpression
|
||||
@@ -23,8 +23,8 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUArrayAccessExpression(
|
||||
override val psi: KtArrayAccessExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UArrayAccessExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UArrayAccessExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val receiver by lz { KotlinConverter.convertOrEmpty(psi.arrayExpression, this) }
|
||||
override val indices by lz { psi.indexExpressions.map { KotlinConverter.convert(it, this) } }
|
||||
override val indices by lz { psi.indexExpressions.map { KotlinConverter.convertExpression(it, this) } }
|
||||
}
|
||||
+41
-7
@@ -14,26 +14,44 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUBinaryExpression(
|
||||
override val psi: KtBinaryExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UBinaryExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UBinaryExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
private companion object {
|
||||
val BITWISE_OPERATORS = mapOf(
|
||||
"or" to UastBinaryOperator.BITWISE_OR,
|
||||
"and" to UastBinaryOperator.BITWISE_AND,
|
||||
"xor" to UastBinaryOperator.BITWISE_XOR
|
||||
)
|
||||
}
|
||||
|
||||
override val leftOperand by lz { KotlinConverter.convertOrEmpty(psi.left, this) }
|
||||
override val rightOperand by lz { KotlinConverter.convertOrEmpty(psi.right, this) }
|
||||
|
||||
override val operatorIdentifier: UIdentifier?
|
||||
get() = UIdentifier(psi.operationReference, this)
|
||||
|
||||
override fun resolveOperator() = psi.operationReference.resolveCallToDeclaration(context = this) as? PsiMethod
|
||||
|
||||
override val operator = when (psi.operationToken) {
|
||||
KtTokens.EQ -> UastBinaryOperator.ASSIGN
|
||||
KtTokens.PLUS -> UastBinaryOperator.PLUS
|
||||
KtTokens.MINUS -> UastBinaryOperator.MINUS
|
||||
KtTokens.MUL -> UastBinaryOperator.MULT
|
||||
KtTokens.MUL -> UastBinaryOperator.MULTIPLY
|
||||
KtTokens.DIV -> UastBinaryOperator.DIV
|
||||
KtTokens.PERC -> UastBinaryOperator.MOD
|
||||
KtTokens.OROR -> UastBinaryOperator.LOGICAL_OR
|
||||
@@ -54,14 +72,25 @@ class KotlinUBinaryExpression(
|
||||
KtTokens.IN_KEYWORD -> KotlinBinaryOperators.IN
|
||||
KtTokens.NOT_IN -> KotlinBinaryOperators.NOT_IN
|
||||
KtTokens.RANGE -> KotlinBinaryOperators.RANGE_TO
|
||||
else -> UastBinaryOperator.UNKNOWN
|
||||
else -> run { // Handle bitwise operators
|
||||
val other = UastBinaryOperator.OTHER
|
||||
val ref = psi.operationReference
|
||||
val resolvedCall = psi.operationReference.getResolvedCall(ref.analyze()) ?: return@run other
|
||||
val resultingDescriptor = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return@run other
|
||||
val applicableOperator = BITWISE_OPERATORS[resultingDescriptor.name.asString()] ?: return@run other
|
||||
|
||||
val containingClass = resultingDescriptor.containingDeclaration as? ClassDescriptor ?: return@run other
|
||||
if (containingClass.typeConstructor.supertypes.any {
|
||||
it.constructor.declarationDescriptor?.fqNameSafe?.asString() == "kotlin.Number"
|
||||
}) applicableOperator else other
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinCustomUBinaryExpression(
|
||||
override val psi: PsiElement,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UBinaryExpression, PsiElementBacked {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UBinaryExpression, PsiElementBacked {
|
||||
lateinit override var leftOperand: UExpression
|
||||
internal set
|
||||
|
||||
@@ -70,4 +99,9 @@ class KotlinCustomUBinaryExpression(
|
||||
|
||||
lateinit override var rightOperand: UExpression
|
||||
internal set
|
||||
|
||||
override val operatorIdentifier: UIdentifier?
|
||||
get() = null
|
||||
|
||||
override fun resolveOperator() = null
|
||||
}
|
||||
+22
-11
@@ -14,21 +14,32 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.UBinaryExpressionWithType
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.UastBinaryExpressionWithTypeKind
|
||||
import org.jetbrains.uast.expressions.UTypeReferenceExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUBinaryExpressionWithType(
|
||||
override val psi: KtBinaryExpressionWithTypeRHS,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UBinaryExpressionWithType, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val operand by lz { KotlinConverter.convert(psi.left, this) }
|
||||
override val type by lz { KotlinConverter.convert(psi.right, this) }
|
||||
override val typeReference by lz { psi.right?.let { KotlinConverter.convertTypeReference(it, this) } }
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UBinaryExpressionWithType, PsiElementBacked,
|
||||
KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
|
||||
override val operand by lz { KotlinConverter.convertExpression(psi.left, this) }
|
||||
override val type by lz { psi.right.toPsiType(this) }
|
||||
|
||||
override val typeReference by lz {
|
||||
psi.right?.let { KotlinUTypeReferenceExpression(it.toPsiType(this), it, this) }
|
||||
}
|
||||
|
||||
override val operationKind = when (psi.operationReference.getReferencedNameElementType()) {
|
||||
KtTokens.AS_KEYWORD -> UastBinaryExpressionWithTypeKind.TYPE_CAST
|
||||
KtTokens.AS_SAFE -> KotlinBinaryExpressionWithTypeKinds.SAFE_TYPE_CAST
|
||||
@@ -38,17 +49,17 @@ class KotlinUBinaryExpressionWithType(
|
||||
|
||||
class KotlinCustomUBinaryExpressionWithType(
|
||||
override val psi: PsiElement,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UBinaryExpressionWithType, PsiElementBacked {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UBinaryExpressionWithType, PsiElementBacked {
|
||||
lateinit override var operand: UExpression
|
||||
internal set
|
||||
|
||||
lateinit override var operationKind: UastBinaryExpressionWithTypeKind
|
||||
internal set
|
||||
|
||||
lateinit override var type: UType
|
||||
lateinit override var type: PsiType
|
||||
internal set
|
||||
|
||||
override var typeReference: UTypeReference? = null
|
||||
override var typeReference: UTypeReferenceExpression? = null
|
||||
internal set
|
||||
}
|
||||
+3
-3
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||
import org.jetbrains.uast.UBlockExpression
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUBlockExpression(
|
||||
override val psi: KtBlockExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UBlockExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UBlockExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val expressions by lz { psi.statements.map { KotlinConverter.convertOrEmpty(it, this) } }
|
||||
}
|
||||
+4
-4
@@ -14,18 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast.expressions
|
||||
package org.jetbrains.uast.kotlin.expressions
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtBreakExpression
|
||||
import org.jetbrains.kotlin.uast.KotlinAbstractUElement
|
||||
import org.jetbrains.uast.UBreakExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.kotlin.KotlinAbstractUExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUBreakExpression(
|
||||
override val psi: KtBreakExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UBreakExpression, PsiElementBacked {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UBreakExpression, PsiElementBacked {
|
||||
override val label: String?
|
||||
get() = psi.getLabelName()
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.UCallableReferenceExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUCallableReferenceExpression(
|
||||
override val psi: KtCallableReferenceExpression,
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UCallableReferenceExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val qualifierExpression: UExpression?
|
||||
get() {
|
||||
if (qualifierType != null) return null
|
||||
val receiverExpression = psi.receiverExpression ?: return null
|
||||
return KotlinConverter.convertExpression(receiverExpression, this)
|
||||
}
|
||||
|
||||
override val qualifierType by lz {
|
||||
val ktType = psi.analyze(BodyResolveMode.PARTIAL)[DOUBLE_COLON_LHS, psi.receiverExpression]?.type ?: return@lz null
|
||||
ktType.toPsiType(this, psi, boxed = true)
|
||||
}
|
||||
|
||||
override val callableName: String
|
||||
get() = psi.callableReference.getReferencedName()
|
||||
}
|
||||
+16
-13
@@ -14,28 +14,31 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtCatchClause
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.UCatchClause
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UType
|
||||
import org.jetbrains.uast.UVariable
|
||||
import org.jetbrains.uast.UParameter
|
||||
import org.jetbrains.uast.expressions.UTypeReferenceExpression
|
||||
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUCatchClause(
|
||||
override val psi: KtCatchClause,
|
||||
override val parent: UElement
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUElement(), UCatchClause, PsiElementBacked {
|
||||
override val body by lz { KotlinConverter.convertOrEmpty(psi.catchBody, this) }
|
||||
override val parameters by lz { psi.catchParameter?.let { listOf(KotlinConverter.convert(it, this)) } ?: emptyList<UVariable>() }
|
||||
override val types by lz {
|
||||
val catchParameter = psi.catchParameter ?: return@lz emptyList<UType>()
|
||||
val bindingContext = psi.analyze(BodyResolveMode.PARTIAL)
|
||||
val parameter = bindingContext[BindingContext.VALUE_PARAMETER, catchParameter] ?: return@lz emptyList<UType>()
|
||||
listOf(KotlinConverter.convert(parameter.type, psi.project, this))
|
||||
|
||||
override val parameters by lz {
|
||||
val parameter = psi.catchParameter ?: return@lz emptyList<UParameter>()
|
||||
listOf(KotlinUParameter(UastKotlinPsiParameter.create(parameter, psi, this, 0), this))
|
||||
}
|
||||
|
||||
override val typeReferences by lz {
|
||||
val parameter = psi.catchParameter ?: return@lz emptyList<UTypeReferenceExpression>()
|
||||
val typeReference = parameter.typeReference
|
||||
val type = typeReference.toPsiType(this, boxed = true)
|
||||
listOf(KotlinUTypeReferenceExpression(type, typeReference, this))
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtClassLiteralExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.UClassLiteralExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUClassLiteralExpression(
|
||||
override val psi: KtClassLiteralExpression,
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UClassLiteralExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val type by lz {
|
||||
val ktType = psi.analyze(BodyResolveMode.PARTIAL)[DOUBLE_COLON_LHS, psi.receiverExpression]?.type ?: return@lz null
|
||||
ktType.toPsiType(this, psi, boxed = true)
|
||||
}
|
||||
|
||||
override val expression: UExpression?
|
||||
get() {
|
||||
if (type != null) return null
|
||||
val receiverExpression = psi.receiverExpression ?: return null
|
||||
return KotlinConverter.convertExpression(receiverExpression, this)
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -14,18 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast.expressions
|
||||
package org.jetbrains.uast.kotlin.expressions
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtContinueExpression
|
||||
import org.jetbrains.kotlin.uast.KotlinAbstractUElement
|
||||
import org.jetbrains.uast.UContinueExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.kotlin.KotlinAbstractUExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUContinueExpression(
|
||||
override val psi: KtContinueExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UContinueExpression, PsiElementBacked {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UContinueExpression, PsiElementBacked {
|
||||
override val label: String?
|
||||
get() = psi.getLabelName()
|
||||
}
|
||||
+10
-3
@@ -14,17 +14,24 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtDoWhileExpression
|
||||
import org.jetbrains.uast.UDoWhileExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUDoWhileExpression(
|
||||
override val psi: KtDoWhileExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UDoWhileExpression, PsiElementBacked {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UDoWhileExpression, PsiElementBacked {
|
||||
override val condition by lz { KotlinConverter.convertOrEmpty(psi.condition, this) }
|
||||
override val body by lz { KotlinConverter.convertOrEmpty(psi.body, this) }
|
||||
|
||||
override val doIdentifier: UIdentifier
|
||||
get() = UIdentifier(null, this)
|
||||
|
||||
override val whileIdentifier: UIdentifier
|
||||
get() = UIdentifier(null, this)
|
||||
}
|
||||
+7
-8
@@ -14,29 +14,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.UType
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
interface KotlinUElementWithType : UExpression, PsiElementBacked {
|
||||
override fun getExpressionType(): UType? {
|
||||
override fun getExpressionType(): PsiType? {
|
||||
val ktElement = psi as? KtExpression ?: return null
|
||||
val ktType = ktElement.analyze(BodyResolveMode.PARTIAL)[BindingContext.EXPRESSION_TYPE_INFO, ktElement]?.type ?: return null
|
||||
return KotlinConverter.convert(ktType, ktElement.project, null)
|
||||
val ktType = ktElement.analyze()[BindingContext.EXPRESSION_TYPE_INFO, ktElement]?.type ?: return null
|
||||
return ktType.toPsiType(this, ktElement, boxed = false)
|
||||
}
|
||||
}
|
||||
|
||||
interface KotlinEvaluatableUElement : UExpression, PsiElementBacked {
|
||||
override fun evaluate(): Any? {
|
||||
val ktElement = psi as? KtExpression ?: return null
|
||||
val compileTimeConst = ktElement.analyze(BodyResolveMode.PARTIAL)[BindingContext.COMPILE_TIME_VALUE, ktElement]
|
||||
|
||||
val compileTimeConst = ktElement.analyze()[BindingContext.COMPILE_TIME_VALUE, ktElement]
|
||||
return compileTimeConst?.getValue(TypeUtils.NO_EXPECTED_TYPE)
|
||||
}
|
||||
}
|
||||
+6
-13
@@ -14,36 +14,29 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.USpecialExpressionList
|
||||
import org.jetbrains.uast.UExpressionList
|
||||
import org.jetbrains.uast.UastSpecialExpressionKind
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
open class KotlinUSpecialExpressionList(
|
||||
open class KotlinUExpressionList(
|
||||
override val psi: PsiElement?,
|
||||
override val kind: UastSpecialExpressionKind, // original element
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), USpecialExpressionList, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
class Empty(psi: PsiElement, expressionType: UastSpecialExpressionKind, parent: UElement) :
|
||||
KotlinUSpecialExpressionList(psi, expressionType, parent) {
|
||||
init { expressions = emptyList() }
|
||||
}
|
||||
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UExpressionList, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override lateinit var expressions: List<UExpression>
|
||||
internal set
|
||||
|
||||
override fun evaluate(): Any? {
|
||||
val ktElement = psi as? KtExpression ?: return null
|
||||
val compileTimeConst = ktElement.analyze(BodyResolveMode.PARTIAL)[BindingContext.COMPILE_TIME_VALUE, ktElement]
|
||||
val compileTimeConst = ktElement.analyze()[BindingContext.COMPILE_TIME_VALUE, ktElement]
|
||||
return compileTimeConst?.getValue(TypeUtils.NO_EXPECTED_TYPE)
|
||||
}
|
||||
}
|
||||
+18
-5
@@ -14,17 +14,30 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UForEachExpression
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
import org.jetbrains.uast.psi.UastPsiParameterNotResolved
|
||||
|
||||
class KotlinUForEachExpression(
|
||||
override val psi: KtForExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UForEachExpression, PsiElementBacked {
|
||||
override val variable by lz { psi.loopParameter?.let { KotlinConverter.convert(it, this) } ?: UVariableNotResolved }
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UForEachExpression, PsiElementBacked {
|
||||
override val iteratedValue by lz { KotlinConverter.convertOrEmpty(psi.loopRange, this) }
|
||||
override val body by lz { KotlinConverter.convertOrEmpty(psi.body, this) }
|
||||
|
||||
override val variable by lz {
|
||||
val parameter = psi.loopParameter?.let { UastKotlinPsiParameter.create(it, psi, this, 0) }
|
||||
?: UastPsiParameterNotResolved(psi, KotlinLanguage.INSTANCE)
|
||||
KotlinUParameter(parameter, this)
|
||||
}
|
||||
|
||||
override val forIdentifier: UIdentifier
|
||||
get() = UIdentifier(null, this)
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.internal.acceptList
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
class KotlinUFunctionCallExpression(
|
||||
override val psi: KtCallExpression,
|
||||
override val containingElement: UElement?,
|
||||
private val _resolvedCall: ResolvedCall<*>? = null
|
||||
) : KotlinAbstractUExpression(), UCallExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
companion object {
|
||||
fun resolveSource(descriptor: DeclarationDescriptor, source: PsiElement?): PsiMethod? {
|
||||
if (descriptor is ConstructorDescriptor && descriptor.isPrimary
|
||||
&& source is KtClassOrObject && source.getPrimaryConstructor() == null
|
||||
&& source.getSecondaryConstructors().isEmpty()) {
|
||||
return source.toLightClass()?.constructors?.firstOrNull()
|
||||
}
|
||||
|
||||
return when (source) {
|
||||
is KtFunction -> LightClassUtil.getLightClassMethod(source)
|
||||
is PsiMethod -> source
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val resolvedCall by lz {
|
||||
_resolvedCall ?: psi.getResolvedCall(psi.analyze())
|
||||
}
|
||||
|
||||
override val receiverType by lz {
|
||||
val resolvedCall = this.resolvedCall ?: return@lz null
|
||||
val receiver = resolvedCall.dispatchReceiver ?: resolvedCall.extensionReceiver ?: return@lz null
|
||||
receiver.type.toPsiType(this, psi, boxed = true)
|
||||
}
|
||||
|
||||
override val methodName by lz { resolvedCall?.resultingDescriptor?.name?.asString() }
|
||||
|
||||
override val classReference by lz {
|
||||
KotlinClassViaConstructorUSimpleReferenceExpression(psi, methodName.orAnonymous("class"), this)
|
||||
}
|
||||
|
||||
override val methodIdentifier by lz {
|
||||
val calleeExpression = psi.calleeExpression ?: return@lz null
|
||||
UIdentifier(calleeExpression, this)
|
||||
}
|
||||
|
||||
override val valueArgumentCount: Int
|
||||
get() = psi.valueArguments.size
|
||||
|
||||
override val valueArguments by lz { psi.valueArguments.map { KotlinConverter.convertOrEmpty(it.getArgumentExpression(), this) } }
|
||||
|
||||
override val typeArgumentCount: Int
|
||||
get() = psi.typeArguments.size
|
||||
|
||||
override val typeArguments by lz { psi.typeArguments.map { it.typeReference.toPsiType(this, boxed = true) } }
|
||||
|
||||
override val returnType: PsiType?
|
||||
get() = getExpressionType()
|
||||
|
||||
override val kind by lz {
|
||||
when (resolvedCall?.resultingDescriptor) {
|
||||
is ConstructorDescriptor -> UastCallKind.CONSTRUCTOR_CALL
|
||||
else -> UastCallKind.METHOD_CALL
|
||||
}
|
||||
}
|
||||
|
||||
override val receiver: UExpression?
|
||||
get() {
|
||||
return if (containingElement is UQualifiedReferenceExpression && containingElement.selector == this)
|
||||
containingElement.receiver
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
override fun resolve(): PsiMethod? {
|
||||
val descriptor = resolvedCall?.resultingDescriptor ?: return null
|
||||
val source = descriptor.toSource() ?: return null
|
||||
return resolveSource(descriptor, source)
|
||||
}
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitCallExpression(this)) return
|
||||
methodIdentifier?.accept(visitor)
|
||||
classReference.accept(visitor)
|
||||
valueArguments.acceptList(visitor)
|
||||
|
||||
visitor.afterVisitCallExpression(this)
|
||||
}
|
||||
}
|
||||
+12
-5
@@ -14,19 +14,26 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtIfExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.UIfExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUIfExpression(
|
||||
override val psi: KtIfExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UIfExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UIfExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val condition by lz { KotlinConverter.convertOrEmpty(psi.condition, this) }
|
||||
override val thenBranch by lz { KotlinConverter.convertOrNull(psi.then, this) }
|
||||
override val elseBranch by lz { KotlinConverter.convertOrNull(psi.`else`, this) }
|
||||
override val thenExpression by lz { KotlinConverter.convertOrNull(psi.then, this) }
|
||||
override val elseExpression by lz { KotlinConverter.convertOrNull(psi.`else`, this) }
|
||||
override val isTernary = false
|
||||
|
||||
override val ifIdentifier: UIdentifier
|
||||
get() = UIdentifier(null, this)
|
||||
|
||||
override val elseIdentifier: UIdentifier?
|
||||
get() = null
|
||||
}
|
||||
+3
-3
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtLabeledExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
@@ -23,8 +23,8 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinULabeledExpression(
|
||||
override val psi: KtLabeledExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), ULabeledExpression, PsiElementBacked {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), ULabeledExpression, PsiElementBacked {
|
||||
override val label: String
|
||||
get() = psi.getLabelName().orAnonymous("label")
|
||||
|
||||
+19
-9
@@ -14,25 +14,35 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.uast.UBlockExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.ULambdaExpression
|
||||
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
import org.jetbrains.uast.withMargin
|
||||
|
||||
class KotlinULambdaExpression(
|
||||
override val psi: KtLambdaExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), ULambdaExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), ULambdaExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) }
|
||||
override val valueParameters by lz { psi.valueParameters.map { KotlinConverter.convert(it, this) } }
|
||||
override fun renderString(): String {
|
||||
|
||||
override val valueParameters by lz {
|
||||
psi.valueParameters.mapIndexed { i, p ->
|
||||
KotlinUParameter(UastKotlinPsiParameter.create(p, psi, this, i), this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun asRenderString(): String {
|
||||
val renderedValueParameters = if (valueParameters.isEmpty())
|
||||
""
|
||||
else
|
||||
valueParameters.joinToString { it.renderString() } + " ->\n"
|
||||
valueParameters.joinToString { it.asRenderString() } + " ->\n"
|
||||
val expressions = (body as? UBlockExpression)?.expressions
|
||||
?.joinToString("\n") { it.renderString().withMargin } ?: body.renderString()
|
||||
?.joinToString("\n") { it.asRenderString().withMargin } ?: body.asRenderString()
|
||||
|
||||
return "{ " + renderedValueParameters + "\n" + expressions + "\n}"
|
||||
}
|
||||
+7
-7
@@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isNullExpression
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.psi.KtConstantExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.ULiteralExpression
|
||||
@@ -26,19 +26,19 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinULiteralExpression(
|
||||
override val psi: KtConstantExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), ULiteralExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), ULiteralExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val isNull: Boolean
|
||||
get() = psi.isNullExpression()
|
||||
get() = psi.unwrapBlockOrParenthesis().node?.elementType == KtNodeTypes.NULL
|
||||
|
||||
override val value by lz { evaluate() }
|
||||
}
|
||||
|
||||
class KotlinStringULiteralExpression(
|
||||
override val psi: PsiElement,
|
||||
override val parent: UElement,
|
||||
override val containingElement: UElement?,
|
||||
val text: String? = null
|
||||
) : KotlinAbstractUElement(), ULiteralExpression, PsiElementBacked, KotlinUElementWithType{
|
||||
) : KotlinAbstractUExpression(), ULiteralExpression, PsiElementBacked, KotlinUElementWithType{
|
||||
override val value: String
|
||||
get() = text ?: StringUtil.unescapeStringCharacters(psi.text)
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.expressions.UReferenceExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUObjectLiteralExpression(
|
||||
override val psi: KtObjectLiteralExpression,
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UObjectLiteralExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val declaration by lz { getLanguagePlugin().convert<UClass>(psi.objectDeclaration.toLightClass()!!, this) }
|
||||
|
||||
override fun getExpressionType() = psi.objectDeclaration.toPsiType()
|
||||
|
||||
private val superClassConstructorCall by lz {
|
||||
psi.objectDeclaration.getSuperTypeListEntries().firstOrNull { it is KtSuperTypeCallEntry } as? KtSuperTypeCallEntry
|
||||
}
|
||||
|
||||
override val classReference: UReferenceExpression? by lz { superClassConstructorCall?.let { ObjectLiteralClassReference(it, this) } }
|
||||
|
||||
override val valueArgumentCount: Int
|
||||
get() = superClassConstructorCall?.valueArguments?.size ?: 0
|
||||
|
||||
override val valueArguments by lz {
|
||||
val psi = superClassConstructorCall ?: return@lz emptyList<UExpression>()
|
||||
psi.valueArguments.map { KotlinConverter.convertOrEmpty(it.getArgumentExpression(), this) }
|
||||
}
|
||||
|
||||
override val typeArgumentCount: Int
|
||||
get() = superClassConstructorCall?.typeArguments?.size ?: 0
|
||||
|
||||
override val typeArguments by lz {
|
||||
val psi = superClassConstructorCall ?: return@lz emptyList<PsiType>()
|
||||
psi.typeArguments.map { it.typeReference.toPsiType(this, boxed = true) }
|
||||
}
|
||||
|
||||
override fun resolve() = superClassConstructorCall?.resolveCallToDeclaration(this) as? PsiMethod
|
||||
|
||||
private class ObjectLiteralClassReference(
|
||||
override val psi: KtSuperTypeCallEntry,
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUElement(), USimpleNameReferenceExpression, PsiElementBacked {
|
||||
override fun resolve() = (psi.resolveCallToDeclaration(this) as? PsiMethod)?.containingClass
|
||||
|
||||
override val resolvedName: String?
|
||||
get() = identifier
|
||||
|
||||
override val identifier: String
|
||||
get() = psi.name ?: "<error>"
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtParenthesizedExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUParenthesizedExpression(
|
||||
override val psi: KtParenthesizedExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UParenthesizedExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UParenthesizedExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val expression by lz { KotlinConverter.convertOrEmpty(psi.expression, this) }
|
||||
}
|
||||
+15
-6
@@ -14,19 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtPostfixExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UPostfixExpression
|
||||
import org.jetbrains.uast.UastPostfixOperator
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUPostfixExpression(
|
||||
override val psi: KtPostfixExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UPostfixExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UPostfixExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement, UResolvable {
|
||||
override val operand by lz { KotlinConverter.convertOrEmpty(psi.baseExpression, this) }
|
||||
|
||||
override val operator = when (psi.operationToken) {
|
||||
@@ -35,4 +34,14 @@ class KotlinUPostfixExpression(
|
||||
KtTokens.EXCLEXCL -> KotlinPostfixOperators.EXCLEXCL
|
||||
else -> UastPostfixOperator.UNKNOWN
|
||||
}
|
||||
|
||||
override val operatorIdentifier: UIdentifier?
|
||||
get() = UIdentifier(psi.operationReference, this)
|
||||
|
||||
override fun resolveOperator() = psi.operationReference.resolveCallToDeclaration(context = this) as? PsiMethod
|
||||
|
||||
override fun resolve(): PsiMethod? = when (psi.operationToken) {
|
||||
KtTokens.EXCLEXCL -> operand.tryResolve() as? PsiMethod
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
+10
-3
@@ -14,21 +14,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtPrefixExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.UPrefixExpression
|
||||
import org.jetbrains.uast.UastPrefixOperator
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUPrefixExpression(
|
||||
override val psi: KtPrefixExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UPrefixExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UPrefixExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val operand by lz { KotlinConverter.convertOrEmpty(psi.baseExpression, this) }
|
||||
|
||||
override val operatorIdentifier: UIdentifier?
|
||||
get() = UIdentifier(psi.operationReference, this)
|
||||
|
||||
override fun resolveOperator() = psi.operationReference.resolveCallToDeclaration(context = this) as? PsiMethod
|
||||
|
||||
override val operator = when (psi.operationToken) {
|
||||
KtTokens.EXCL -> UastPrefixOperator.LOGICAL_NOT
|
||||
KtTokens.PLUS -> UastPrefixOperator.UNARY_PLUS
|
||||
+27
-16
@@ -14,42 +14,53 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.UQualifiedReferenceExpression
|
||||
import org.jetbrains.uast.UastQualifiedExpressionAccessType
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUQualifiedExpression(
|
||||
class KotlinUQualifiedReferenceExpression(
|
||||
override val psi: KtDotQualifiedExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UQualifiedExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UQualifiedReferenceExpression,
|
||||
PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val receiver by lz { KotlinConverter.convertOrEmpty(psi.receiverExpression, this) }
|
||||
override val selector by lz { KotlinConverter.convertOrEmpty(psi.selectorExpression, this) }
|
||||
override val accessType = UastQualifiedExpressionAccessType.SIMPLE
|
||||
|
||||
override fun resolve() = psi.selectorExpression?.resolveCallToDeclaration(this)
|
||||
|
||||
override fun resolve(context: UastContext) = psi.selectorExpression.resolveCallToUDeclaration(context)
|
||||
override val resolvedName: String?
|
||||
get() = (resolve() as? PsiNamedElement)?.name
|
||||
}
|
||||
|
||||
class KotlinUComponentQualifiedExpression(
|
||||
class KotlinUComponentQualifiedReferenceExpression(
|
||||
override val psi: KtDestructuringDeclarationEntry,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UQualifiedExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UQualifiedReferenceExpression,
|
||||
PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val accessType = UastQualifiedExpressionAccessType.SIMPLE
|
||||
|
||||
override lateinit var receiver: UExpression
|
||||
internal set
|
||||
|
||||
override lateinit var selector: UExpression
|
||||
internal set
|
||||
|
||||
override val accessType = UastQualifiedExpressionAccessType.SIMPLE
|
||||
override fun resolve(context: UastContext): UDeclaration? {
|
||||
val bindingContext = psi.analyze(BodyResolveMode.PARTIAL)
|
||||
override val resolvedName: String?
|
||||
get() = psi.analyze()[BindingContext.COMPONENT_RESOLVED_CALL, psi]?.resultingDescriptor?.name?.asString()
|
||||
|
||||
override fun resolve(): PsiElement? {
|
||||
val bindingContext = psi.analyze()
|
||||
val descriptor = bindingContext[BindingContext.COMPONENT_RESOLVED_CALL, psi]?.resultingDescriptor ?: return null
|
||||
val source = descriptor.toSource() ?: return null
|
||||
return context.convert(source) as? UDeclaration
|
||||
return descriptor.toSource()?.getMaybeLightElement(this)
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtReturnExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUReturnExpression(
|
||||
override val psi: KtReturnExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UReturnExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UReturnExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val returnExpression by lz { KotlinConverter.convertOrNull(psi.returnedExpression, this) }
|
||||
}
|
||||
+10
-6
@@ -14,21 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UQualifiedExpression
|
||||
import org.jetbrains.uast.UastContext
|
||||
import org.jetbrains.uast.UQualifiedReferenceExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUSafeQualifiedExpression(
|
||||
override val psi: KtSafeQualifiedExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UQualifiedExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UQualifiedReferenceExpression,
|
||||
PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val receiver by lz { KotlinConverter.convertOrEmpty(psi.receiverExpression, this) }
|
||||
override val selector by lz { KotlinConverter.convertOrEmpty(psi.selectorExpression, this) }
|
||||
override val accessType = KotlinQualifiedExpressionAccessTypes.SAFE
|
||||
|
||||
override fun resolve(context: UastContext) = psi.selectorExpression.resolveCallToUDeclaration(context)
|
||||
override val resolvedName: String?
|
||||
get() = (resolve() as? PsiNamedElement)?.name
|
||||
|
||||
override fun resolve() = psi.selectorExpression?.resolveCallToDeclaration(this)
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.constant
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.expressions.UReferenceExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
open class KotlinUSimpleReferenceExpression(
|
||||
override val psi: KtSimpleNameExpression,
|
||||
override val identifier: String,
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), USimpleNameReferenceExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
private val resolvedDeclaration by lz { psi.resolveCallToDeclaration(this) }
|
||||
|
||||
override fun resolve() = resolvedDeclaration
|
||||
|
||||
override val resolvedName: String?
|
||||
get() = (resolvedDeclaration as? PsiNamedElement)?.name
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
visitor.visitSimpleNameReferenceExpression(this)
|
||||
|
||||
// Visit Kotlin get-set synthetic Java property calls as function calls
|
||||
val bindingContext = psi.analyze()
|
||||
val access = psi.readWriteAccess()
|
||||
val resolvedCall = psi.getResolvedCall(bindingContext)
|
||||
val resultingDescriptor = resolvedCall?.resultingDescriptor as? SyntheticJavaPropertyDescriptor
|
||||
if (resultingDescriptor != null) {
|
||||
val setterValue = if (access.isWrite) {
|
||||
findAssignment(psi, psi.parent)?.right ?: run {
|
||||
visitor.afterVisitSimpleNameReferenceExpression(this)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
if (resolvedCall != null) {
|
||||
if (access.isRead) {
|
||||
val getDescriptor = resultingDescriptor.getMethod
|
||||
KotlinAccessorCallExpression(psi, this, resolvedCall, getDescriptor, null).accept(visitor)
|
||||
}
|
||||
|
||||
if (access.isWrite && setterValue != null) {
|
||||
val setDescriptor = resultingDescriptor.setMethod
|
||||
if (setDescriptor != null) {
|
||||
KotlinAccessorCallExpression(psi, this, resolvedCall, setDescriptor, setterValue).accept(visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visitor.afterVisitSimpleNameReferenceExpression(this)
|
||||
}
|
||||
|
||||
private tailrec fun findAssignment(prev: PsiElement?, element: PsiElement?): KtBinaryExpression? = when (element) {
|
||||
is KtBinaryExpression -> if (element.left == prev && element.operationToken == KtTokens.EQ) element else null
|
||||
is KtQualifiedExpression -> findAssignment(element, element.parent)
|
||||
is KtSimpleNameExpression -> findAssignment(element, element.parent)
|
||||
else -> null
|
||||
}
|
||||
|
||||
class KotlinAccessorCallExpression(
|
||||
override val psi: KtElement,
|
||||
override val containingElement: KotlinUSimpleReferenceExpression,
|
||||
private val resolvedCall: ResolvedCall<*>,
|
||||
private val accessorDescriptor: DeclarationDescriptor,
|
||||
val setterValue: KtExpression?
|
||||
) : UCallExpression, PsiElementBacked {
|
||||
override val methodName: String?
|
||||
get() = accessorDescriptor.name.asString()
|
||||
|
||||
override val receiver: UExpression?
|
||||
get() {
|
||||
val containingElement = containingElement.containingElement
|
||||
return if (containingElement is UQualifiedReferenceExpression && containingElement.selector == this)
|
||||
containingElement.receiver
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
override val receiverType by lz {
|
||||
val type = (resolvedCall.dispatchReceiver ?: resolvedCall.extensionReceiver)?.type ?: return@lz null
|
||||
type.toPsiType(this, psi, boxed = true)
|
||||
}
|
||||
|
||||
override val methodIdentifier: UIdentifier?
|
||||
get() = UIdentifier(containingElement.psi, this)
|
||||
|
||||
override val classReference: UReferenceExpression?
|
||||
get() = null
|
||||
|
||||
override val valueArgumentCount: Int
|
||||
get() = if (setterValue != null) 1 else 0
|
||||
|
||||
override val valueArguments by lz {
|
||||
if (setterValue != null)
|
||||
listOf(KotlinConverter.convertOrEmpty(setterValue, this))
|
||||
else
|
||||
emptyList()
|
||||
}
|
||||
|
||||
override val typeArgumentCount: Int
|
||||
get() = resolvedCall.typeArguments.size
|
||||
|
||||
override val typeArguments by lz {
|
||||
resolvedCall.typeArguments.values.map { it.toPsiType(this, psi, true) }
|
||||
}
|
||||
|
||||
override val returnType by lz {
|
||||
(accessorDescriptor as? CallableDescriptor)?.returnType?.toPsiType(this, psi, boxed = false)
|
||||
}
|
||||
|
||||
override val kind: UastCallKind
|
||||
get() = UastCallKind.METHOD_CALL
|
||||
|
||||
override fun resolve(): PsiMethod? {
|
||||
val source = accessorDescriptor.toSource()
|
||||
return KotlinUFunctionCallExpression.resolveSource(accessorDescriptor, source)
|
||||
}
|
||||
}
|
||||
|
||||
enum class ReferenceAccess(val isRead: Boolean, val isWrite: Boolean) {
|
||||
READ(true, false), WRITE(false, true), READ_WRITE(true, true)
|
||||
}
|
||||
|
||||
private fun KtExpression.readWriteAccess(): ReferenceAccess {
|
||||
var expression = getQualifiedExpressionForSelectorOrThis()
|
||||
loop@ while (true) {
|
||||
val parent = expression.parent
|
||||
when (parent) {
|
||||
is KtParenthesizedExpression, is KtAnnotatedExpression, is KtLabeledExpression -> expression = parent as KtExpression
|
||||
else -> break@loop
|
||||
}
|
||||
}
|
||||
|
||||
val assignment = expression.getAssignmentByLHS()
|
||||
if (assignment != null) {
|
||||
when (assignment.operationToken) {
|
||||
KtTokens.EQ -> return ReferenceAccess.WRITE
|
||||
else -> return ReferenceAccess.READ_WRITE
|
||||
}
|
||||
}
|
||||
|
||||
return if ((expression.parent as? KtUnaryExpression)?.operationToken
|
||||
in constant { setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) })
|
||||
ReferenceAccess.READ_WRITE
|
||||
else
|
||||
ReferenceAccess.READ
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinClassViaConstructorUSimpleReferenceExpression(
|
||||
override val psi: KtCallExpression,
|
||||
override val identifier: String,
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), USimpleNameReferenceExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val resolvedName: String?
|
||||
get() = (psi.getResolvedCall(psi.analyze())?.resultingDescriptor as? ConstructorDescriptor)
|
||||
?.containingDeclaration?.name?.asString()
|
||||
|
||||
override fun resolve(): PsiElement? {
|
||||
val resolvedCall = psi.getResolvedCall(psi.analyze())
|
||||
val resultingDescriptor = resolvedCall?.resultingDescriptor as? ConstructorDescriptor ?: return null
|
||||
val clazz = resultingDescriptor.containingDeclaration
|
||||
return clazz.toSource()?.getMaybeLightElement(this)
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinStringUSimpleReferenceExpression(
|
||||
override val identifier: String,
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), USimpleNameReferenceExpression {
|
||||
override fun resolve() = null
|
||||
override val resolvedName: String?
|
||||
get() = identifier
|
||||
}
|
||||
+3
-3
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtSuperExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
@@ -23,5 +23,5 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUSuperExpression(
|
||||
override val psi: KtSuperExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), USuperExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), USuperExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement
|
||||
+24
-21
@@ -14,40 +14,42 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.uast.kinds.KotlinSpecialExpressionKinds
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
class KotlinUSwitchExpression(
|
||||
override val psi: KtWhenExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), USwitchExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), USwitchExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val expression by lz { KotlinConverter.convertOrNull(psi.subjectExpression, this) }
|
||||
|
||||
override val body: UExpression by lz {
|
||||
object : KotlinUSpecialExpressionList(psi, KotlinSpecialExpressionKinds.WHEN, this) {
|
||||
override fun renderString() = expressions.joinToString("\n") { it.renderString().withMargin }
|
||||
object : KotlinUExpressionList(psi, KotlinSpecialExpressionKinds.WHEN, this) {
|
||||
override fun asRenderString() = expressions.joinToString("\n") { it.asRenderString().withMargin }
|
||||
}.apply {
|
||||
expressions = this@KotlinUSwitchExpression.psi.entries.map { KotlinUSwitchEntry(it, this) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun renderString() = buildString {
|
||||
val expr = expression?.let { "(" + it.renderString() + ") " } ?: ""
|
||||
override fun asRenderString() = buildString {
|
||||
val expr = expression?.let { "(" + it.asRenderString() + ") " } ?: ""
|
||||
appendln("switch $expr {")
|
||||
appendln(body.renderString())
|
||||
appendln(body.asRenderString())
|
||||
appendln("}")
|
||||
}
|
||||
|
||||
override val switchIdentifier: UIdentifier
|
||||
get() = UIdentifier(null, this)
|
||||
}
|
||||
|
||||
class KotlinUSwitchEntry(
|
||||
override val psi: KtWhenEntry,
|
||||
override val parent: UExpression
|
||||
) : KotlinAbstractUElement(), USwitchClauseExpressionWithBody, PsiElementBacked {
|
||||
override val containingElement: UExpression
|
||||
) : KotlinAbstractUExpression(), USwitchClauseExpressionWithBody, PsiElementBacked {
|
||||
override val caseValues by lz {
|
||||
psi.conditions.map { when (it) {
|
||||
is KtWhenConditionInRange -> KotlinCustomUBinaryExpression(it, this).apply {
|
||||
@@ -65,32 +67,33 @@ class KotlinUSwitchEntry(
|
||||
else -> UastBinaryExpressionWithTypeKind.INSTANCE_CHECK
|
||||
}
|
||||
val typeRef = it.typeReference
|
||||
type = KotlinConverter.convert(typeRef, this)
|
||||
typeReference = typeRef?.let { KotlinConverter.convertTypeReference(it, this) }
|
||||
val type = typeRef.toPsiType(this, boxed = true)
|
||||
this.type = type
|
||||
typeReference = typeRef?.let { KotlinUTypeReferenceExpression(type, it, this) }
|
||||
}
|
||||
is KtWhenConditionWithExpression -> KotlinConverter.convertOrEmpty(it.expression, this)
|
||||
else -> EmptyUExpression(this)
|
||||
else -> UastEmptyExpression
|
||||
}}
|
||||
}
|
||||
|
||||
override val body: UExpression by lz {
|
||||
object : KotlinUSpecialExpressionList(psi, KotlinSpecialExpressionKinds.WHEN_ENTRY, this) {
|
||||
override fun renderString() = buildString {
|
||||
object : KotlinUExpressionList(psi, KotlinSpecialExpressionKinds.WHEN_ENTRY, this) {
|
||||
override fun asRenderString() = buildString {
|
||||
appendln("{")
|
||||
expressions.forEach { appendln(it.renderString().withMargin) }
|
||||
expressions.forEach { appendln(it.asRenderString().withMargin) }
|
||||
appendln("}")
|
||||
}
|
||||
}.apply {
|
||||
val exprPsi = this@KotlinUSwitchEntry.psi.expression
|
||||
val userExpressions = when (exprPsi) {
|
||||
is KtBlockExpression -> exprPsi.statements.map { KotlinConverter.convert(it, this) }
|
||||
is KtBlockExpression -> exprPsi.statements.map { KotlinConverter.convertExpression(it, this) }
|
||||
else -> listOf(KotlinConverter.convertOrEmpty(exprPsi, this))
|
||||
}
|
||||
parent
|
||||
containingElement
|
||||
expressions = userExpressions + object : UBreakExpression {
|
||||
override val label: String?
|
||||
get() = null
|
||||
override val parent: UElement?
|
||||
override val containingElement: UElement?
|
||||
get() = this@KotlinUSwitchEntry
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtThisExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
@@ -23,5 +23,5 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUThisExpression(
|
||||
override val psi: KtThisExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UThisExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UThisExpression, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement
|
||||
+3
-3
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtThrowExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUThrowExpression(
|
||||
override val psi: KtThrowExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UThrowExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UThrowExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val thrownExpression by lz { KotlinConverter.convertOrEmpty(psi.thrownExpression, this) }
|
||||
}
|
||||
+18
-6
@@ -14,20 +14,32 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiResourceListElement
|
||||
import org.jetbrains.kotlin.psi.KtTryExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.UTryExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUTryExpression(
|
||||
override val psi: KtTryExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UTryExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val tryClause by lz { KotlinConverter.convert(psi.tryBlock, this) }
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UTryExpression, PsiElementBacked, KotlinUElementWithType {
|
||||
override val tryClause by lz { KotlinConverter.convertExpression(psi.tryBlock, this) }
|
||||
override val catchClauses by lz { psi.catchClauses.map { KotlinUCatchClause(it, this) } }
|
||||
override val finallyClause by lz { psi.finallyBlock?.finalExpression?.let { KotlinConverter.convert(it, this) } }
|
||||
override val resources: List<UElement>?
|
||||
override val finallyClause by lz { psi.finallyBlock?.finalExpression?.let { KotlinConverter.convertExpression(it, this) } }
|
||||
|
||||
override val resources: List<PsiResourceListElement>?
|
||||
get() = null
|
||||
|
||||
override val isResources: Boolean
|
||||
get() = false
|
||||
|
||||
override val tryIdentifier: UIdentifier
|
||||
get() = UIdentifier(null, this)
|
||||
|
||||
override val finallyIdentifier: UIdentifier?
|
||||
get() = null
|
||||
}
|
||||
+11
-6
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtIsExpression
|
||||
import org.jetbrains.uast.UBinaryExpressionWithType
|
||||
@@ -23,10 +23,15 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUTypeCheckExpression(
|
||||
override val psi: KtIsExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UBinaryExpressionWithType, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val operand by lz { KotlinConverter.convert(psi.leftHandSide, this) }
|
||||
override val type by lz { KotlinConverter.convert(psi.typeReference, this) }
|
||||
override val typeReference by lz { psi.typeReference?.let { KotlinConverter.convertTypeReference(it, this) } }
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UBinaryExpressionWithType, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val operand by lz { KotlinConverter.convertExpression(psi.leftHandSide, this) }
|
||||
|
||||
override val type by lz { psi.typeReference.toPsiType(this) }
|
||||
|
||||
override val typeReference by lz {
|
||||
psi.typeReference?.let { KotlinUTypeReferenceExpression(it.toPsiType(this), it, this) }
|
||||
}
|
||||
|
||||
override val operationKind = KotlinBinaryExpressionWithTypeKinds.NEGATED_INSTANCE_CHECK
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.expressions.UTypeReferenceExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
open class KotlinUTypeReferenceExpression(
|
||||
override val type: PsiType,
|
||||
override val psi: PsiElement?,
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UTypeReferenceExpression, PsiElementBacked, KotlinUElementWithType
|
||||
+5
-3
@@ -15,9 +15,11 @@
|
||||
*/
|
||||
package org.jetbrains.uast
|
||||
|
||||
import org.jetbrains.kotlin.uast.KotlinAbstractUElement
|
||||
import org.jetbrains.uast.kotlin.KotlinAbstractUExpression
|
||||
|
||||
class KotlinUDeclarationsExpression(override val parent: UElement) : KotlinAbstractUElement(), UDeclarationsExpression {
|
||||
override lateinit var declarations: List<UElement>
|
||||
class KotlinUVariableDeclarationsExpression(
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UVariableDeclarationsExpression {
|
||||
override lateinit var variables: List<UVariable>
|
||||
internal set
|
||||
}
|
||||
+7
-3
@@ -14,17 +14,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtWhileExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.UWhileExpression
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUWhileExpression(
|
||||
override val psi: KtWhileExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UWhileExpression, PsiElementBacked {
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UWhileExpression, PsiElementBacked {
|
||||
override val condition by lz { KotlinConverter.convertOrEmpty(psi.condition, this) }
|
||||
override val body by lz { KotlinConverter.convertOrEmpty(psi.body, this) }
|
||||
|
||||
override val whileIdentifier: UIdentifier
|
||||
get() = UIdentifier(null, this)
|
||||
}
|
||||
+4
-4
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class UnknownKotlinExpression(
|
||||
override val psi: KtExpression,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UExpression, PsiElementBacked {
|
||||
override fun logString() = "[!] UnknownKotlinExpression ($psi)"
|
||||
override val containingElement: UElement?
|
||||
) : KotlinAbstractUExpression(), UExpression, PsiElementBacked {
|
||||
override fun asLogString() = "[!] UnknownKotlinExpression ($psi)"
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package org.jetbrains.uast.kotlin.internal
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension
|
||||
import org.jetbrains.uast.kotlin.KotlinUastBindingContextProviderService
|
||||
|
||||
class CliKotlinUastBindingContextProviderService : KotlinUastBindingContextProviderService {
|
||||
val Project.analysisCompletedHandler: UastAnalysisCompletedHandlerExtension?
|
||||
get() = getExtensions(AnalysisCompletedHandlerExtension.extensionPointName)
|
||||
.filterIsInstance<UastAnalysisCompletedHandlerExtension>()
|
||||
.firstOrNull()
|
||||
|
||||
override fun getBindingContext(element: KtElement): BindingContext {
|
||||
return element.project.analysisCompletedHandler?.getBindingContext() ?: BindingContext.EMPTY
|
||||
}
|
||||
|
||||
override fun getTypeMapper(element: KtElement): KotlinTypeMapper? {
|
||||
return element.project.analysisCompletedHandler?.getTypeMapper()
|
||||
}
|
||||
}
|
||||
|
||||
class UastAnalysisCompletedHandlerExtension : AnalysisCompletedHandlerExtension {
|
||||
private var context: BindingContext? = null
|
||||
private var typeMapper: KotlinTypeMapper? = null
|
||||
|
||||
fun getBindingContext() = context
|
||||
|
||||
fun getTypeMapper(): KotlinTypeMapper? {
|
||||
if (typeMapper != null) return typeMapper
|
||||
val bindingContext = context ?: return null
|
||||
|
||||
val typeMapper = KotlinTypeMapper(bindingContext, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider,
|
||||
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false)
|
||||
this.typeMapper = typeMapper
|
||||
return typeMapper
|
||||
}
|
||||
|
||||
override fun analysisCompleted(
|
||||
project: Project,
|
||||
module: ModuleDescriptor,
|
||||
bindingTrace: BindingTrace,
|
||||
files: Collection<KtFile>
|
||||
): AnalysisResult? {
|
||||
context = bindingTrace.bindingContext
|
||||
return null
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin.internal
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.kotlin.KotlinUastBindingContextProviderService
|
||||
|
||||
class IdeaKotlinUastBindingContextProviderService : KotlinUastBindingContextProviderService {
|
||||
override fun getBindingContext(element: KtElement) = element.analyze(BodyResolveMode.PARTIAL)
|
||||
|
||||
override fun getTypeMapper(element: KtElement): KotlinTypeMapper? {
|
||||
return KotlinTypeMapper(getBindingContext(element),
|
||||
ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider,
|
||||
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false)
|
||||
}
|
||||
}
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiPrimitiveType
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.impl.cache.TypeInfo
|
||||
import com.intellij.psi.impl.compiled.ClsTypeElementImpl
|
||||
import com.intellij.psi.impl.compiled.SignatureParsing
|
||||
import com.intellij.psi.impl.compiled.StubBuildingVisitor
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.asJava.toLightElements
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.uast.*
|
||||
import java.lang.ref.WeakReference
|
||||
import java.text.StringCharacterIterator
|
||||
|
||||
internal val KOTLIN_CACHED_UELEMENT_KEY = Key.create<WeakReference<UElement>>("cached-kotlin-uelement")
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
internal inline fun String?.orAnonymous(kind: String = ""): String {
|
||||
return this ?: "<anonymous" + (if (kind.isNotBlank()) " $kind" else "") + ">"
|
||||
}
|
||||
|
||||
internal fun DeclarationDescriptor.toSource() = try {
|
||||
DescriptorToSourceUtils.descriptorToDeclaration(this)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
internal fun <T> lz(initializer: () -> T) = lazy(LazyThreadSafetyMode.NONE, initializer)
|
||||
|
||||
internal fun KotlinType.toPsiType(source: UElement, element: KtElement, boxed: Boolean): PsiType {
|
||||
if (this.isError) return UastErrorType
|
||||
|
||||
if (arguments.isEmpty()) {
|
||||
val typeFqName = this.constructor.declarationDescriptor?.fqNameSafe?.asString()
|
||||
fun PsiPrimitiveType.orBoxed() = if (boxed) getBoxedType(element) else this
|
||||
val psiType = when (typeFqName) {
|
||||
"kotlin.Int" -> PsiType.INT.orBoxed()
|
||||
"kotlin.Long" -> PsiType.LONG.orBoxed()
|
||||
"kotlin.Short" -> PsiType.SHORT.orBoxed()
|
||||
"kotlin.Boolean" -> PsiType.BOOLEAN.orBoxed()
|
||||
"kotlin.Byte" -> PsiType.BYTE.orBoxed()
|
||||
"kotlin.Char" -> PsiType.CHAR.orBoxed()
|
||||
"kotlin.Double" -> PsiType.DOUBLE.orBoxed()
|
||||
"kotlin.Float" -> PsiType.FLOAT.orBoxed()
|
||||
"kotlin.String" -> PsiType.getJavaLangString(element.manager, GlobalSearchScope.projectScope(element.project))
|
||||
else -> null
|
||||
}
|
||||
if (psiType != null) return psiType
|
||||
}
|
||||
|
||||
val project = element.project
|
||||
val typeMapper = ServiceManager.getService(project, KotlinUastBindingContextProviderService::class.java)
|
||||
.getTypeMapper(element) ?: return UastErrorType
|
||||
|
||||
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.TYPE)
|
||||
val typeMappingMode = if (boxed) TypeMappingMode.GENERIC_ARGUMENT else TypeMappingMode.DEFAULT
|
||||
typeMapper.mapType(this, signatureWriter, typeMappingMode)
|
||||
|
||||
val signature = StringCharacterIterator(signatureWriter.toString())
|
||||
|
||||
val javaType = SignatureParsing.parseTypeString(signature, StubBuildingVisitor.GUESSING_MAPPER)
|
||||
val typeInfo = TypeInfo.fromString(javaType, false)
|
||||
val typeText = TypeInfo.createTypeText(typeInfo) ?: return UastErrorType
|
||||
|
||||
return ClsTypeElementImpl(source.getParentOfType<UDeclaration>(false)?.psi ?: element, typeText, '\u0000').type
|
||||
}
|
||||
|
||||
internal fun KtTypeReference?.toPsiType(source: UElement, boxed: Boolean = false): PsiType {
|
||||
if (this == null) return UastErrorType
|
||||
return (analyze()[BindingContext.TYPE, this] ?: return UastErrorType).toPsiType(source, this, boxed)
|
||||
}
|
||||
|
||||
internal fun KtClassOrObject.toPsiType(): PsiType {
|
||||
val lightClass = toLightClass() ?: return UastErrorType
|
||||
return PsiTypesUtil.getClassType(lightClass)
|
||||
}
|
||||
|
||||
internal fun PsiElement.getMaybeLightElement(context: UElement): PsiElement? {
|
||||
return when (this) {
|
||||
is KtVariableDeclaration -> {
|
||||
val lightElement = toLightElements().firstOrNull()
|
||||
if (lightElement != null) return lightElement
|
||||
|
||||
val languagePlugin = context.getLanguagePlugin()
|
||||
val uElement = languagePlugin.convertElementWithParent(this, null)
|
||||
when (uElement) {
|
||||
is UDeclaration -> uElement.psi
|
||||
is UVariableDeclarationsExpression -> uElement.variables.firstOrNull()?.psi
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
is KtDeclaration -> toLightElements().firstOrNull()
|
||||
is KtElement -> null
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
internal fun KtElement.resolveCallToDeclaration(
|
||||
context: KotlinAbstractUElement,
|
||||
resultingDescriptor: DeclarationDescriptor? = null
|
||||
): PsiElement? {
|
||||
val descriptor = resultingDescriptor ?: run {
|
||||
val resolvedCall = getResolvedCall(analyze()) ?: return null
|
||||
resolvedCall.resultingDescriptor
|
||||
}
|
||||
|
||||
return descriptor.toSource()?.getMaybeLightElement(context)
|
||||
}
|
||||
|
||||
internal fun KtExpression.unwrapBlockOrParenthesis(): KtExpression {
|
||||
val innerExpression = KtPsiUtil.safeDeparenthesize(this)
|
||||
if (innerExpression is KtBlockExpression) {
|
||||
val statement = innerExpression.statements.singleOrNull() ?: return this
|
||||
return KtPsiUtil.safeDeparenthesize(statement)
|
||||
}
|
||||
return innerExpression
|
||||
}
|
||||
|
||||
internal fun KtElement.analyze(): BindingContext {
|
||||
return ServiceManager.getService(project, KotlinUastBindingContextProviderService::class.java)
|
||||
?.getBindingContext(this) ?: BindingContext.EMPTY
|
||||
}
|
||||
|
||||
internal inline fun <reified T : UDeclaration, reified P : PsiElement> unwrap(element: P): P {
|
||||
val unwrapped = if (element is T) element.psi else element
|
||||
assert(unwrapped !is UElement)
|
||||
return unwrapped as P
|
||||
}
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.uast.UastBinaryExpressionWithTypeKind
|
||||
|
||||
+2
-1
@@ -14,13 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.uast.UastBinaryOperator
|
||||
|
||||
object KotlinBinaryOperators {
|
||||
@JvmField
|
||||
val IN = UastBinaryOperator("in")
|
||||
|
||||
@JvmField
|
||||
val NOT_IN = UastBinaryOperator("!in")
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.uast.UastPostfixOperator
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.uast.UastQualifiedExpressionAccessType
|
||||
|
||||
+1
-4
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast.kinds
|
||||
package org.jetbrains.uast.kotlin.kinds
|
||||
|
||||
import org.jetbrains.uast.UastSpecialExpressionKind
|
||||
|
||||
@@ -27,7 +27,4 @@ object KotlinSpecialExpressionKinds {
|
||||
|
||||
@JvmField
|
||||
val CLASS_BODY = UastSpecialExpressionKind("class_body")
|
||||
|
||||
@JvmField
|
||||
val VARARG = UastSpecialExpressionKind("vararg")
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.jetbrains.uast.kotlin.psi
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiParameter
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.impl.light.LightParameter
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.uast.UDeclaration
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UastErrorType
|
||||
import org.jetbrains.uast.getParentOfType
|
||||
import org.jetbrains.uast.kotlin.analyze
|
||||
import org.jetbrains.uast.kotlin.toPsiType
|
||||
|
||||
class UastKotlinPsiParameter(
|
||||
name: String,
|
||||
type: PsiType,
|
||||
parent: PsiElement,
|
||||
language: Language,
|
||||
isVarArgs: Boolean,
|
||||
val ktDefaultValue: KtExpression?,
|
||||
val ktParameter: KtParameter
|
||||
) : LightParameter(name, type, parent, language, isVarArgs) {
|
||||
companion object {
|
||||
fun create(parameter: KtParameter, parent: PsiElement, containingElement: UElement, index: Int): PsiParameter {
|
||||
val psiParent = containingElement.getParentOfType<UDeclaration>()?.psi ?: parent
|
||||
return UastKotlinPsiParameter(
|
||||
parameter.name ?: "p$index",
|
||||
(parameter.analyze()[BindingContext.DECLARATION_TO_DESCRIPTOR, parameter] as? VariableDescriptor)
|
||||
?.type?.toPsiType(containingElement, parameter, boxed = false) ?: UastErrorType,
|
||||
psiParent,
|
||||
KotlinLanguage.INSTANCE,
|
||||
parameter.isVarArg,
|
||||
parameter.defaultValue,
|
||||
parameter)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getContainingFile(): PsiFile? = ktParameter.containingFile
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
return ktParameter == (other as? UastKotlinPsiParameter)?.ktParameter
|
||||
}
|
||||
|
||||
override fun hashCode() = ktParameter.hashCode()
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.jetbrains.uast.kotlin.psi
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.asJava.elements.LightVariableBuilder
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtVariableDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.uast.UDeclaration
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UastErrorType
|
||||
import org.jetbrains.uast.getParentOfType
|
||||
import org.jetbrains.uast.kotlin.analyze
|
||||
import org.jetbrains.uast.kotlin.orAnonymous
|
||||
import org.jetbrains.uast.kotlin.toPsiType
|
||||
|
||||
class UastKotlinPsiVariable(
|
||||
manager: PsiManager,
|
||||
name: String,
|
||||
type: PsiType,
|
||||
language: Language,
|
||||
val ktInitializer: KtExpression?,
|
||||
val psiParent: PsiElement?,
|
||||
val containingElement: UElement,
|
||||
val ktElement: KtElement
|
||||
) : LightVariableBuilder(manager, name, type, language), PsiLocalVariable {
|
||||
override fun getParent() = psiParent
|
||||
|
||||
override fun hasInitializer() = ktInitializer != null
|
||||
override fun getInitializer(): PsiExpression? = ktInitializer?.let { KotlinUastPsiExpression(it, containingElement) }
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
return ktElement == (other as? UastKotlinPsiVariable)?.ktElement
|
||||
}
|
||||
|
||||
override fun getTypeElement() = throw NotImplementedError()
|
||||
override fun setInitializer(initializer: PsiExpression?) = throw NotImplementedError()
|
||||
|
||||
override fun getContainingFile(): PsiFile? = ktElement.containingFile
|
||||
|
||||
override fun hashCode() = ktElement.hashCode()
|
||||
|
||||
companion object {
|
||||
fun create(
|
||||
declaration: KtVariableDeclaration,
|
||||
parent: PsiElement?,
|
||||
containingElement: UElement,
|
||||
initializer: KtExpression? = null
|
||||
): PsiVariable {
|
||||
val psiParent = containingElement.getParentOfType<UDeclaration>()?.psi ?: parent
|
||||
return UastKotlinPsiVariable(
|
||||
declaration.manager,
|
||||
declaration.name.orAnonymous("unnamed"),
|
||||
declaration.typeReference.toPsiType(containingElement),
|
||||
KotlinLanguage.INSTANCE,
|
||||
initializer ?: declaration.initializer,
|
||||
psiParent,
|
||||
containingElement,
|
||||
declaration)
|
||||
}
|
||||
|
||||
fun create(declaration: KtDestructuringDeclaration, containingElement: UElement): PsiVariable {
|
||||
val psiParent = containingElement.getParentOfType<UDeclaration>()?.psi ?: declaration.parent
|
||||
return UastKotlinPsiVariable(
|
||||
declaration.manager,
|
||||
"var" + Integer.toHexString(declaration.hashCode()),
|
||||
UastErrorType, //TODO,
|
||||
KotlinLanguage.INSTANCE,
|
||||
declaration.initializer,
|
||||
psiParent,
|
||||
containingElement,
|
||||
declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class KotlinUastPsiExpression(val ktExpression: KtExpression, val parent: UElement) : PsiElement by ktExpression, PsiExpression {
|
||||
override fun getType(): PsiType? {
|
||||
val ktType = ktExpression.analyze()[BindingContext.EXPRESSION_TYPE_INFO, ktExpression]?.type ?: return null
|
||||
return ktType.toPsiType(parent, ktExpression, boxed = false)
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
|
||||
import org.jetbrains.android.inspections.klint.AndroidLintInspectionBase
|
||||
import org.jetbrains.kotlin.android.KotlinAndroidTestCase
|
||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes
|
||||
@@ -28,7 +27,7 @@ abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() {
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
ConfigLibraryUtil.configureKotlinRuntime(myModule)
|
||||
AndroidLintInspectionBase.invalidateInspectionShortName2IssueMap()
|
||||
// AndroidLintInspectionBase.invalidateInspectionShortName2IssueMap()
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
@@ -46,28 +45,29 @@ abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() {
|
||||
inspectionClassNames += className
|
||||
}
|
||||
|
||||
myFixture.enableInspections(*inspectionClassNames.map { className ->
|
||||
val inspectionClass = Class.forName(className)
|
||||
inspectionClass.newInstance() as AndroidLintInspectionBase
|
||||
}.toTypedArray())
|
||||
//TODO
|
||||
// myFixture.enableInspections(*inspectionClassNames.map { className ->
|
||||
// val inspectionClass = Class.forName(className)
|
||||
// inspectionClass.newInstance() as AndroidLintInspectionBase
|
||||
// }.toTypedArray())
|
||||
|
||||
val additionalResourcesDir = File(ktFile.parentFile, getTestName(true))
|
||||
if (additionalResourcesDir.exists()) {
|
||||
for (file in additionalResourcesDir.listFiles()) {
|
||||
if (file.isFile) {
|
||||
myFixture.copyFileToProject(file.absolutePath, file.name)
|
||||
}
|
||||
else if (file.isDirectory) {
|
||||
myFixture.copyDirectoryToProject(file.absolutePath, file.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val virtualFile = myFixture.copyFileToProject(ktFile.absolutePath, "src/" + getTestName(true) + ".kt")
|
||||
myFixture.configureFromExistingVirtualFile(virtualFile)
|
||||
|
||||
myFixture.doHighlighting()
|
||||
myFixture.checkHighlighting(true, false, false)
|
||||
// val additionalResourcesDir = File(ktFile.parentFile, getTestName(true))
|
||||
// if (additionalResourcesDir.exists()) {
|
||||
// for (file in additionalResourcesDir.listFiles()) {
|
||||
// if (file.isFile) {
|
||||
// myFixture.copyFileToProject(file.absolutePath, file.name)
|
||||
// }
|
||||
// else if (file.isDirectory) {
|
||||
// myFixture.copyDirectoryToProject(file.absolutePath, file.name)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// val virtualFile = myFixture.copyFileToProject(ktFile.absolutePath, "src/" + getTestName(true) + ".kt");
|
||||
// myFixture.configureFromExistingVirtualFile(virtualFile)
|
||||
//
|
||||
// myFixture.doHighlighting()
|
||||
// myFixture.checkHighlighting(true, false, false)
|
||||
}
|
||||
|
||||
override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory() + "/plugins/uast-kotlin/testData/lint/"
|
||||
|
||||
+41
-45
@@ -18,57 +18,53 @@ package org.jetbrains.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractKotlinUastStructureTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
fun doTest() {
|
||||
val testName = getTestName(false)
|
||||
myFixture.configureByFile("$testName.kt")
|
||||
|
||||
val logFile = File(File(testDataPath, "log"), "$testName.txt")
|
||||
val renderFile = File(File(testDataPath, "render"), "$testName.txt")
|
||||
val treeFile = File(File(testDataPath, "tree"), "$testName.txt")
|
||||
|
||||
val psiFile = myFixture.file
|
||||
val uElement = KotlinUastLanguagePlugin.converter.convertWithParent(psiFile) ?: error("UFile was not created")
|
||||
|
||||
val logActual = uElement.logString()
|
||||
val renderActual = trimEmptyLines(uElement.renderString())
|
||||
|
||||
try {
|
||||
KotlinTestUtils.assertEqualsToFile(logFile, logActual)
|
||||
} catch (e: Throwable) {
|
||||
KotlinTestUtils.assertEqualsToFile(renderFile, renderActual)
|
||||
throw e
|
||||
}
|
||||
KotlinTestUtils.assertEqualsToFile(renderFile, renderActual)
|
||||
KotlinTestUtils.assertEqualsToFile(treeFile, genTree(uElement))
|
||||
// val testName = getTestName(false)
|
||||
// myFixture.configureByFile("$testName.kt")
|
||||
//
|
||||
// val logFile = File(File(testDataPath, "log"), "$testName.txt")
|
||||
// val renderFile = File(File(testDataPath, "render"), "$testName.txt")
|
||||
// val treeFile = File(File(testDataPath, "tree"), "$testName.txt")
|
||||
//
|
||||
// val psiFile = myFixture.file
|
||||
// val uElement = KotlinUastLanguagePlugin.converter.convertWithParent(psiFile) ?: error("UFile was not created")
|
||||
//
|
||||
// val logActual = uElement.logString()
|
||||
// val renderActual = trimEmptyLines(uElement.renderString())
|
||||
//
|
||||
// try {
|
||||
// KotlinTestUtils.assertEqualsToFile(logFile, logActual)
|
||||
// } catch (e: Throwable) {
|
||||
// KotlinTestUtils.assertEqualsToFile(renderFile, renderActual)
|
||||
// throw e
|
||||
// }
|
||||
// KotlinTestUtils.assertEqualsToFile(renderFile, renderActual)
|
||||
// KotlinTestUtils.assertEqualsToFile(treeFile, genTree(uElement))
|
||||
}
|
||||
|
||||
private fun trimEmptyLines(s: String): String {
|
||||
val lineSeparator = System.getProperty("line.separator")
|
||||
return s.lines().map { if (it.trim().isEmpty()) "" else it.trimEnd() }.joinToString(lineSeparator)
|
||||
}
|
||||
// private fun trimEmptyLines(s: String): String {
|
||||
// val lineSeparator = System.getProperty("line.separator")
|
||||
// return s.lines().map { if (it.trim().isEmpty()) "" else it.trimEnd() }.joinToString(lineSeparator)
|
||||
// }
|
||||
|
||||
private fun genTree(node: UElement): String {
|
||||
val builder = StringBuilder()
|
||||
val visitor = object : AbstractUastVisitor() {
|
||||
private tailrec fun height(node: UElement, current: Int): Int {
|
||||
val parent = node.parent ?: return current
|
||||
return height(parent, current + 1)
|
||||
}
|
||||
|
||||
override fun visitElement(node: UElement): Boolean {
|
||||
builder.appendln(" ".repeat(height(node, 0)) + node.javaClass.simpleName)
|
||||
return super.visitElement(node)
|
||||
}
|
||||
}
|
||||
node.accept(visitor)
|
||||
return builder.toString()
|
||||
}
|
||||
// private fun genTree(node: UElement): String {
|
||||
// val builder = StringBuilder()
|
||||
// val visitor = object : AbstractUastVisitor() {
|
||||
// private tailrec fun height(node: UElement, current: Int): Int {
|
||||
// val parent = node.parent ?: return current
|
||||
// return height(parent, current + 1)
|
||||
// }
|
||||
//
|
||||
// override fun visitElement(node: UElement): Boolean {
|
||||
// builder.appendln(" ".repeat(height(node, 0)) + node.javaClass.simpleName)
|
||||
// return super.visitElement(node)
|
||||
// }
|
||||
// }
|
||||
// node.accept(visitor)
|
||||
// return builder.toString()
|
||||
// }
|
||||
|
||||
override fun getTestDataPath() = "plugins/uast-kotlin/testData"
|
||||
|
||||
|
||||
@@ -19,10 +19,8 @@
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
<orderEntry type="module" module-name="idea-test-framework" scope="TEST" />
|
||||
<orderEntry type="module" module-name="tests-common" scope="TEST" />
|
||||
<orderEntry type="module" module-name="uast-android" />
|
||||
<orderEntry type="module" module-name="lint-api" scope="TEST" />
|
||||
<orderEntry type="module" module-name="lint-checks" scope="TEST" />
|
||||
<orderEntry type="module" module-name="lint-idea" scope="TEST" />
|
||||
<orderEntry type="module" module-name="android-extensions-idea" scope="TEST" />
|
||||
<orderEntry type="module" module-name="light-classes" />
|
||||
<orderEntry type="module" module-name="util.runtime" />
|
||||
</component>
|
||||
</module>
|
||||
Reference in New Issue
Block a user