From 92d2e7a0a92f7afe3da40b8f5042cd32ec46fb49 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Thu, 3 Mar 2016 17:46:54 +0300 Subject: [PATCH] Kotlin Uast: Initial implementation --- .../lint/KotlinLintLanguageExtension.kt | 24 +++ .../jetbrains/kotlin/uast/KotlinConverter.kt | 186 ++++++++++++++++++ .../uast/declarations/KotlinPsiElementStub.kt | 30 +++ .../uast/declarations/KotlinUAnnotation.kt | 61 ++++++ .../declarations/KotlinUAnnotationList.kt | 37 ++++ .../kotlin/uast/declarations/KotlinUClass.kt | 106 ++++++++++ .../kotlin/uast/declarations/KotlinUFile.kt | 31 +++ .../declarations/KotlinUImportStatement.kt | 32 +++ .../kotlin/uast/declarations/KotlinUType.kt | 59 ++++++ .../uast/declarations/KotlinUVariable.kt | 106 ++++++++++ .../uast/declarations/kotlinUFunctions.kt | 89 +++++++++ .../KotlinStringTemplateUBinaryExpression.kt | 34 ++++ .../uast/expressions/KotlinUArrayAccess.kt | 31 +++ .../KotlinUArrayAccessExpression.kt | 30 +++ .../expressions/KotlinUBinaryExpression.kt | 59 ++++++ .../KotlinUBinaryExpressionWithType.kt | 45 +++++ .../expressions/KotlinUBlockExpression.kt | 30 +++ .../uast/expressions/KotlinUCatchClause.kt | 41 ++++ .../KotlinUDeclarationsExpression.kt | 21 ++ .../expressions/KotlinUDoWhileExpression.kt | 31 +++ .../uast/expressions/KotlinUExpression.kt | 42 ++++ .../expressions/KotlinUForEachExpression.kt | 32 +++ .../KotlinUFunctionCallExpression.kt | 91 +++++++++ .../uast/expressions/KotlinUIfExpression.kt | 32 +++ .../expressions/KotlinULambdaExpression.kt | 39 ++++ .../expressions/KotlinULiteralExpression.kt | 51 +++++ .../KotlinUParenthesizedExpression.kt | 29 +++ .../expressions/KotlinUPostfixExpression.kt | 39 ++++ .../expressions/KotlinUPrefixExpression.kt | 40 ++++ .../expressions/KotlinUQualifiedExpression.kt | 43 ++++ .../KotlinUSafeQualifiedExpression.kt | 35 ++++ .../KotlinUSimpleReferenceExpression.kt | 58 ++++++ .../KotlinUSpecialExpressionList.kt | 48 +++++ .../expressions/KotlinUSuperExpression.kt | 27 +++ .../expressions/KotlinUSwitchExpression.kt | 107 ++++++++++ .../uast/expressions/KotlinUThisExpression.kt | 28 +++ .../uast/expressions/KotlinUTryExpression.kt | 32 +++ .../expressions/KotlinUTypeCheckExpression.kt | 31 +++ .../expressions/KotlinUWhileExpression.kt | 31 +++ .../expressions/UnknownKotlinExpression.kt | 32 +++ .../uast/internal/kotlinInternalUastUtils.kt | 77 ++++++++ .../org/jetbrains/kotlin/uast/internal/lz.kt | 41 ++++ .../KotlinBinaryExpressionWithTypeKinds.kt | 27 +++ .../uast/kinds/KotlinBinaryOperators.kt | 26 +++ .../uast/kinds/KotlinPostfixOperators.kt | 24 +++ .../KotlinQualifiedExpressionAccessTypes.kt | 24 +++ .../kinds/KotlinSpecialExpressionKinds.kt | 30 +++ .../uast/kinds/KotlinUastVisibilities.kt | 24 +++ .../AbstractKotlinUastStructureTest.kt | 50 +++++ .../KotlinUastStructureTest.kt | 25 +++ .../uast-kotlin/testData/ControlStructures.kt | 59 ++++++ plugins/uast-kotlin/testData/Declarations.kt | 13 ++ plugins/uast-kotlin/testData/Simple.kt | 8 + .../testData/log/ControlStructures.txt | 11 ++ .../uast-kotlin/testData/log/Declarations.txt | 21 ++ plugins/uast-kotlin/testData/log/Simple.txt | 19 ++ .../testData/render/ControlStructures.txt | 7 + .../testData/render/Declarations.txt | 16 ++ .../uast-kotlin/testData/render/Simple.txt | 9 + plugins/uast-kotlin/uast-kotlin.iml | 24 +++ 60 files changed, 2485 insertions(+) create mode 100644 plugins/android-lint/src/org/jetbrains/kotlin/lint/KotlinLintLanguageExtension.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinConverter.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinPsiElementStub.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUAnnotation.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUAnnotationList.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUClass.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUFile.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUImportStatement.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUType.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUVariable.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/kotlinUFunctions.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinStringTemplateUBinaryExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUArrayAccess.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUArrayAccessExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpressionWithType.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBlockExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUCatchClause.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUDeclarationsExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUDoWhileExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUForEachExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUFunctionCallExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUIfExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinULambdaExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinULiteralExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUParenthesizedExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUPostfixExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUPrefixExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUQualifiedExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSafeQualifiedExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSimpleReferenceExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSpecialExpressionList.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSuperExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSwitchExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUThisExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTryExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTypeCheckExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUWhileExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/UnknownKotlinExpression.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/internal/kotlinInternalUastUtils.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/internal/lz.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinBinaryExpressionWithTypeKinds.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinBinaryOperators.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinPostfixOperators.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinQualifiedExpressionAccessTypes.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinSpecialExpressionKinds.kt create mode 100644 plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinUastVisibilities.kt create mode 100644 plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/AbstractKotlinUastStructureTest.kt create mode 100644 plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/KotlinUastStructureTest.kt create mode 100644 plugins/uast-kotlin/testData/ControlStructures.kt create mode 100644 plugins/uast-kotlin/testData/Declarations.kt create mode 100644 plugins/uast-kotlin/testData/Simple.kt create mode 100644 plugins/uast-kotlin/testData/log/ControlStructures.txt create mode 100644 plugins/uast-kotlin/testData/log/Declarations.txt create mode 100644 plugins/uast-kotlin/testData/log/Simple.txt create mode 100644 plugins/uast-kotlin/testData/render/ControlStructures.txt create mode 100644 plugins/uast-kotlin/testData/render/Declarations.txt create mode 100644 plugins/uast-kotlin/testData/render/Simple.txt create mode 100644 plugins/uast-kotlin/uast-kotlin.iml diff --git a/plugins/android-lint/src/org/jetbrains/kotlin/lint/KotlinLintLanguageExtension.kt b/plugins/android-lint/src/org/jetbrains/kotlin/lint/KotlinLintLanguageExtension.kt new file mode 100644 index 00000000000..a1059ae3a4f --- /dev/null +++ b/plugins/android-lint/src/org/jetbrains/kotlin/lint/KotlinLintLanguageExtension.kt @@ -0,0 +1,24 @@ +/* + * 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.lint + +import com.android.tools.lint.client.api.LintLanguageExtension +import org.jetbrains.kotlin.uast.KotlinConverter + +class KotlinLintLanguageExtension : LintLanguageExtension() { + override fun getConverter() = KotlinConverter +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinConverter.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinConverter.kt new file mode 100644 index 00000000000..c10f43ce042 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinConverter.kt @@ -0,0 +1,186 @@ +/* + * 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.uast.* + +object KotlinConverter : UastConverter { + override fun isFileSupported(path: String) = path.endsWith(".kt", false) || path.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 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 -> KotlinUClass(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) + 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.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 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 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 -> KotlinUSpecialExpressionList.Empty(expression, UastSpecialExpressionKind.BREAK, parent) + is KtContinueExpression -> KotlinUSpecialExpressionList.Empty(expression, UastSpecialExpressionKind.CONTINUE, parent) + is KtReturnExpression -> KotlinUSpecialExpressionList(expression, UastSpecialExpressionKind.RETURN, parent).apply { + expressions = listOf(convertOrEmpty(expression.returnedExpression, this)) + } + is KtThrowExpression -> KotlinUSpecialExpressionList(expression, UastSpecialExpressionKind.THROW, parent).apply { + expressions = singletonListOrEmpty(convertOrNull(expression.thrownExpression, this)) + } + is KtBlockExpression -> KotlinUBlockExpression(expression, parent) + is KtConstantExpression -> KotlinULiteralExpression(expression, parent) + is KtTryExpression -> KotlinUTryExpression(expression, parent) + is KtArrayAccessExpression -> KotlinUArrayAccess(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: KotlinType, project: Project, parent: UElement?): UType { + return KotlinUType(element, project, parent) + } + + internal fun convert(typeReference: KtTypeReference?, parent: UElement): UType { + if (typeReference == null) return KotlinUErrorType + val bindingContext = typeReference.analyze(BodyResolveMode.PARTIAL) + val type = bindingContext[BindingContext.TYPE, typeReference] ?: return KotlinUErrorType + return convert(type, typeReference.project, parent) + } + + internal fun asSimpleReference(element: PsiElement?, parent: UElement): USimpleReferenceExpression? { + if (element == null) return null + return KotlinUSimpleReferenceExpression(element, KtPsiUtil.unquoteIdentifier(element.text), parent) + } + + internal fun convertOrEmpty(expression: KtExpression?, parent: UElement): UExpression { + return if (expression != null) convert(expression, parent) else EmptyExpression(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() + return SimpleUDeclarationsExpression(parent, udeclarations).apply { + convert(declaration, this)?.let { udeclarations += it } + } + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinPsiElementStub.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinPsiElementStub.kt new file mode 100644 index 00000000000..cf5768ab486 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinPsiElementStub.kt @@ -0,0 +1,30 @@ +/* + * 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.NoTraverse +import org.jetbrains.uast.UElement +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinPsiElementStub( + override val psi: PsiElement, + override val parent: UElement +) : UElement, PsiElementBacked, NoTraverse { + override fun logString() = "KotlinPsiElementStub" + override fun renderString() = "" +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUAnnotation.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUAnnotation.kt new file mode 100644 index 00000000000..67460dbc04a --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUAnnotation.kt @@ -0,0 +1,61 @@ +/* + * 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.descriptors.ConstructorDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +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 +) : 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? ConstructorDescriptor)?.containingDeclaration + } + + override fun resolve(context: UastContext): UClass? { + val classDescriptor = resolveToDescriptor() ?: return null + val source = DescriptorToSourceUtilsIde.getAnyDeclaration(psi.project, classDescriptor) ?: return null + return context.convert(source) as? UClass + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUAnnotationList.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUAnnotationList.kt new file mode 100644 index 00000000000..b89b188f343 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUAnnotationList.kt @@ -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.kotlin.uast + +import org.jetbrains.kotlin.psi.KtAnnotation +import org.jetbrains.uast.UAnnotation +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UastHandler +import org.jetbrains.uast.handleTraverseList +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUAnnotationList( + override val psi: KtAnnotation, + override val parent: UElement +) : UElement, PsiElementBacked { + lateinit var annotations: List + + override fun logString() = "KotlinUAnnotationList" + override fun renderString() = annotations.joinToString(" ") { it.renderString() } + override fun traverse(handler: UastHandler) { + annotations.handleTraverseList(handler) + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUClass.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUClass.kt new file mode 100644 index 00000000000..1dc7f9fb40e --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUClass.kt @@ -0,0 +1,106 @@ +/* + * 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.JetTypeMapper +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.idea.codeInsight.DescriptorToSourceUtilsIde +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 +) : UClass, PsiElementBacked { + override val name: String + get() = psi.name.orAnonymous() + + override val nameElement by lz { KotlinConverter.asSimpleReference(psi.nameIdentifier, this) } + + override val fqName: String? + get() = psi.fqName?.asString() + + override val isEnum: Boolean + get() = (psi as? KtClass)?.isEnum() ?: false + + override val isInterface: Boolean + get() = (psi as? KtClass)?.isInterface() ?: false + + override val isObject: Boolean + get() = psi is KtObjectDeclaration + + override val isAnnotation: Boolean + get() = psi.isAnnotation() + + override val isAnonymous = false + + override val internalName by lz { + val descriptor = resolveToDescriptor() ?: return@lz null + val typeMapper = JetTypeMapper(BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider, null, + IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME) + typeMapper.mapClass(descriptor).internalName + } + + override fun getSuperClass(context: UastContext): UClass? { + val superClass = resolveToDescriptor()?.getSuperClassOrAny() ?: return null + val source = DescriptorToSourceUtilsIde.getAnyDeclaration(psi.project, superClass) ?: return null + return context.convert(source) as? UClass + } + + override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier) + + override val declarations by lz { + val primaryConstructor = psi.getPrimaryConstructor()?.let { KotlinConverter.convert(it, this) } + val declarations = psi.declarations.map { KotlinConverter.convert(it, this) }.filterNotNull() + if (primaryConstructor != null) listOf(primaryConstructor) + declarations else declarations + } + + override val superTypes by lz { + val superTypes = resolveToDescriptor()?.typeConstructor?.supertypes ?: return@lz emptyList() + 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(name: String): Boolean { + val descriptor = psi.resolveToDescriptorIfAny() as? ClassDescriptor ?: return false + return descriptor.defaultType.supertypes().any { + it.constructor.declarationDescriptor?.fqNameSafe?.asString() == name + } + } + + private fun resolveToDescriptor(): ClassDescriptor? { + val bindingContext = psi.analyze(BodyResolveMode.PARTIAL) + return bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, psi] as? ClassDescriptor + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUFile.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUFile.kt new file mode 100644 index 00000000000..71b8b8ec663 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUFile.kt @@ -0,0 +1,31 @@ +/* + * 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): UFile, PsiElementBacked { + override val packageFqName by lz { + val packageName = psi.packageFqName.asString() + if (packageName.isNotBlank()) packageName else null + } + + override val declarations by lz { psi.declarations.map { KotlinConverter.convert(it, this) }.filterNotNull() } + override val importStatements by lz { psi.importDirectives.map { KotlinUImportStatement(it, this) } } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUImportStatement.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUImportStatement.kt new file mode 100644 index 00000000000..a788cbc69d2 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUImportStatement.kt @@ -0,0 +1,32 @@ +/* + * 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.psi.PsiElementBacked + +class KotlinUImportStatement( + override val psi: KtImportDirective, + override val parent: UElement +) : UImportStatement, PsiElementBacked { + override val nameToImport = psi.importedFqName?.asString() + + override val isStarImport: Boolean + get() = psi.isAllUnder +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUType.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUType.kt new file mode 100644 index 00000000000..5c48a3c2fd3 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUType.kt @@ -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.kotlin.uast + +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.typeUtil.isBooleanOrNullableBoolean +import org.jetbrains.uast.* + +class KotlinUType( + val type: KotlinType, + val project: Project, + override val parent: UElement? +) : UType { + override val name: String + get() = type.toString() + + override val fqName: String? + get() = type.constructor.declarationDescriptor?.fqNameSafe?.asString() + + override val isInt = name == "Int" + + override fun resolve(context: UastContext): UClass? { + val descriptor = type.constructor.declarationDescriptor ?: return null + val sourceElement = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) ?: return null + return context.convert(sourceElement) as? UClass + } + + override val isBoolean: Boolean + get() = type.isBooleanOrNullableBoolean() + + //TODO + override val annotations = emptyList() +} + +object KotlinUErrorType : UType, NoAnnotations { + override val isInt = false + override val parent = null + override val name = "" + override val fqName = null + override val isBoolean = false + override fun resolve(context: UastContext) = null +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUVariable.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUVariable.kt new file mode 100644 index 00000000000..0338f4c876f --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUVariable.kt @@ -0,0 +1,106 @@ +/* + * 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.uast.* +import org.jetbrains.uast.psi.PsiElementBacked + +open class KotlinUVariable( + override val psi: KtVariableDeclaration, + override val parent: UElement +) : UVariable, PsiElementBacked { + override val name: String + get() = psi.name.orAnonymous() + + override val nameElement by lz { KotlinConverter.asSimpleReference(psi.nameIdentifier, this) } + + override val initializer by lz { KotlinConverter.convertOrEmpty(psi.initializer, this) } + + override val type by lz { + val descriptor = psi.resolveToDescriptorIfAny() as? CallableDescriptor ?: return@lz KotlinUErrorType + val type = descriptor.returnType ?: return@lz KotlinUErrorType + KotlinConverter.convert(type, psi.project, this) + } + + override val kind: UastVariableKind + get() = when (psi.parent) { + is KtClassBody -> UastVariableKind.MEMBER + is KtClassOrObject -> UastVariableKind.MEMBER + else -> UastVariableKind.LOCAL_VARIABLE + } + + override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier) + override val annotations by lz { psi.getUastAnnotations(this) } +} + +class KotlinDestructuredUVariable( + val entry: KtDestructuringDeclarationEntry, + parent: UElement +) : KotlinUVariable(entry, parent) { + override lateinit var initializer: UExpression + + override val type by lz { + val bindingContext = entry.analyze(BodyResolveMode.PARTIAL) + val resolvedCall = bindingContext[BindingContext.COMPONENT_RESOLVED_CALL, entry] ?: return@lz KotlinUErrorType + val returnType = resolvedCall.resultingDescriptor.returnType ?: return@lz KotlinUErrorType + KotlinConverter.convert(returnType, entry.project, this) + } +} + +class KotlinDestructuringUVariable( + override val psi: KtDestructuringDeclaration, + override val parent: UElement +) : UVariable, PsiElementBacked { + override val name = "var" + psi.text.hashCode() + override val initializer by lz { KotlinConverter.convertOrEmpty(psi.initializer, this) } + override val kind = UastVariableKind.LOCAL_VARIABLE + override val type: UType + get() = initializer.getExpressionType() ?: KotlinUErrorType + + override val nameElement = null + override fun hasModifier(modifier: UastModifier) = false + override val annotations = emptyList() +} + +class KotlinParameterUVariable( + override val psi: KtParameter, + override val parent: UElement +) : UVariable, PsiElementBacked { + override val name: String + get() = psi.name.orAnonymous() + + override val nameElement by lz { KotlinConverter.asSimpleReference(psi.nameIdentifier, this) } + + override val initializer by lz { KotlinConverter.convertOrEmpty(psi.defaultValue, this) } + + 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 KotlinUErrorType + KotlinConverter.convert(param.type, psi.project, this) + } + + override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier) + override val annotations = psi.getUastAnnotations(this) +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/kotlinUFunctions.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/kotlinUFunctions.kt new file mode 100644 index 00000000000..adbc4c6023d --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/kotlinUFunctions.kt @@ -0,0 +1,89 @@ +/* + * 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.FunctionDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny +import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +import org.jetbrains.kotlin.psi.KtConstructor +import org.jetbrains.kotlin.psi.KtFunction +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode +import org.jetbrains.uast.* +import org.jetbrains.uast.psi.PsiElementBacked + +abstract class KotlinAbstractUFunction : 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 { + val bindingContext = psi.analyze(BodyResolveMode.PARTIAL) + val clazz = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, psi] as? FunctionDescriptor ?: return emptyList() + return clazz.overriddenDescriptors.map { + context.convert(DescriptorToSourceUtilsIde.getAnyDeclaration(psi.getProject(), it)) as? UFunction + }.filterNotNull() + } + + override fun hasModifier(modifier: UastModifier) = psi.hasModifier(modifier) + override val annotations by lz { psi.getUastAnnotations(this) } + + override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) } + override val visibility by lz { psi.getVisibility() } +} + +class KotlinConstructorUFunction( + override val psi: KtConstructor<*>, + override val parent: UElement +) : KotlinAbstractUFunction(), PsiElementBacked { + override val nameElement by lz { + val constructorKeyword = psi.getConstructorKeyword()?.let { KotlinPsiElementStub(it, this) } + constructorKeyword ?: this.getContainingFunction()?.nameElement + } + + override val kind = UastFunctionKind.CONSTRUCTOR + + override val typeParameterCount = 0 + override val typeParameters = emptyList() + + override val returnType = null +} + +class KotlinUFunction( + override val psi: KtFunction, + override val parent: UElement +) : KotlinAbstractUFunction(), PsiElementBacked { + override val nameElement by lz { psi.nameIdentifier?.let { KotlinConverter.convert(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) + } + + //TODO + override val typeParameterCount = 0 + override val typeParameters = emptyList() +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinStringTemplateUBinaryExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinStringTemplateUBinaryExpression.kt new file mode 100644 index 00000000000..0489302058b --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinStringTemplateUBinaryExpression.kt @@ -0,0 +1,34 @@ +/* + * 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.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.psi.PsiElementBacked + +class KotlinStringTemplateUBinaryExpression( + override val psi: KtStringTemplateExpression, + override val parent: UElement +) : UBinaryExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override lateinit var leftOperand: UExpression + override lateinit var rightOperand: UExpression + + override val operator = UastBinaryOperator.PLUS +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUArrayAccess.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUArrayAccess.kt new file mode 100644 index 00000000000..3a46461390f --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUArrayAccess.kt @@ -0,0 +1,31 @@ +/* + * 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.KtArrayAccessExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UArrayAccessExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUArrayAccess( + override val psi: KtArrayAccessExpression, + override val parent: UElement +) : UArrayAccessExpression, PsiElementBacked, KotlinTypeHelper, NoEvaluate { + override val receiver by lz { KotlinConverter.convertOrEmpty(psi.arrayExpression, this) } + override val indices by lz { psi.indexExpressions.map { KotlinConverter.convert(it, this) } } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUArrayAccessExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUArrayAccessExpression.kt new file mode 100644 index 00000000000..078051bb197 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUArrayAccessExpression.kt @@ -0,0 +1,30 @@ +/* + * 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.KtArrayAccessExpression +import org.jetbrains.uast.UArrayAccessExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUArrayAccessExpression( + override val psi: KtArrayAccessExpression, + override val parent: UElement +) : UArrayAccessExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override val receiver by lz { KotlinConverter.convertOrEmpty(psi.arrayExpression, this) } + override val indices by lz { psi.indexExpressions.map { KotlinConverter.convert(it, this) } } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpression.kt new file mode 100644 index 00000000000..cb12c2b5111 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpression.kt @@ -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.kotlin.uast + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.uast.* +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUBinaryExpression( + override val psi: KtBinaryExpression, + override val parent: UElement +) : UBinaryExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override val leftOperand by lz { KotlinConverter.convertOrEmpty(psi.left, this) } + override val rightOperand by lz { KotlinConverter.convertOrEmpty(psi.right, this) } + + override val operator = when (psi.operationToken) { + KtTokens.PLUS -> UastBinaryOperator.PLUS + KtTokens.MINUS -> UastBinaryOperator.MINUS + KtTokens.MUL -> UastBinaryOperator.MULT + KtTokens.DIV -> UastBinaryOperator.DIV + KtTokens.PERC -> UastBinaryOperator.MOD + KtTokens.EQEQ -> UastBinaryOperator.EQUALS + KtTokens.EXCLEQ -> UastBinaryOperator.NOT_EQUALS + KtTokens.EQEQEQ -> UastBinaryOperator.IDENTITY_EQUALS + KtTokens.EXCLEQEQEQ -> UastBinaryOperator.IDENTITY_NOT_EQUALS + KtTokens.GT -> UastBinaryOperator.GREATER + KtTokens.GTEQ -> UastBinaryOperator.GREATER_OR_EQUAL + KtTokens.LT -> UastBinaryOperator.LESS + KtTokens.LTEQ -> UastBinaryOperator.LESS_OR_EQUAL + KtTokens.IN_KEYWORD -> KotlinBinaryOperators.IN + KtTokens.NOT_IN -> KotlinBinaryOperators.NOT_IN + else -> UastBinaryOperator.UNKNOWN + } +} + +class KotlinCustomUBinaryExpression( + override val psi: PsiElement, + override val parent: UElement +) : UBinaryExpression, PsiElementBacked, NoEvaluate { + lateinit override var leftOperand: UExpression + lateinit override var operator: UastBinaryOperator + lateinit override var rightOperand: UExpression +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpressionWithType.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpressionWithType.kt new file mode 100644 index 00000000000..37f1d578317 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpressionWithType.kt @@ -0,0 +1,45 @@ +/* + * 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.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS +import org.jetbrains.uast.* +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUBinaryExpressionWithType( + override val psi: KtBinaryExpressionWithTypeRHS, + override val parent: UElement +) : UBinaryExpressionWithType, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override val operand by lz { KotlinConverter.convert(psi.left, this) } + override val type by lz { KotlinConverter.convert(psi.right, this) } + override val operationKind = when (psi.operationReference.getReferencedNameElementType()) { + KtTokens.AS_KEYWORD -> UastBinaryExpressionWithTypeKind.TYPE_CAST + KtTokens.AS_SAFE -> KotlinBinaryExpressionWithTypeKinds.SAFE_TYPE_CAST + else -> UastBinaryExpressionWithTypeKind.UNKNOWN + } +} + +class KotlinCustomUBinaryExpressionWithType( + override val psi: PsiElement, + override val parent: UElement +) : UBinaryExpressionWithType, PsiElementBacked, NoEvaluate { + lateinit override var operand: UExpression + lateinit override var operationKind: UastBinaryExpressionWithTypeKind + lateinit override var type: UType +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBlockExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBlockExpression.kt new file mode 100644 index 00000000000..fbc5014998e --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBlockExpression.kt @@ -0,0 +1,30 @@ +/* + * 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.KtBlockExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UBlockExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUBlockExpression( + override val psi: KtBlockExpression, + override val parent: UElement +) : UBlockExpression, PsiElementBacked, KotlinTypeHelper, NoEvaluate { + override val expressions by lz { psi.statements.map { KotlinConverter.convertOrEmpty(it, this) } } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUCatchClause.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUCatchClause.kt new file mode 100644 index 00000000000..f2b11dd4955 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUCatchClause.kt @@ -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.kotlin.uast + +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.psi.PsiElementBacked + +class KotlinUCatchClause( + override val psi: KtCatchClause, + override val parent: UElement +) : 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() } + override val types by lz { + val catchParameter = psi.catchParameter ?: return@lz emptyList() + val bindingContext = psi.analyze(BodyResolveMode.PARTIAL) + val parameter = bindingContext[BindingContext.VALUE_PARAMETER, catchParameter] ?: return@lz emptyList() + listOf(KotlinConverter.convert(parameter.type, psi.project, this)) + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUDeclarationsExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUDeclarationsExpression.kt new file mode 100644 index 00000000000..121923bfcba --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUDeclarationsExpression.kt @@ -0,0 +1,21 @@ +/* + * 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 + +class KotlinUDeclarationsExpression(override val parent: UElement) : UDeclarationsExpression { + override lateinit var declarations: List + override fun evaluate() = null +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUDoWhileExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUDoWhileExpression.kt new file mode 100644 index 00000000000..90f5f083815 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUDoWhileExpression.kt @@ -0,0 +1,31 @@ +/* + * 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.KtDoWhileExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UDoWhileExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUDoWhileExpression( + override val psi: KtDoWhileExpression, + override val parent: UElement +) : UDoWhileExpression, PsiElementBacked, NoEvaluate { + override val condition by lz { KotlinConverter.convertOrEmpty(psi.condition, this) } + override val body by lz { KotlinConverter.convertOrEmpty(psi.body, this) } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUExpression.kt new file mode 100644 index 00000000000..b25502b7670 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUExpression.kt @@ -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.kotlin.uast + +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.UExpression +import org.jetbrains.uast.UType +import org.jetbrains.uast.psi.PsiElementBacked + +interface KotlinTypeHelper : UExpression, PsiElementBacked { + override fun getExpressionType(): UType? { + val ktElement = psi as? KtExpression ?: return null + val ktType = ktElement.analyze(BodyResolveMode.PARTIAL)[BindingContext.EXPECTED_EXPRESSION_TYPE, ktElement] ?: return null + return KotlinConverter.convert(ktType, ktElement.project, null) + } +} + +interface KotlinEvaluateHelper : UExpression, PsiElementBacked { + override fun evaluate(): Any? { + val ktElement = psi as? KtExpression ?: return null + val compileTimeConst = ktElement.analyze(BodyResolveMode.PARTIAL)[BindingContext.COMPILE_TIME_VALUE, ktElement] + return compileTimeConst?.getValue(TypeUtils.NO_EXPECTED_TYPE) + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUForEachExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUForEachExpression.kt new file mode 100644 index 00000000000..cc882f0e205 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUForEachExpression.kt @@ -0,0 +1,32 @@ +/* + * 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.KtForExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UForEachExpression +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUForEachExpression( + override val psi: KtForExpression, + override val parent: UElement +) : UForEachExpression, PsiElementBacked, NoEvaluate { + override val variableName by lz { psi.loopParameter?.name } + override val iteratedValue by lz { KotlinConverter.convertOrEmpty(psi.loopRange, this) } + override val body by lz { KotlinConverter.convertOrEmpty(psi.body, this) } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUFunctionCallExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUFunctionCallExpression.kt new file mode 100644 index 00000000000..91aea7f479f --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUFunctionCallExpression.kt @@ -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.kotlin.uast + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ConstructorDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +import org.jetbrains.kotlin.psi.KtCallExpression +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +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 + +class KotlinUFunctionCallExpression( + override val psi: KtCallExpression, + override val parent: UElement +) : UCallExpression, PsiElementBacked, KotlinTypeHelper, NoEvaluate { + override val functionName: String? + get() = (psi.calleeExpression as? KtSimpleNameExpression)?.getReferencedName() + + 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 + KotlinUSimpleReferenceExpression(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 (resolveCall()?.resultingDescriptor) { + is ConstructorDescriptor -> UastCallKind.CONSTRUCTOR_CALL + else -> UastCallKind.FUNCTION_CALL + } + } + + override fun resolve(context: UastContext): UFunction? { + val resultingDescriptor = resolveCall()?.resultingDescriptor ?: return null + val source = DescriptorToSourceUtilsIde.getAnyDeclaration(psi.project, resultingDescriptor) ?: return null + return context.convert(source) as? UFunction + } + + private fun resolveCall() = psi.getResolvedCall(psi.analyze(BodyResolveMode.PARTIAL)) +} + +class KotlinUComponentFunctionCallExpression( + override val psi: PsiElement, + val n: Int, + override val parent: UElement +) : UCallExpression, PsiElementBacked, NoEvaluate { + override val valueArgumentCount = 0 + override val valueArguments = emptyList() + override val typeArgumentCount = 0 + override val typeArguments = emptyList() + override val classReference = null + override val functionName = "component$n" + override val functionReference by lz { KotlinStringUSimpleReferenceExpression(functionName, this) } + override val functionNameElement = null + override val kind = UastCallKind.FUNCTION_CALL + override fun resolve(context: UastContext) = null +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUIfExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUIfExpression.kt new file mode 100644 index 00000000000..98426c6b0d5 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUIfExpression.kt @@ -0,0 +1,32 @@ +/* + * 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.KtIfExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UIfExpression +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUIfExpression( + override val psi: KtIfExpression, + override val parent: UElement +) : UIfExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + 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 isTernary = false +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinULambdaExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinULambdaExpression.kt new file mode 100644 index 00000000000..5b700c1b3ca --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinULambdaExpression.kt @@ -0,0 +1,39 @@ +/* + * 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.* +import org.jetbrains.uast.* +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinULambdaExpression( + override val psi: KtLambdaExpression, + override val parent: UElement +) : ULambdaExpression, PsiElementBacked, KotlinTypeHelper, NoEvaluate { + 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 { + val renderedValueParameters = if (valueParameters.isEmpty()) + "" + else + valueParameters.joinToString { it.renderString() } + " ->\n" + val expressions = (body as? UBlockExpression)?.expressions + ?.joinToString("\n") { it.renderString().withMargin } ?: body.renderString() + + return "{ " + renderedValueParameters + "\n" + expressions + "\n}" + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinULiteralExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinULiteralExpression.kt new file mode 100644 index 00000000000..cef75f6aaf3 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinULiteralExpression.kt @@ -0,0 +1,51 @@ +/* + * 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.idea.intentions.branchedTransformations.isNullExpression +import org.jetbrains.kotlin.psi.KtConstantExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.ULiteralExpression +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinULiteralExpression( + override val psi: KtConstantExpression, + override val parent: UElement +) : ULiteralExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override val isNull: Boolean + get() = psi.isNullExpression() + + override val text: String + get() = psi.text + + override val value by lz { evaluate() } +} + +class KotlinStringULiteralExpression( + override val psi: PsiElement, + override val parent: UElement +) : ULiteralExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override val isNull = false + override val text: String + get() = '"' + psi.text + '"' + + override val value: String + get() = psi.text + + override fun evaluate() = psi.text +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUParenthesizedExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUParenthesizedExpression.kt new file mode 100644 index 00000000000..f82a2f07edc --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUParenthesizedExpression.kt @@ -0,0 +1,29 @@ +/* + * 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.KtParenthesizedExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UParenthesizedExpression +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUParenthesizedExpression( + override val psi: KtParenthesizedExpression, + override val parent: UElement +) : UParenthesizedExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override val expression by lz { KotlinConverter.convertOrEmpty(psi.expression, this) } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUPostfixExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUPostfixExpression.kt new file mode 100644 index 00000000000..654c917cae3 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUPostfixExpression.kt @@ -0,0 +1,39 @@ +/* + * 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.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtPostfixExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UPostfixExpression +import org.jetbrains.uast.UastPostfixOperator +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUPostfixExpression( + override val psi: KtPostfixExpression, + override val parent: UElement +) : UPostfixExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override val operand by lz { KotlinConverter.convertOrEmpty(psi.baseExpression, this) } + + override val operator = when (psi.operationToken) { + KtTokens.PLUSPLUS -> UastPostfixOperator.INC + KtTokens.MINUSMINUS -> UastPostfixOperator.DEC + KtTokens.EXCLEXCL -> KotlinPostfixOperators.EXCLEXCL + else -> UastPostfixOperator.UNKNOWN + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUPrefixExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUPrefixExpression.kt new file mode 100644 index 00000000000..9818b01d490 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUPrefixExpression.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.uast + +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtPrefixExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UElement +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 +) : UPrefixExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override val operand by lz { KotlinConverter.convertOrEmpty(psi.baseExpression, this) } + + override val operator = when (psi.operationToken) { + KtTokens.PLUS -> UastPrefixOperator.UNARY_PLUS + KtTokens.MINUS -> UastPrefixOperator.UNARY_MINUS + KtTokens.PLUSPLUS -> UastPrefixOperator.INC + KtTokens.MINUSMINUS -> UastPrefixOperator.DEC + else -> UastPrefixOperator.UNKNOWN + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUQualifiedExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUQualifiedExpression.kt new file mode 100644 index 00000000000..cb644636f09 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUQualifiedExpression.kt @@ -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.kotlin.uast + +import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry +import org.jetbrains.kotlin.psi.KtDotQualifiedExpression +import org.jetbrains.uast.* +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUQualifiedExpression( + override val psi: KtDotQualifiedExpression, + override val parent: UElement +) : UQualifiedExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + 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(context: UastContext) = psi.selectorExpression.resolveCallToUDeclaration(context) +} + +class KotlinUComponentQualifiedExpression( + override val psi: KtDestructuringDeclarationEntry, + override val parent: UElement +) : UQualifiedExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override lateinit var receiver: UExpression + override lateinit var selector: UExpression + override val accessType = UastQualifiedExpressionAccessType.SIMPLE + override fun resolve(context: UastContext) = null +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSafeQualifiedExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSafeQualifiedExpression.kt new file mode 100644 index 00000000000..9b300157d22 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSafeQualifiedExpression.kt @@ -0,0 +1,35 @@ +/* + * 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.KtSafeQualifiedExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UQualifiedExpression +import org.jetbrains.uast.UastContext +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUSafeQualifiedExpression( + override val psi: KtSafeQualifiedExpression, + override val parent: UElement +) : UQualifiedExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + 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) +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSimpleReferenceExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSimpleReferenceExpression.kt new file mode 100644 index 00000000000..57d2b8d3d5d --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSimpleReferenceExpression.kt @@ -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.kotlin.uast + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ConstructorDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +import org.jetbrains.kotlin.psi.KtCallExpression +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 + +class KotlinUSimpleReferenceExpression( + override val psi: PsiElement, + override val identifier: String, + override val parent: UElement +) : USimpleReferenceExpression, PsiElementBacked, KotlinTypeHelper, NoEvaluate { + override fun resolve(context: UastContext) = context.convert( + psi.references.firstOrNull()?.resolve()) as? UDeclaration +} + +class KotlinClassViaConstructorUSimpleReferenceExpression( + override val psi: KtCallExpression, + override val identifier: String, + override val parent: UElement +) : USimpleReferenceExpression, PsiElementBacked, KotlinTypeHelper, NoEvaluate { + 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 = DescriptorToSourceUtilsIde.getAnyDeclaration(psi.project, clazz) ?: return null + return context.convert(source) as? UClass + } +} + +class KotlinStringUSimpleReferenceExpression( + override val identifier: String, + override val parent: UElement +) : USimpleReferenceExpression, NoEvaluate { + override fun resolve(context: UastContext) = null +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSpecialExpressionList.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSpecialExpressionList.kt new file mode 100644 index 00000000000..f8a7d3ce844 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSpecialExpressionList.kt @@ -0,0 +1,48 @@ +/* + * 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.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.UastSpecialExpressionKind +import org.jetbrains.uast.psi.PsiElementBacked + +open class KotlinUSpecialExpressionList( + override val psi: PsiElement, + override val kind: UastSpecialExpressionKind, // original element + override val parent: UElement +) : USpecialExpressionList, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + class Empty(psi: PsiElement, expressionType: UastSpecialExpressionKind, parent: UElement) : + KotlinUSpecialExpressionList(psi, expressionType, parent) { + init { expressions = emptyList() } + } + + override lateinit var expressions: List + + override fun evaluate(): Any? { + val ktElement = psi as? KtExpression ?: return null + val compileTimeConst = ktElement.analyze(BodyResolveMode.PARTIAL)[BindingContext.COMPILE_TIME_VALUE, ktElement] + return compileTimeConst?.getValue(TypeUtils.NO_EXPECTED_TYPE) + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSuperExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSuperExpression.kt new file mode 100644 index 00000000000..8e97a7b09a1 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSuperExpression.kt @@ -0,0 +1,27 @@ +/* + * 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.KtSuperExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.USuperExpression +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUSuperExpression( + override val psi: KtSuperExpression, + override val parent: UElement +) : USuperExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSwitchExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSwitchExpression.kt new file mode 100644 index 00000000000..d314b8061a4 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSwitchExpression.kt @@ -0,0 +1,107 @@ +/* + * 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.* +import org.jetbrains.kotlin.uast.kinds.KotlinSpecialExpressionKinds +import org.jetbrains.uast.* +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUSwitchExpression( + override val psi: KtWhenExpression, + override val parent: UElement +) : USwitchExpression, PsiElementBacked, KotlinTypeHelper, NoEvaluate { + override val expression by lz { KotlinConverter.convertOrNull(psi.subjectExpression, this) } + + //TODO to entries + override val body: UExpression by lz { + object : KotlinUSpecialExpressionList(psi, KotlinSpecialExpressionKinds.WHEN, this) { + override fun renderString() = expressions.joinToString("\n") { it.renderString().withMargin } + }.apply { + expressions = this@KotlinUSwitchExpression.psi.entries.map { KotlinUSwitchEntry(it, this) } + } + } + + override fun renderString() = buildString { + val expr = expression?.let { "(" + it.renderString() + ") " } ?: "" + appendln("switch $expr {") + appendln(body.renderString()) + appendln("}") + } +} + +class KotlinUSwitchEntry( + override val psi: KtWhenEntry, + override val parent: UExpression +) : UExpression, PsiElementBacked, NoEvaluate { + val conditions by lz { + psi.conditions.map { when (it) { + is KtWhenConditionInRange -> KotlinCustomUBinaryExpression(it, this).apply { + leftOperand = KotlinStringUSimpleReferenceExpression("it", this) + operator = when { + it.isNegated -> KotlinBinaryOperators.NOT_IN + else -> KotlinBinaryOperators.IN + } + rightOperand = KotlinConverter.convertOrEmpty(it.rangeExpression, this) + } + is KtWhenConditionIsPattern -> KotlinCustomUBinaryExpressionWithType(it, this).apply { + operand = KotlinStringUSimpleReferenceExpression("it", this) + operationKind = when { + it.isNegated -> KotlinBinaryExpressionWithTypeKinds.NEGATED_INSTANCE_CHECK + else -> UastBinaryExpressionWithTypeKind.INSTANCE_CHECK + } + type = KotlinConverter.convert(it.typeReference, this) + } + is KtWhenConditionWithExpression -> KotlinConverter.convertOrEmpty(it.expression, this) + else -> EmptyExpression(this) + }} + } + + val expression: UExpression by lz { + object : KotlinUSpecialExpressionList(psi, KotlinSpecialExpressionKinds.WHEN_ENTRY, this) { + override fun renderString() = buildString { + appendln("{") + expressions.forEach { appendln(it.renderString().withMargin) } + appendln("}") + } + }.apply { + val exprPsi = this@KotlinUSwitchEntry.psi.expression + val userExpressions = when (exprPsi) { + is KtBlockExpression -> exprPsi.statements.map { KotlinConverter.convert(it, this) } + else -> listOf(KotlinConverter.convertOrEmpty(exprPsi, this)) + } + expressions = userExpressions + KotlinUSpecialExpressionList.Empty( + exprPsi ?: this@KotlinUSwitchEntry.psi, UastSpecialExpressionKind.BREAK, parent) + } + } + + override fun renderString() = buildString { + if (conditions.isEmpty()) { + append("else") + } else { + append(conditions.joinToString { it.renderString() }) + } + append(" -> ") + append(expression.renderString()) + } + + override fun logString() = log("KotlinUSwitchEntry", expression) + + override fun traverse(handler: UastHandler) { + expression.handleTraverse(handler) + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUThisExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUThisExpression.kt new file mode 100644 index 00000000000..e2eabc7e64c --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUThisExpression.kt @@ -0,0 +1,28 @@ +/* + * 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.KtThisExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UThisExpression +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUThisExpression( + override val psi: KtThisExpression, + override val parent: UElement +) : UThisExpression, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTryExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTryExpression.kt new file mode 100644 index 00000000000..a5df1189d3c --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTryExpression.kt @@ -0,0 +1,32 @@ +/* + * 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.KtTryExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UTryExpression +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUTryExpression( + override val psi: KtTryExpression, + override val parent: UElement +) : UTryExpression, PsiElementBacked, KotlinTypeHelper, NoEvaluate { + override val tryClause by lz { KotlinConverter.convert(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) } } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTypeCheckExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTypeCheckExpression.kt new file mode 100644 index 00000000000..abe28b15617 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTypeCheckExpression.kt @@ -0,0 +1,31 @@ +/* + * 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.KtIsExpression +import org.jetbrains.uast.UBinaryExpressionWithType +import org.jetbrains.uast.UElement +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUTypeCheckExpression( + override val psi: KtIsExpression, + override val parent: UElement +) : UBinaryExpressionWithType, PsiElementBacked, KotlinTypeHelper, KotlinEvaluateHelper { + override val operand by lz { KotlinConverter.convert(psi.leftHandSide, this) } + override val type by lz { KotlinConverter.convert(psi.typeReference, this) } + override val operationKind = KotlinBinaryExpressionWithTypeKinds.NEGATED_INSTANCE_CHECK +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUWhileExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUWhileExpression.kt new file mode 100644 index 00000000000..90ad562d832 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUWhileExpression.kt @@ -0,0 +1,31 @@ +/* + * 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.KtWhileExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UWhileExpression +import org.jetbrains.uast.psi.PsiElementBacked + +class KotlinUWhileExpression( + override val psi: KtWhileExpression, + override val parent: UElement +) : UWhileExpression, PsiElementBacked, NoEvaluate { + override val condition by lz { KotlinConverter.convertOrEmpty(psi.condition, this) } + override val body by lz { KotlinConverter.convertOrEmpty(psi.body, this) } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/UnknownKotlinExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/UnknownKotlinExpression.kt new file mode 100644 index 00000000000..e6d524df43d --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/UnknownKotlinExpression.kt @@ -0,0 +1,32 @@ +/* + * 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.KtExpression +import org.jetbrains.uast.NoEvaluate +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UExpression +import org.jetbrains.uast.UastHandler +import org.jetbrains.uast.psi.PsiElementBacked + +class UnknownKotlinExpression( + override val psi: KtExpression, + override val parent: UElement +) : UExpression, PsiElementBacked, NoEvaluate { + override fun traverse(handler: UastHandler) {} + override fun logString() = "[!] UnknownKotlinExpression ($psi)" +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/internal/kotlinInternalUastUtils.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/internal/kotlinInternalUastUtils.kt new file mode 100644 index 00000000000..09de56ed1ea --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/internal/kotlinInternalUastUtils.kt @@ -0,0 +1,77 @@ +/* + * 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.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtAnnotated +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtModifierListOwner +import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType +import org.jetbrains.kotlin.resolve.BindingContext +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 MODIFIER_MAP = mapOf( + UastModifier.ABSTRACT to KtTokens.ABSTRACT_KEYWORD, + UastModifier.INNER to KtTokens.INNER_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 { + val javaModifier = MODIFIER_MAP[modifier] ?: return false + return hasModifier(javaModifier) +} + +internal fun runReadAction(action: () -> T): T { + return ApplicationManager.getApplication().runReadAction(action) +} + +internal fun KtElement?.resolveCallToUDeclaration(context: UastContext): UDeclaration? { + if (this == null) return null + val resolvedCall = this.getResolvedCall(analyze(BodyResolveMode.PARTIAL)) ?: return null + val source = DescriptorToSourceUtilsIde.getAnyDeclaration(project, resolvedCall.resultingDescriptor) ?: return null + return context.convert(source) as? UDeclaration +} + +internal fun KtElement?.resolveElementToUDeclaration(context: UastContext): UDeclaration? { + if (this == null) return null + val bindingContext = analyze(BodyResolveMode.PARTIAL) + val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, this] ?: return null + val source = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) ?: return null + return context.convert(source) as? UDeclaration +} + +@Suppress("NOTHING_TO_INLINE") +internal inline fun String?.orAnonymous(kind: String = ""): String { + return this ?: "" +} + +internal fun KtAnnotated.getUastAnnotations(parent: UElement) = annotationEntries.map { KotlinUAnnotation(it, parent) } + +internal fun singletonListOrEmpty(element: T?) = if (element != null) listOf(element) else emptyList() \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/internal/lz.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/internal/lz.kt new file mode 100644 index 00000000000..64c4868380d --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/internal/lz.kt @@ -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.kotlin.uast + +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty + +internal fun lz(initializer: () -> T): ReadOnlyProperty = UnsafeLazyInsideReadAction(initializer, false) + +private class UnsafeLazyInsideReadAction(initializer: () -> T, private val readAction: Boolean) : ReadOnlyProperty { + private var initializer: (() -> T)? = initializer + private var _value: Any? = UNINITIALIZED_VALUE + + override fun getValue(thisRef: Any, property: KProperty<*>): T { + if (_value === UNINITIALIZED_VALUE) { + if (readAction) { + _value = runReadAction { initializer!!() } + } + else { + _value = initializer!!() + } + initializer = null + } + return _value as T + } +} + +private object UNINITIALIZED_VALUE \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinBinaryExpressionWithTypeKinds.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinBinaryExpressionWithTypeKinds.kt new file mode 100644 index 00000000000..3c3ec5c2578 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinBinaryExpressionWithTypeKinds.kt @@ -0,0 +1,27 @@ +/* + * 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.UastBinaryExpressionWithTypeKind + +object KotlinBinaryExpressionWithTypeKinds { + @JvmField + val NEGATED_INSTANCE_CHECK = UastBinaryExpressionWithTypeKind("!is") + + @JvmField + val SAFE_TYPE_CAST = UastBinaryExpressionWithTypeKind("!is") +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinBinaryOperators.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinBinaryOperators.kt new file mode 100644 index 00000000000..2e3447f424c --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinBinaryOperators.kt @@ -0,0 +1,26 @@ +/* + * 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.UastBinaryOperator + +object KotlinBinaryOperators { + @JvmField + val IN = UastBinaryOperator("in") + @JvmField + val NOT_IN = UastBinaryOperator("!in") +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinPostfixOperators.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinPostfixOperators.kt new file mode 100644 index 00000000000..43f3e969dfd --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinPostfixOperators.kt @@ -0,0 +1,24 @@ +/* + * 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.UastPostfixOperator + +object KotlinPostfixOperators { + @JvmField + val EXCLEXCL = UastPostfixOperator("!!") +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinQualifiedExpressionAccessTypes.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinQualifiedExpressionAccessTypes.kt new file mode 100644 index 00000000000..99d90a4f67f --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinQualifiedExpressionAccessTypes.kt @@ -0,0 +1,24 @@ +/* + * 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.UastQualifiedExpressionAccessType + +object KotlinQualifiedExpressionAccessTypes { + @JvmField + val SAFE = UastQualifiedExpressionAccessType("?.") +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinSpecialExpressionKinds.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinSpecialExpressionKinds.kt new file mode 100644 index 00000000000..b0ab489f9c9 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinSpecialExpressionKinds.kt @@ -0,0 +1,30 @@ +/* + * 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.UastSpecialExpressionKind + +object KotlinSpecialExpressionKinds { + @JvmField + val WHEN = UastSpecialExpressionKind("when") + + @JvmField + val WHEN_ENTRY = UastSpecialExpressionKind("when_entry") + + @JvmField + val DESTRUCTURING = UastSpecialExpressionKind("destructuring") +} \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinUastVisibilities.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinUastVisibilities.kt new file mode 100644 index 00000000000..605003484cd --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/kinds/KotlinUastVisibilities.kt @@ -0,0 +1,24 @@ +/* + * 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") +} \ No newline at end of file diff --git a/plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/AbstractKotlinUastStructureTest.kt b/plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/AbstractKotlinUastStructureTest.kt new file mode 100644 index 00000000000..68523225870 --- /dev/null +++ b/plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/AbstractKotlinUastStructureTest.kt @@ -0,0 +1,50 @@ +/* + * 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.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor +import org.jetbrains.kotlin.test.KotlinTestUtils +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 psiFile = myFixture.file + val uElement = KotlinConverter.convertWithParent(psiFile) ?: error("UFile was not created") + + val logActual = uElement.logString() + val renderActual = uElement.renderString() + + try { + KotlinTestUtils.assertEqualsToFile(logFile, logActual) + } catch (e: Throwable) { + KotlinTestUtils.assertEqualsToFile(renderFile, renderActual) + throw e + } + KotlinTestUtils.assertEqualsToFile(renderFile, renderActual) + } + + override fun getTestDataPath() = "plugins/uast-kotlin/testData" + + override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE +} \ No newline at end of file diff --git a/plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/KotlinUastStructureTest.kt b/plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/KotlinUastStructureTest.kt new file mode 100644 index 00000000000..180eec6eed9 --- /dev/null +++ b/plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/KotlinUastStructureTest.kt @@ -0,0 +1,25 @@ +/* + * 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.test.TestMetadata + +class KotlinUastStructureTest : AbstractKotlinUastStructureTest() { + @TestMetadata("Simple.kt") fun testSimple() = doTest() + @TestMetadata("Declarations.kt") fun testDeclarations() = doTest() + @TestMetadata("ControlStructures.kt") fun testControlStructures() = doTest() +} \ No newline at end of file diff --git a/plugins/uast-kotlin/testData/ControlStructures.kt b/plugins/uast-kotlin/testData/ControlStructures.kt new file mode 100644 index 00000000000..eaff37c7ecf --- /dev/null +++ b/plugins/uast-kotlin/testData/ControlStructures.kt @@ -0,0 +1,59 @@ +class ControlStructures { + fun test(): Boolean { + if (5 > 3) { + println("5 > 3") + } + + for (c in "ABC") { + println(c) + } + + for (c: Char in "DEF") { + println(c.toByte()) + } + + var i = 5 + while (i > 0) { + i-- + if (i == 3) break + if (i == 2) { + continue + } + } + + i = 5 + do { + i -= 1 + } while (i > 0) + + "ABC".forEach { println(it.toString()[0]) } + + "ABC".zip("DEF").forEach { println(it.first + " " + it.second) } + + val (a, b) = "ABC".zip("DEF") + + val value = if (5 > 3) "a" else "b" + val list = listOf("A") + val list2 = listOf("A") + + val type = when (value) { + in list -> "inlist" + !in list2 -> "notinlist2" + is String -> "string" + is CharSequence -> "cs" + else -> "unknown" + } + + val x = when { + value == "b" -> "B" + 5 % 2 == 0 -> { + println("A") + "Q" + } + false -> "!" + else -> "A" + } + + return false + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/testData/Declarations.kt b/plugins/uast-kotlin/testData/Declarations.kt new file mode 100644 index 00000000000..bb423f89146 --- /dev/null +++ b/plugins/uast-kotlin/testData/Declarations.kt @@ -0,0 +1,13 @@ +class Declarations { + val a: String = "a" + class NestedClass { + val b: String = "b" + } + inner class InnerClass { + val c: CharSequence = a + } + + fun func(a: Int, b: String): Int { + return (a + 1) * b.length + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/testData/Simple.kt b/plugins/uast-kotlin/testData/Simple.kt new file mode 100644 index 00000000000..ddc3292f925 --- /dev/null +++ b/plugins/uast-kotlin/testData/Simple.kt @@ -0,0 +1,8 @@ +class Simple { + val a: String = "text" + "other" + "text" + val b = listOf("A") + + fun test() { + System.out.println(5.0f / 2) + } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/testData/log/ControlStructures.txt b/plugins/uast-kotlin/testData/log/ControlStructures.txt new file mode 100644 index 00000000000..727f223f81a --- /dev/null +++ b/plugins/uast-kotlin/testData/log/ControlStructures.txt @@ -0,0 +1,11 @@ +UFile (package = null) + UClass (ControlStructures, enum = false, interface = false, object = false) + UFunction (test, kind = function, paramCount = 0) + UBlockExpression + UDeclarationsExpression + UVariable (x, kind = local) + UFunctionCallExpression (FUNCTION_CALL, argCount = 1) + USimpleReferenceExpression (listOf) + ULiteralExpression ("ABC") + USpecialExpressionList (return) + ULiteralExpression (false) diff --git a/plugins/uast-kotlin/testData/log/Declarations.txt b/plugins/uast-kotlin/testData/log/Declarations.txt new file mode 100644 index 00000000000..297a4ee6992 --- /dev/null +++ b/plugins/uast-kotlin/testData/log/Declarations.txt @@ -0,0 +1,21 @@ +UFile (package = null) + UClass (Declarations, enum = false, interface = false, object = false) + UVariable (a, kind = member) + ULiteralExpression ("a") + UClass (NestedClass, enum = false, interface = false, object = false) + UVariable (b, kind = member) + ULiteralExpression ("b") + UClass (InnerClass, enum = false, interface = false, object = false) + UVariable (c, kind = member) + USimpleReferenceExpression (a) + UFunction (func, kind = function, paramCount = 2) + UBlockExpression + USpecialExpressionList (return) + UBinaryExpression (*) + UParenthesizedExpression + UBinaryExpression (+) + USimpleReferenceExpression (a) + ULiteralExpression (1) + UQualifiedExpression + USimpleReferenceExpression (b) + USimpleReferenceExpression (length) diff --git a/plugins/uast-kotlin/testData/log/Simple.txt b/plugins/uast-kotlin/testData/log/Simple.txt new file mode 100644 index 00000000000..6496ac3caa1 --- /dev/null +++ b/plugins/uast-kotlin/testData/log/Simple.txt @@ -0,0 +1,19 @@ +UFile (package = null) + UClass (Simple, enum = false, interface = false, object = false) + UVariable (a, kind = member) + UBinaryExpression (+) + UBinaryExpression (+) + ULiteralExpression ("text") + ULiteralExpression ("other") + ULiteralExpression ("text") + UFunction (test, kind = function, paramCount = 0) + UBlockExpression + UQualifiedExpression + UQualifiedExpression + USimpleReferenceExpression (System) + USimpleReferenceExpression (out) + UFunctionCallExpression (FUNCTION_CALL, argCount = 1) + USimpleReferenceExpression (println) + UBinaryExpression (/) + ULiteralExpression (5.0f) + ULiteralExpression (2) diff --git a/plugins/uast-kotlin/testData/render/ControlStructures.txt b/plugins/uast-kotlin/testData/render/ControlStructures.txt new file mode 100644 index 00000000000..6bc8e8b5a80 --- /dev/null +++ b/plugins/uast-kotlin/testData/render/ControlStructures.txt @@ -0,0 +1,7 @@ +public class ControlStructures { + public fun test(): Boolean { + var x: List = listOf("ABC") + return false + } + +} diff --git a/plugins/uast-kotlin/testData/render/Declarations.txt b/plugins/uast-kotlin/testData/render/Declarations.txt new file mode 100644 index 00000000000..097cf604522 --- /dev/null +++ b/plugins/uast-kotlin/testData/render/Declarations.txt @@ -0,0 +1,16 @@ +public class Declarations { + var a: String = "a" + + public class NestedClass { + var b: String = "b" + + } + public inner class InnerClass { + var c: CharSequence = a + + } + public fun func(a: Int, b: String): Int { + return (a + 1) * b.length + } + +} diff --git a/plugins/uast-kotlin/testData/render/Simple.txt b/plugins/uast-kotlin/testData/render/Simple.txt new file mode 100644 index 00000000000..24f2786c257 --- /dev/null +++ b/plugins/uast-kotlin/testData/render/Simple.txt @@ -0,0 +1,9 @@ +public class Simple { + var a: String = "text" + "other" + "text" + val b = listOf("A") + + public fun test(): Unit { + System.out.println(5.0f / 2) + } + +} diff --git a/plugins/uast-kotlin/uast-kotlin.iml b/plugins/uast-kotlin/uast-kotlin.iml new file mode 100644 index 00000000000..486fbdd1427 --- /dev/null +++ b/plugins/uast-kotlin/uast-kotlin.iml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file