From b02ec40a4c6a4e5cd849435e459117ae44b2e7f4 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 11 Jan 2018 20:12:40 +0300 Subject: [PATCH] 172: Revert "UAST: support for `JvmDeclarationUElement`" This reverts commit db6a2390a22d4b35246cc4c6d246a5d7752f3506. --- .../uast/kotlin/KotlinAbstractUElement.kt.172 | 8 +- .../kotlin/KotlinUastLanguagePlugin.kt.172 | 41 +++---- .../kotlin/declarations/KotlinUClass.kt.172 | 23 +--- .../kotlin/declarations/KotlinUFile.kt.172 | 56 +++++++++ .../KotlinUImportStatement.kt.172 | 65 +++++++++++ .../kotlin/declarations/KotlinUMethod.kt.172 | 8 +- .../declarations/KotlinUVariable.kt.172 | 41 ++----- .../kotlin/expressions/ElvisExpression.kt.172 | 110 ++++++++++++++++++ .../expressions/KotlinUBlockExpression.kt.172 | 59 ++++++++++ .../expressions/KotlinUCatchClause.kt.172 | 42 +++++++ .../KotlinUDeclarationsExpression.kt.172 | 3 - .../KotlinUForEachExpression.kt.172 | 42 +++++++ .../KotlinULambdaExpression.kt.172 | 52 +++++++++ .../expressions/KotlinUNamedExpression.kt.172 | 96 +++++++++++++++ .../KotlinUObjectLiteralExpression.kt.172 | 93 +++++++++++++++ .../KotlinUSwitchExpression.kt.172 | 91 +++++++++++++++ .../kotlin/expressions/LocalFunction.kt.172 | 59 ++++++++++ .../KotlinUElementWithComments.kt.172 | 29 +++++ 18 files changed, 828 insertions(+), 90 deletions(-) create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUFile.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUImportStatement.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/ElvisExpression.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUBlockExpression.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCatchClause.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUForEachExpression.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinULambdaExpression.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUNamedExpression.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUObjectLiteralExpression.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSwitchExpression.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/LocalFunction.kt.172 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/KotlinUElementWithComments.kt.172 diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinAbstractUElement.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinAbstractUElement.kt.172 index 38096536a40..469c8926548 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinAbstractUElement.kt.172 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinAbstractUElement.kt.172 @@ -28,7 +28,7 @@ import org.jetbrains.uast.* import org.jetbrains.uast.kotlin.expressions.KotlinUElvisExpression import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable -abstract class KotlinAbstractUElement(private val givenParent: UElement?) : UElement, JvmDeclarationUElement { +abstract class KotlinAbstractUElement(private val givenParent: UElement?) : UElement { override val uastParent: UElement? by lz { givenParent ?: convertParent() @@ -175,11 +175,7 @@ private fun findAnnotationClassFromConstructorParameter(parameter: KtParameter): } abstract class KotlinAbstractUExpression(givenParent: UElement?) - : KotlinAbstractUElement(givenParent), UExpression, JvmDeclarationUElement { - - override val javaPsi = null - override val sourcePsi - get() = psi + : KotlinAbstractUElement(givenParent), UExpression { override val annotations: List get() { diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.172 index 1619212b41e..f76719b3c00 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.172 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.172 @@ -80,7 +80,7 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { if (!element.isJvmElement) return null return convertDeclarationOrElement(element, parent, requiredType) } - + override fun convertElementWithParent(element: PsiElement, requiredType: Class?): UElement? { if (!element.isJvmElement) return null if (element is PsiFile) return convertDeclaration(element, null, requiredType) @@ -117,7 +117,7 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { 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 val parentUElement = convertElementWithParent(parent, null) ?: return null @@ -134,7 +134,7 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { if (element !is KtCallExpression) return null val resolvedCall = element.getResolvedCall(element.analyze()) ?: return null val resultingDescriptor = resolvedCall.resultingDescriptor - if (resultingDescriptor !is ConstructorDescriptor + if (resultingDescriptor !is ConstructorDescriptor || resultingDescriptor.returnType.constructor.declarationDescriptor?.name?.asString() != fqName) { return null } @@ -151,13 +151,9 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { internal fun convertDeclaration(element: PsiElement, givenParent: UElement?, requiredType: Class?): UElement? { - fun

build(ctor: (P, UElement?) -> UElement): () -> UElement? = { ctor(element as P, givenParent) } - - fun

buildKt(ktElement: K, ctor: (P, K, UElement?) -> UElement): () -> UElement? = - { ctor(element as P, ktElement, givenParent) } - - fun

buildKtOpt(ktElement: K?, ctor: (P, K?, UElement?) -> UElement): () -> UElement? = - { ctor(element as P, ktElement, givenParent) } + fun

build(ctor: (P, UElement?) -> UElement): () -> UElement? { + return { ctor(element as P, givenParent) } + } val original = element.originalElement return with(requiredType) { @@ -169,11 +165,10 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { } else -> el { KotlinUClass.create(original, givenParent) } } - is KtLightFieldImpl.KtLightEnumConstant -> el(buildKtOpt(original.kotlinOrigin, ::KotlinUEnumConstant)) - is KtLightField -> el(buildKtOpt(original.kotlinOrigin, ::KotlinUField)) - is KtLightParameter -> el(buildKtOpt(original.kotlinOrigin, ::KotlinUParameter)) - is UastKotlinPsiParameter -> el(buildKt(original.ktParameter, ::KotlinUParameter)) - is UastKotlinPsiVariable -> el(buildKt(original.ktElement, ::KotlinUVariable)) + is KtLightFieldImpl.KtLightEnumConstant -> el(build(::KotlinUEnumConstant)) + is KtLightField -> el(build(::KotlinUField)) + is KtLightParameter, is UastKotlinPsiParameter -> el(build(::KotlinUParameter)) + is UastKotlinPsiVariable -> el(build(::KotlinUVariable)) is KtEnumEntry -> el { convertEnumEntry(original, givenParent) @@ -220,7 +215,7 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { val ownerFunction = original.ownerFunction as? KtFunction ?: return null val lightMethod = LightClassUtil.getLightClassMethod(ownerFunction) ?: return null val lightParameter = lightMethod.parameterList.parameters.find { it.name == original.name } ?: return null - KotlinUParameter(lightParameter, original, givenParent) + KotlinUParameter(lightParameter, givenParent) } is KtFile -> el { KotlinUFile(original, this@KotlinUastLanguagePlugin) } @@ -246,7 +241,7 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { private fun convertEnumEntry(original: KtEnumEntry, givenParent: UElement?): UElement? { return LightClassUtil.getLightClassBackingField(original)?.let { psiField -> if (psiField is KtLightFieldImpl.KtLightEnumConstant) { - KotlinUEnumConstant(psiField, psiField.kotlinOrigin, givenParent) + KotlinUEnumConstant(psiField, givenParent) } else { null @@ -280,7 +275,7 @@ private fun convertNonLocalProperty(property: KtProperty, val methods = LightClassUtil.getLightClassPropertyMethods(property) return methods.backingField?.let { backingField -> with(requiredType) { - el { KotlinUField(backingField, (backingField as? KtLightElement<*,*>)?.kotlinOrigin, givenParent) } + el { KotlinUField(backingField, givenParent) } } } ?: methods.getter?.let { getter -> KotlinUastLanguagePlugin().convertDeclaration(getter, givenParent, requiredType) @@ -310,7 +305,7 @@ internal object KotlinConverter { val declarationsExpression = KotlinUDeclarationsExpression(givenParent) declarationsExpression.apply { declarations = element.parameters.mapIndexed { i, p -> - KotlinUParameter(UastKotlinPsiParameter.create(p, element, declarationsExpression, i), p, this) + KotlinUParameter(UastKotlinPsiParameter.create(p, element, declarationsExpression, i), this) } } } @@ -320,7 +315,7 @@ internal object KotlinConverter { if (element is KtProperty && !element.isLocal) { el { LightClassUtil.getLightClassBackingField(element)?.let { - KotlinUField(it, element, givenParent) + KotlinUField(it, givenParent) } } } @@ -420,13 +415,13 @@ internal object KotlinConverter { is KtDestructuringDeclaration -> expr { val declarationsExpression = KotlinUDestructuringDeclarationExpression(givenParent, expression) declarationsExpression.apply { - val tempAssignment = KotlinULocalVariable(UastKotlinPsiVariable.create(expression, declarationsExpression), expression, declarationsExpression) + val tempAssignment = KotlinULocalVariable(UastKotlinPsiVariable.create(expression, declarationsExpression), declarationsExpression) val destructuringAssignments = expression.entries.mapIndexed { i, entry -> val psiFactory = KtPsiFactory(expression.project) val initializer = psiFactory.createAnalyzableExpression("${tempAssignment.name}.component${i + 1}()", expression.containingFile) initializer.destructuringDeclarationInitializer = true - KotlinULocalVariable(UastKotlinPsiVariable.create(entry, tempAssignment.psi, declarationsExpression, initializer), entry, declarationsExpression) + KotlinULocalVariable(UastKotlinPsiVariable.create(entry, tempAssignment.psi, declarationsExpression, initializer), declarationsExpression) } declarations = listOf(tempAssignment) + destructuringAssignments } @@ -551,7 +546,7 @@ private fun convertVariablesDeclaration( val declarationsExpression = KotlinUDeclarationsExpression(null, parent, psi) val parentPsiElement = parent?.psi val variable = KotlinUAnnotatedLocalVariable( - UastKotlinPsiVariable.create(psi, parentPsiElement, declarationsExpression), psi, declarationsExpression) { annotationParent -> + UastKotlinPsiVariable.create(psi, parentPsiElement, declarationsExpression), declarationsExpression) { annotationParent -> psi.annotationEntries.map { KotlinUAnnotation(it, annotationParent) } } return declarationsExpression.apply { declarations = listOf(variable) } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt.172 index 0e3315e29c7..7590c719bc8 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt.172 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt.172 @@ -31,7 +31,7 @@ import org.jetbrains.uast.java.AbstractJavaUClass import org.jetbrains.uast.kotlin.declarations.KotlinUMethod import org.jetbrains.uast.kotlin.declarations.UastLightIdentifier -abstract class AbstractKotlinUClass(private val givenParent: UElement?) : AbstractJavaUClass(), JvmDeclarationUElement { +abstract class AbstractKotlinUClass(private val givenParent: UElement?) : AbstractJavaUClass() { override val uastParent: UElement? by lz { givenParent ?: convertParent() } //TODO: should be merged with KotlinAbstractUElement.convertParent() after detaching from AbstractJavaUClass @@ -42,6 +42,7 @@ abstract class AbstractKotlinUClass(private val givenParent: UElement?) : Abstra else -> it.toUElement() } } ?: (psi.parent ?: psi.containingFile).toUElement() + } open class KotlinUClass private constructor( @@ -51,10 +52,6 @@ open class KotlinUClass private constructor( val ktClass = psi.kotlinOrigin - override val javaPsi: KtLightClass = psi - - override val sourcePsi: KtClassOrObject? = ktClass - override val psi = unwrap(psi) override fun getSourceElement() = sourcePsi ?: this @@ -119,7 +116,6 @@ open class KotlinUClass private constructor( else -> KotlinUClass(psi, containingElement) } } - } open class KotlinConstructorUMethod( @@ -153,10 +149,6 @@ open class KotlinConstructorUMethod( } } - override val javaPsi = psi - - override val sourcePsi = psi.kotlinOrigin - open protected fun getBodyExpressions(): List { if (isPrimary) return getInitializers() val bodyExpression = (psi.kotlinOrigin as? KtFunction)?.bodyExpression ?: return emptyList() @@ -186,10 +178,6 @@ class KotlinUAnonymousClass( override val psi: PsiAnonymousClass = unwrap(psi) - override val javaPsi: PsiAnonymousClass = psi - - override val sourcePsi: KtClassOrObject? = (psi as? KtLightClass)?.kotlinOrigin - override fun getOriginalElement(): PsiElement? = super.getOriginalElement() override fun getSuperClass(): UClass? = super.getSuperClass() @@ -219,10 +207,6 @@ class KotlinScriptUClass( override val uastAnchor: UElement get() = UIdentifier(nameIdentifier, this) - override val javaPsi: PsiClass = psi - - override val sourcePsi: KtClassOrObject? = psi.kotlinOrigin - override val psi = unwrap(psi) override fun getSuperClass(): UClass? = super.getSuperClass() @@ -256,11 +240,8 @@ class KotlinScriptUClass( val initializers = script.declarations.filterIsInstance() KotlinUBlockExpression.create(initializers, this) } - override val javaPsi = psi - override val sourcePsi = psi.kotlinOrigin } } - private fun reportConvertFailure(psiMethod: PsiMethod): Nothing { val isValid = psiMethod.isValid val report = KotlinExceptionWithAttachments( diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUFile.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUFile.kt.172 new file mode 100644 index 00000000000..33dde2e91d4 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUFile.kt.172 @@ -0,0 +1,56 @@ +/* + * 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.PsiClass +import com.intellij.psi.PsiComment +import com.intellij.psi.PsiRecursiveElementWalkingVisitor +import org.jetbrains.kotlin.asJava.findFacadeClass +import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.psi.KtClassOrObject +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 annotations: List + get() = psi.annotationEntries.map { KotlinUAnnotation(it, this) } + + override val allCommentsInFile by lz { + val comments = ArrayList(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 { + val facadeOrScriptClass = if (psi.isScript()) psi.script?.toLightClass() else psi.findFacadeClass() + val classes = psi.declarations.mapNotNull { (it as? KtClassOrObject)?.toLightClass()?.toUClass() } + + (facadeOrScriptClass?.toUClass()?.let { listOf(it) } ?: emptyList()) + classes + } + + private fun PsiClass.toUClass() = languagePlugin.convertOpt(this, this@KotlinUFile) +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUImportStatement.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUImportStatement.kt.172 new file mode 100644 index 00000000000..a990b42f918 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUImportStatement.kt.172 @@ -0,0 +1,65 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.uast.kotlin + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtImportDirective +import org.jetbrains.kotlin.psi.KtReferenceExpression +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UImportStatement +import org.jetbrains.uast.USimpleNameReferenceExpression + +class KotlinUImportStatement( + override val psi: KtImportDirective, + givenParent: UElement? +) : KotlinAbstractUElement(givenParent), UImportStatement { + override val isOnDemand: Boolean + get() = psi.isAllUnder + + private val importRef by lz { + psi.importedReference?.let { + ImportReference(it, psi.name ?: psi.text, this, psi) + } + } + + override val importReference: UElement? + get() = importRef + + override fun resolve() = importRef?.resolve() + + private class ImportReference( + override val psi: KtExpression, + override val identifier: String, + givenParent: UElement?, + private val importDirective: KtImportDirective + ) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression { + override val resolvedName: String? + get() = identifier + + override fun asRenderString(): String = importDirective.importedFqName?.asString() ?: psi.text + + override fun resolve(): PsiElement? { + val reference = psi.getQualifiedElementSelector() as? KtReferenceExpression ?: return null + val bindingContext = reference.analyze() + val referenceTarget = bindingContext[BindingContext.REFERENCE_TARGET, reference] ?: return null + return referenceTarget.toSource()?.getMaybeLightElement(this) + } + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt.172 index ed95dcf685d..2cc3868f908 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt.172 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt.172 @@ -38,12 +38,6 @@ open class KotlinUMethod( ) : KotlinAbstractUElement(givenParent), UAnnotationMethod, JavaUElementWithComments, PsiMethod by psi { override val psi: KtLightMethod = unwrap(psi) - override val javaPsi = psi - - override val sourcePsi = psi.kotlinOrigin - - override fun getSourceElement() = sourcePsi ?: this - override val uastDefaultValue by lz { val annotationParameter = psi.kotlinOrigin as? KtParameter ?: return@lz null val defaultValue = annotationParameter.defaultValue ?: return@lz null @@ -63,7 +57,7 @@ open class KotlinUMethod( } override val uastParameters by lz { - psi.parameterList.parameters.map { KotlinUParameter(it, (it as? KtLightElement<*, *>)?.kotlinOrigin, this) } + psi.parameterList.parameters.map { KotlinUParameter(it, this) } } override val uastAnchor: UElement diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUVariable.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUVariable.kt.172 index 2259c3c3b39..6fb2f3f8428 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUVariable.kt.172 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUVariable.kt.172 @@ -19,7 +19,10 @@ package org.jetbrains.uast.kotlin import com.intellij.psi.* import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.elements.KtLightElement -import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.KtVariableDeclaration import org.jetbrains.uast.* import org.jetbrains.uast.internal.acceptList import org.jetbrains.uast.java.JavaAbstractUExpression @@ -83,13 +86,9 @@ abstract class AbstractKotlinUVariable(givenParent: UElement?) class KotlinUVariable( psi: PsiVariable, - override val sourcePsi: KtElement, givenParent: UElement? ) : AbstractKotlinUVariable(givenParent), UVariable, PsiVariable by psi { - - override val javaPsi = unwrap(psi) - - override val psi = javaPsi + override val psi = unwrap(psi) override val annotations by lz { psi.annotations.map { JavaUAnnotation(it, this) } } @@ -114,13 +113,10 @@ class KotlinUVariable( open class KotlinUParameter( psi: PsiParameter, - override val sourcePsi: KtElement?, givenParent: UElement? ) : AbstractKotlinUVariable(givenParent), UParameter, PsiParameter by psi { - override val javaPsi = unwrap(psi) - - override val psi = javaPsi + override val psi = unwrap(psi) override fun getInitializer(): PsiExpression? { return super.getInitializer() @@ -141,13 +137,10 @@ open class KotlinUParameter( open class KotlinUField( psi: PsiField, - override val sourcePsi: KtElement?, givenParent: UElement? ) : AbstractKotlinUVariable(givenParent), UField, PsiField by psi { - override val javaPsi = unwrap(psi) - - override val psi = javaPsi + override val psi = unwrap(psi) override fun getInitializer(): PsiExpression? { return super.getInitializer() @@ -180,13 +173,10 @@ open class KotlinUField( open class KotlinULocalVariable( psi: PsiLocalVariable, - override val sourcePsi: KtElement, givenParent: UElement? ) : AbstractKotlinUVariable(givenParent), ULocalVariable, PsiLocalVariable by psi { - override val javaPsi = unwrap(psi) - - override val psi = javaPsi + override val psi = unwrap(psi) override fun getInitializer(): PsiExpression? { return super.getInitializer() @@ -215,29 +205,24 @@ open class KotlinULocalVariable( open class KotlinUAnnotatedLocalVariable( psi: PsiLocalVariable, - sourcePsi: KtElement, uastParent: UElement?, computeAnnotations: (parent: UElement) -> List -) : KotlinULocalVariable(psi, sourcePsi, uastParent) { +) : KotlinULocalVariable(psi, uastParent) { override val annotations: List by lz { computeAnnotations(this) } } open class KotlinUEnumConstant( psi: PsiEnumConstant, - override val sourcePsi: KtElement?, givenParent: UElement? ) : AbstractKotlinUVariable(givenParent), UEnumConstant, PsiEnumConstant by psi { - override val initializingClass: UClass? by lz { (psi.initializingClass as? KtLightClass)?.let { initializingClass -> KotlinUClass.create(initializingClass, this) } } - override val javaPsi = unwrap(psi) - - override val psi = javaPsi + override val psi = unwrap(psi) override fun getContainingFile(): PsiFile { return super.getContainingFile() @@ -260,7 +245,7 @@ open class KotlinUEnumConstant( get() = null override val classReference: UReferenceExpression? - get() = KotlinEnumConstantClassReference(psi, sourcePsi, this) + get() = KotlinEnumConstantClassReference(psi, this) override val typeArgumentCount: Int get() = 0 @@ -287,12 +272,8 @@ open class KotlinUEnumConstant( private class KotlinEnumConstantClassReference( override val psi: PsiEnumConstant, - override val sourcePsi: KtElement?, private val givenParent: UElement? ) : JavaAbstractUExpression(), USimpleNameReferenceExpression { - override val javaPsi: PsiElement? - get() = psi - override val uastParent: UElement? by lz { givenParent ?: KotlinUastLanguagePlugin().convertElementWithParent(psi.parent ?: psi.containingFile, null) } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/ElvisExpression.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/ElvisExpression.kt.172 new file mode 100644 index 00000000000..07508f4f6e1 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/ElvisExpression.kt.172 @@ -0,0 +1,110 @@ +package org.jetbrains.uast.kotlin.expressions + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiType +import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.types.CommonSupertypes +import org.jetbrains.uast.* +import org.jetbrains.uast.kotlin.* +import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds +import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable + + +private fun createVariableReferenceExpression(variable: UVariable, containingElement: UElement?) = + object : USimpleNameReferenceExpression { + override val psi: PsiElement? = null + override fun resolve(): PsiElement? = variable + override val uastParent: UElement? = containingElement + override val resolvedName: String? = variable.name + override val annotations: List = emptyList() + override val identifier: String = variable.name.orAnonymous() + } + +private fun createNullLiteralExpression(containingElement: UElement?) = + object : ULiteralExpression { + override val psi: PsiElement? = null + override val uastParent: UElement? = containingElement + override val value: Any? = null + override val annotations: List = emptyList() + } + +private fun createNotEqWithNullExpression(variable: UVariable, containingElement: UElement?) = + object : UBinaryExpression { + override val psi: PsiElement? = null + override val uastParent: UElement? = containingElement + override val leftOperand: UExpression by lz { createVariableReferenceExpression(variable, this) } + override val rightOperand: UExpression by lz { createNullLiteralExpression(this) } + override val operator: UastBinaryOperator = UastBinaryOperator.NOT_EQUALS + override val operatorIdentifier: UIdentifier? = UIdentifier(null, this) + override fun resolveOperator(): PsiMethod? = null + override val annotations: List = emptyList() + } + +private fun createElvisExpressions( + left: KtExpression, + right: KtExpression, + containingElement: UElement?, + psiParent: PsiElement): List { + + val declaration = KotlinUDeclarationsExpression(containingElement) + val tempVariable = KotlinULocalVariable(UastKotlinPsiVariable.create(left, declaration, psiParent), declaration) + declaration.declarations = listOf(tempVariable) + + val ifExpression = object : UIfExpression { + override val psi: PsiElement? = null + override val uastParent: UElement? = containingElement + override val condition: UExpression by lz { createNotEqWithNullExpression(tempVariable, this) } + override val thenExpression: UExpression? by lz { createVariableReferenceExpression(tempVariable, this) } + override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this ) } + override val isTernary: Boolean = false + override val annotations: List = emptyList() + override val ifIdentifier: UIdentifier = UIdentifier(null, this) + override val elseIdentifier: UIdentifier? = UIdentifier(null, this) + } + + return listOf(declaration, ifExpression) +} + +fun createElvisExpression(elvisExpression: KtBinaryExpression, givenParent: UElement?): UExpression { + val left = elvisExpression.left ?: return UastEmptyExpression + val right = elvisExpression.right ?: return UastEmptyExpression + + return KotlinUElvisExpression(elvisExpression, left, right, givenParent) +} + +class KotlinUElvisExpression( + private val elvisExpression: KtBinaryExpression, + private val left: KtExpression, + private val right: KtExpression, + givenParent: UElement? +) : KotlinAbstractUElement(givenParent), UExpressionList, KotlinEvaluatableUElement { + + override val psi: PsiElement? = elvisExpression + override val kind = KotlinSpecialExpressionKinds.ELVIS + override val annotations: List = emptyList() + override val expressions: List by lz { + createElvisExpressions(left, right, this, elvisExpression.parent) + } + + val lhsDeclaration get() = (expressions[0] as UDeclarationsExpression).declarations.single() + val rhsIfExpression get() = expressions[1] as UIfExpression + + override fun asRenderString(): String { + return kind.name + " " + + expressions.joinToString(separator = "\n", prefix = "{\n", postfix = "\n}") { + it.asRenderString().withMargin + } + } + + override fun getExpressionType(): PsiType? { + val leftType = left.analyze()[BindingContext.EXPRESSION_TYPE_INFO, left]?.type ?: return null + val rightType = right.analyze()[BindingContext.EXPRESSION_TYPE_INFO, right]?.type ?: return null + + return CommonSupertypes + .commonSupertype(listOf(leftType, rightType)) + .toPsiType(this, elvisExpression, boxed = false) + } +} diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUBlockExpression.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUBlockExpression.kt.172 new file mode 100644 index 00000000000..244e6d7aa04 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUBlockExpression.kt.172 @@ -0,0 +1,59 @@ +/* + * 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.psi.KtAnonymousInitializer +import org.jetbrains.kotlin.psi.KtBlockExpression +import org.jetbrains.uast.* + +class KotlinUBlockExpression( + override val psi: KtBlockExpression, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), UBlockExpression, KotlinUElementWithType { + override val expressions by lz { psi.statements.map { KotlinConverter.convertOrEmpty(it, this) } } + + class KotlinLazyUBlockExpression( + override val uastParent: UElement?, + expressionProducer: (expressionParent: UElement) -> List + ) : UBlockExpression { + override val psi: PsiElement? = null + override val annotations: List = emptyList() + override val expressions by lz { expressionProducer(this) } + } + + companion object { + fun create(initializers: List, uastParent: UElement): UBlockExpression { + val languagePlugin = uastParent.getLanguagePlugin() + return KotlinLazyUBlockExpression(uastParent) { expressionParent -> + initializers.map { languagePlugin.convertOpt(it.body, expressionParent) ?: UastEmptyExpression } + } + } + } + + override fun convertParent(): UElement? { + val directParent = super.convertParent() + if (directParent is UnknownKotlinExpression && directParent.psi is KtAnonymousInitializer) { + val containingUClass = directParent.getContainingUClass() ?: return directParent + containingUClass.methods + .find { it is KotlinConstructorUMethod && it.isPrimary || it is KotlinSecondaryConstructorWithInitializersUMethod }?.let { + return it.uastBody + } + } + return directParent + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCatchClause.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCatchClause.kt.172 new file mode 100644 index 00000000000..c2936f10844 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCatchClause.kt.172 @@ -0,0 +1,42 @@ +/* + * 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.psi.KtCatchClause +import org.jetbrains.uast.UCatchClause +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UParameter +import org.jetbrains.uast.UTypeReferenceExpression +import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter + +class KotlinUCatchClause( + override val psi: KtCatchClause, + givenParent: UElement? +) : KotlinAbstractUElement(givenParent), UCatchClause { + override val body by lz { KotlinConverter.convertOrEmpty(psi.catchBody, this) } + + override val parameters by lz { + val parameter = psi.catchParameter ?: return@lz emptyList() + listOf(KotlinUParameter(UastKotlinPsiParameter.create(parameter, psi, this, 0), this)) + } + + override val typeReferences by lz { + val parameter = psi.catchParameter ?: return@lz emptyList() + val typeReference = parameter.typeReference ?: return@lz emptyList() + listOf(LazyKotlinUTypeReferenceExpression(typeReference, this) { typeReference.toPsiType(this, boxed = true) } ) + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUDeclarationsExpression.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUDeclarationsExpression.kt.172 index af143b057e6..eb934ef0d54 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUDeclarationsExpression.kt.172 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUDeclarationsExpression.kt.172 @@ -25,9 +25,6 @@ open class KotlinUDeclarationsExpression( val psiAnchor: PsiElement? = null ) : KotlinAbstractUExpression(givenParent), UDeclarationsExpression { - override val sourcePsi: PsiElement? - get() = psiAnchor - override val uastParent: UElement? get() = if (psiAnchor != null) doConvertParent(this, psiAnchor.parent) else super.uastParent diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUForEachExpression.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUForEachExpression.kt.172 new file mode 100644 index 00000000000..c6ce608d15a --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUForEachExpression.kt.172 @@ -0,0 +1,42 @@ +/* + * 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.KotlinLanguage +import org.jetbrains.kotlin.psi.KtForExpression +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.UastPsiParameterNotResolved + +class KotlinUForEachExpression( + override val psi: KtForExpression, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), UForEachExpression { + 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) +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinULambdaExpression.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinULambdaExpression.kt.172 new file mode 100644 index 00000000000..b40a5e5dab3 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinULambdaExpression.kt.172 @@ -0,0 +1,52 @@ +/* + * 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.PsiType +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.withMargin + +class KotlinULambdaExpression( + override val psi: KtLambdaExpression, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), ULambdaExpression, KotlinUElementWithType { + override val functionalInterfaceType: PsiType? + get() = getFunctionalInterfaceType() + + override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) } + + 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.asRenderString() } + " ->\n" + val expressions = (body as? UBlockExpression)?.expressions + ?.joinToString("\n") { it.asRenderString().withMargin } ?: body.asRenderString() + + return "{ $renderedValueParameters\n$expressions\n}" + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUNamedExpression.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUNamedExpression.kt.172 new file mode 100644 index 00000000000..15ca3c913df --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUNamedExpression.kt.172 @@ -0,0 +1,96 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.uast.kotlin + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiType +import org.jetbrains.kotlin.psi.ValueArgument +import org.jetbrains.uast.* + +class KotlinUNamedExpression private constructor( + override val name: String?, + givenParent: UElement?, + expressionProducer: (UElement) -> UExpression +) : KotlinAbstractUElement(givenParent), UNamedExpression { + override val expression: UExpression by lz { expressionProducer(this) } + + override val annotations: List = emptyList() + + override val psi: PsiElement? = null + + companion object { + internal fun create(name: String?, valueArgument: ValueArgument, uastParent: UElement?): UNamedExpression { + val expression = valueArgument.getArgumentExpression() + return KotlinUNamedExpression(name, uastParent) { expressionParent -> + expression?.let { expressionParent.getLanguagePlugin().convert(it, expressionParent) } ?: UastEmptyExpression + } + } + + internal fun create( + name: String?, + valueArguments: List, + uastParent: UElement?): UNamedExpression { + return KotlinUNamedExpression(name, uastParent) { expressionParent -> + KotlinUVarargExpression(valueArguments, expressionParent) + } + } + } +} +class KotlinUVarargExpression(private val valueArgs: List, + uastParent: UElement?) : KotlinAbstractUExpression(uastParent), UCallExpression { + override val kind: UastCallKind = UastCallKind.NESTED_ARRAY_INITIALIZER + + override val valueArguments: List by lz { + valueArgs.map { + it.getArgumentExpression()?.let { argumentExpression -> + getLanguagePlugin().convert(argumentExpression, this) + } ?: UastEmptyExpression + } + } + + override val valueArgumentCount: Int + get() = valueArgs.size + + override val psi: PsiElement? + get() = null + + override val methodIdentifier: UIdentifier? + get() = null + + override val classReference: UReferenceExpression? + get() = null + + override val methodName: String? + get() = null + + override val typeArgumentCount: Int + get() = 0 + + override val typeArguments: List + get() = emptyList() + + override val returnType: PsiType? + get() = null + + override fun resolve() = null + + override val receiver: UExpression? + get() = null + + override val receiverType: PsiType? + get() = null +} diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUObjectLiteralExpression.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUObjectLiteralExpression.kt.172 new file mode 100644 index 00000000000..546c5c405f9 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUObjectLiteralExpression.kt.172 @@ -0,0 +1,93 @@ +/* + * 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.diagnostic.Attachment +import com.intellij.openapi.diagnostic.Logger +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiType +import com.intellij.psi.impl.light.LightPsiClassBuilder +import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.psi.KtObjectLiteralExpression +import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry +import org.jetbrains.uast.* + +class KotlinUObjectLiteralExpression( + override val psi: KtObjectLiteralExpression, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), UObjectLiteralExpression, KotlinUElementWithType { + override val declaration: UClass by lz { + val lightClass: KtLightClass? = psi.objectDeclaration.toLightClass() + if (lightClass != null) { + getLanguagePlugin().convert(lightClass, this) + } + else { + logger.error( + "Failed to create light class for object declaration", + Attachment(psi.containingFile.virtualFile?.path ?: "", psi.containingFile.text)) + + getLanguagePlugin().convert(LightPsiClassBuilder(psi, ""), this) + } + } + + override fun getExpressionType() = psi.objectDeclaration.toPsiType() + + private val superClassConstructorCall by lz { + psi.objectDeclaration.superTypeListEntries.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() + 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() + psi.typeArguments.map { it.typeReference.toPsiType(this, boxed = true) } + } + + override fun resolve() = superClassConstructorCall?.resolveCallToDeclaration(this) as? PsiMethod + + private class ObjectLiteralClassReference( + override val psi: KtSuperTypeCallEntry, + givenParent: UElement? + ) : KotlinAbstractUElement(givenParent), USimpleNameReferenceExpression { + override fun resolve() = (psi.resolveCallToDeclaration(this) as? PsiMethod)?.containingClass + + override val annotations: List + get() = emptyList() + + override val resolvedName: String? + get() = identifier + + override val identifier: String + get() = psi.name ?: "" + } + + companion object { + val logger by lz { Logger.getInstance(KotlinUObjectLiteralExpression::class.java) } + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSwitchExpression.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSwitchExpression.kt.172 new file mode 100644 index 00000000000..0d6323304b1 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSwitchExpression.kt.172 @@ -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.PsiElement +import org.jetbrains.kotlin.psi.KtBlockExpression +import org.jetbrains.kotlin.psi.KtWhenEntry +import org.jetbrains.kotlin.psi.KtWhenExpression +import org.jetbrains.uast.* +import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds + +class KotlinUSwitchExpression( + override val psi: KtWhenExpression, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), USwitchExpression, KotlinUElementWithType { + override val expression by lz { KotlinConverter.convertOrNull(psi.subjectExpression, this) } + + override val body: UExpressionList by lz { + object : KotlinUExpressionList(psi, KotlinSpecialExpressionKinds.WHEN, this@KotlinUSwitchExpression) { + override fun asRenderString() = expressions.joinToString("\n") { it.asRenderString().withMargin } + }.apply { + expressions = this@KotlinUSwitchExpression.psi.entries.map { KotlinUSwitchEntry(it, this) } + } + } + + override fun asRenderString() = buildString { + val expr = expression?.let { "(" + it.asRenderString() + ") " } ?: "" + appendln("switch $expr {") + appendln(body.asRenderString()) + appendln("}") + } + + override val switchIdentifier: UIdentifier + get() = UIdentifier(null, this) +} + +class KotlinUSwitchEntry( + override val psi: KtWhenEntry, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), USwitchClauseExpressionWithBody { + override val caseValues by lz { + psi.conditions.map { KotlinConverter.convertWhenCondition(it, this) ?: UastEmptyExpression } + } + + override val body: UExpressionList by lz { + object : KotlinUExpressionList(psi, KotlinSpecialExpressionKinds.WHEN_ENTRY, this@KotlinUSwitchEntry) { + override fun asRenderString() = buildString { + appendln("{") + expressions.forEach { appendln(it.asRenderString().withMargin) } + appendln("}") + } + }.apply { + val exprPsi = this@KotlinUSwitchEntry.psi.expression + val userExpressions = when (exprPsi) { + is KtBlockExpression -> exprPsi.statements.map { KotlinConverter.convertOrEmpty(it, this) } + else -> listOf(KotlinConverter.convertOrEmpty(exprPsi, this)) + } + expressions = userExpressions + object : UBreakExpression { + override val psi: PsiElement? + get() = null + override val label: String? + get() = null + override val uastParent: UElement? + get() = this@KotlinUSwitchEntry + override val annotations: List + get() = emptyList() + } + } + } + + override fun convertParent(): UElement? { + val result = KotlinConverter.unwrapElements(psi.parent)?.let { parentUnwrapped -> + KotlinUastLanguagePlugin().convertElementWithParent(parentUnwrapped, null) + } + return (result as? KotlinUSwitchExpression)?.body ?: result + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/LocalFunction.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/LocalFunction.kt.172 new file mode 100644 index 00000000000..094fbbf7cfc --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/LocalFunction.kt.172 @@ -0,0 +1,59 @@ +package org.jetbrains.uast.kotlin.expressions + +import com.intellij.psi.PsiType +import com.intellij.psi.PsiVariable +import org.jetbrains.kotlin.psi.KtFunction +import org.jetbrains.uast.* +import org.jetbrains.uast.kotlin.* +import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter +import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable + + +internal class KotlinLocalFunctionUVariable( + val function: KtFunction, + override val psi: PsiVariable, + givenParent: UElement? +) : KotlinAbstractUElement(givenParent), UVariable, PsiVariable by psi { + override val uastInitializer: UExpression? by lz { + createLocalFunctionLambdaExpression(function, this) + } + override val typeReference: UTypeReferenceExpression? = null + override val uastAnchor: UElement? = null + override val annotations: List = emptyList() +} + + +private class KotlinLocalFunctionULambdaExpression( + override val psi: KtFunction, + givenParent: UElement? +): KotlinAbstractUExpression(givenParent), ULambdaExpression { + override val functionalInterfaceType: PsiType? = null + + override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) } + + override val valueParameters by lz { + psi.valueParameters.mapIndexed { i, p -> + KotlinUParameter(UastKotlinPsiParameter.create(p, psi, this, i), this) + } + } + + override fun asRenderString(): String { + val renderedValueParameters = valueParameters.joinToString(prefix = "(", postfix = ")", + transform = KotlinUParameter::asRenderString) + val expressions = (body as? UBlockExpression)?.expressions?.joinToString("\n") { + it.asRenderString().withMargin + } ?: body.asRenderString() + return "fun $renderedValueParameters {\n${expressions.withMargin}\n}" + } +} + + +fun createLocalFunctionDeclaration(function: KtFunction, parent: UElement?): UDeclarationsExpression { + return KotlinUDeclarationsExpression(null, parent, function).apply { + val functionVariable = UastKotlinPsiVariable.create(function.name.orAnonymous(), function, this) + declarations = listOf(KotlinLocalFunctionUVariable(function, functionVariable, this)) + } +} + +fun createLocalFunctionLambdaExpression(function: KtFunction, parent: UElement?): ULambdaExpression = + KotlinLocalFunctionULambdaExpression(function, parent) diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/KotlinUElementWithComments.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/KotlinUElementWithComments.kt.172 new file mode 100644 index 00000000000..1c5de8fa704 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/KotlinUElementWithComments.kt.172 @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.uast.kotlin.internal + +import com.intellij.psi.PsiComment +import org.jetbrains.uast.UComment +import org.jetbrains.uast.UElement + +interface KotlinUElementWithComments : UElement { + override val comments: List + get() { + val psi = psi ?: return emptyList() + return psi.children.filter { it is PsiComment }.map { UComment(it, this) } + } +} \ No newline at end of file