From 4bb373127251fb8068d37ed1942f1d93059f1922 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 31 May 2012 21:48:51 +0200 Subject: [PATCH] comments support work in progress --- src/org/jetbrains/jet/j2k/Converter.kt | 57 ++++++++++++------- .../jetbrains/jet/j2k/ast/AnonymousClass.kt | 3 +- src/org/jetbrains/jet/j2k/ast/Class.kt | 34 +++++------ src/org/jetbrains/jet/j2k/ast/Element.kt | 8 ++- src/org/jetbrains/jet/j2k/ast/Enum.kt | 6 +- src/org/jetbrains/jet/j2k/ast/File.kt | 4 +- src/org/jetbrains/jet/j2k/ast/Node.kt | 3 - src/org/jetbrains/jet/j2k/ast/Trait.kt | 4 +- .../jet/j2k/visitors/ElementVisitor.kt | 4 ++ tests/testData/ast/issues/file/comments.jav | 14 +++++ tests/testData/ast/issues/file/comments.kt | 4 ++ .../testData/ast/issues/file/kt-824-isDir.kt | 3 + 12 files changed, 91 insertions(+), 53 deletions(-) create mode 100644 tests/testData/ast/issues/file/comments.jav create mode 100644 tests/testData/ast/issues/file/comments.kt diff --git a/src/org/jetbrains/jet/j2k/Converter.kt b/src/org/jetbrains/jet/j2k/Converter.kt index be9e9dbb67c..c7b3f0bebb2 100644 --- a/src/org/jetbrains/jet/j2k/Converter.kt +++ b/src/org/jetbrains/jet/j2k/Converter.kt @@ -47,16 +47,20 @@ public open class Converter() { classIdentifiers.clear() } - public open fun elementToKotlin(element: PsiElement): String = - when(element) { - is PsiJavaFile -> fileToFile(element).toKotlin() - is PsiClass -> classToClass(element).toKotlin() - is PsiMethod -> methodToFunction(element).toKotlin() - is PsiField -> fieldToField(element, element.getContainingClass()).toKotlin() - is PsiStatement -> statementToStatement(element).toKotlin() - is PsiExpression -> expressionToExpression(element).toKotlin() - else -> "" + public open fun elementToKotlin(element: PsiElement): String { + val kElement = topElementToElement(element) + return kElement?.toKotlin() ?: "" + } + public open fun topElementToElement(element: PsiElement?): Node? = when(element) { + is PsiJavaFile -> fileToFile(element) + is PsiClass -> classToClass(element) + is PsiMethod -> methodToFunction(element) + is PsiField -> fieldToField(element, element.getContainingClass()) + is PsiStatement -> statementToStatement(element) + is PsiExpression -> expressionToExpression(element) + is PsiComment -> Comment(element.getText()!!) + else -> null } public open fun fileToFile(javaFile: PsiJavaFile): File { @@ -75,29 +79,41 @@ public open class Converter() { importsToImportList(importList.getAllImportStatements())) for (i : String in additionalImports) imports.add(Import(i)) - return File(quoteKeywords(javaFile.getPackageName()), imports, classesToClassList(javaFile.getClasses()), createMainFunction(javaFile)) - } - private fun classesToClassList(classes: Array): List = classes.map { classToClass(it!!) } + val body: ArrayList = arrayList() + for(element in javaFile.getChildren()) { + if (element !is PsiImportStatementBase) { + val node = topElementToElement(element) + if (node != null) { + body.add(node) + } + } + } + return File(quoteKeywords(javaFile.getPackageName()), imports, body, createMainFunction(javaFile)) + } public open fun anonymousClassToAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass { - return AnonymousClass(this, getMembers(anonymousClass)) + return AnonymousClass(this, getMembers(anonymousClass, false)) } - private fun getMembers(psiClass: PsiClass): List { - val members: List = arrayList() + private fun getMembers(psiClass: PsiClass, takeDocComments: Boolean): List { + val members: List = arrayList() + val lbraceOffset = psiClass.getLBrace()?.getTextRange()?.getStartOffset() ?: 0 for (e : PsiElement? in psiClass.getChildren()) { + val isDocComment = e?.getTextRange()?.getStartOffset() ?: 0 < lbraceOffset + if (isDocComment != takeDocComments) continue val converted = memberToMember(e, psiClass) if (converted != null) members.add(converted) } return members } - private fun memberToMember(e: PsiElement?, containingClass: PsiClass): Member? = when(e) { + private fun memberToMember(e: PsiElement?, containingClass: PsiClass): Node? = when(e) { is PsiMethod -> methodToFunction(e, true) is PsiField -> fieldToField(e, containingClass) is PsiClass -> classToClass(e) is PsiClassInitializer -> initializerToInitializer(e) + is PsiComment -> Comment(e.getText()!!) else -> null } @@ -109,7 +125,8 @@ public open class Converter() { val extendsTypes: List = typesToNotNullableTypeList(psiClass.getExtendsListTypes()) val name: Identifier = Identifier(psiClass.getName()!!) val baseClassParams: List = arrayList() - val members: List = getMembers(psiClass) + val members: List = getMembers(psiClass, false) + val docComments = getMembers(psiClass, true) val visitor: SuperVisitor = SuperVisitor() psiClass.accept(visitor) val resolvedSuperCallParameters = visitor.resolvedSuperCallParameters @@ -166,14 +183,14 @@ public open class Converter() { } if (psiClass.isInterface()) { - return Trait(this, name, modifiers, typeParameters, extendsTypes, Collections.emptyList()!!, implementsTypes, members) + return Trait(this, name, docComments, modifiers, typeParameters, extendsTypes, Collections.emptyList()!!, implementsTypes, members) } if (psiClass.isEnum()) { - return Enum(this, name, modifiers, typeParameters, Collections.emptyList()!!, Collections.emptyList()!!, implementsTypes, members) + return Enum(this, name, docComments, modifiers, typeParameters, Collections.emptyList()!!, Collections.emptyList()!!, implementsTypes, members) } - return Class(this, name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members) + return Class(this, name, docComments, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members) } private fun initializerToInitializer(i: PsiClassInitializer): Initializer { diff --git a/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt b/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt index a397f501658..e96ae0b36b5 100644 --- a/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt +++ b/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt @@ -5,9 +5,10 @@ import org.jetbrains.jet.j2k.ast.types.Type import java.util.Collections import java.util.List -public open class AnonymousClass(converter : Converter, members : List) +public open class AnonymousClass(converter : Converter, members : List) : Class(converter, Identifier("anonClass"), + arrayList(), Collections.emptySet()!!, Collections.emptyList()!!, Collections.emptyList()!!, diff --git a/src/org/jetbrains/jet/j2k/ast/Class.kt b/src/org/jetbrains/jet/j2k/ast/Class.kt index 25d52c4c97f..739671afca3 100644 --- a/src/org/jetbrains/jet/j2k/ast/Class.kt +++ b/src/org/jetbrains/jet/j2k/ast/Class.kt @@ -13,12 +13,13 @@ import java.util.ArrayList public open class Class(converter : Converter, val name : Identifier, + val docComments: List, modifiers : Set, val typeParameters : List, val extendsTypes : List, val baseClassParams : List, val implementsTypes : List, - members : List) : Member(modifiers) { + members : List) : Member(modifiers) { val members = getMembers(members, converter) open val TYPE: String @@ -52,7 +53,7 @@ public open class Class(converter : Converter, return "" } - open fun membersExceptConstructors() : List = members.filterNot { it is Constructor } + open fun membersExceptConstructors() : List = members.filterNot { it is Constructor } open fun secondaryConstructorsAsStaticInitFunction() : List { return members.filter { it is Constructor && !it.isPrimary }.map { constructorToInit(it as Function) } @@ -118,13 +119,14 @@ public open class Class(converter : Converter, } private fun classObjectToKotlin() : String { - val staticMembers : List = arrayList() + val staticMembers : List = arrayList() staticMembers.addAll(secondaryConstructorsAsStaticInitFunction()) staticMembers.addAll(getStatic(membersExceptConstructors())) return staticMembers.toKotlin("\n", "class object {\n", "\n}") } public override fun toKotlin() : String = + docComments.toKotlin("\n", "", "\n") + modifiersToKotlin() + TYPE + " " + name.toKotlin() + typeParametersToKotlin() + @@ -134,31 +136,21 @@ public open class Class(converter : Converter, bodyToKotlin() class object { - open fun getMembers(members : List, converter : Converter) : List { + open fun getMembers(members : List, converter : Converter) : List { if (converter.hasFlag(J2KConverterFlags.SKIP_NON_PUBLIC_MEMBERS)) { - return members.filter { it.accessModifier() == "public" || it.accessModifier() == "protected" } + return members.filter { it is Comment || + (it as Member).accessModifier() == "public" || + (it as Member).accessModifier() == "protected" } } return members } - private fun getStatic(members : List) : List { - val result : List = arrayList() - for (m in members) - if (m.isStatic()) - result.add(m) - - return result + private fun getStatic(members : List) : List { + return members.filter { it is Member && it.isStatic() } } - private fun getNonStatic(members : List) : List { - val result : List = arrayList() - for (m in members) - if (!m.isStatic()) - { - result.add(m) - } - - return result + private fun getNonStatic(members : List) : List { + return members.filterNot { it is Member && it.isStatic() } } } } diff --git a/src/org/jetbrains/jet/j2k/ast/Element.kt b/src/org/jetbrains/jet/j2k/ast/Element.kt index 55f0c5a7c3a..a5533da574c 100644 --- a/src/org/jetbrains/jet/j2k/ast/Element.kt +++ b/src/org/jetbrains/jet/j2k/ast/Element.kt @@ -2,9 +2,7 @@ package org.jetbrains.jet.j2k.ast public abstract class Element(): Node() { - public open fun isEmpty(): Boolean { - return false - } + public open fun isEmpty(): Boolean = false class object { public val EMPTY_ELEMENT: Element = object : Element() { @@ -13,3 +11,7 @@ public abstract class Element(): Node() { } } } + +public class Comment(val text: String): Element() { + override fun toKotlin() = text +} diff --git a/src/org/jetbrains/jet/j2k/ast/Enum.kt b/src/org/jetbrains/jet/j2k/ast/Enum.kt index f137915c1b4..d67094380bc 100644 --- a/src/org/jetbrains/jet/j2k/ast/Enum.kt +++ b/src/org/jetbrains/jet/j2k/ast/Enum.kt @@ -7,19 +7,21 @@ import java.util.Set public open class Enum(converter : Converter, name : Identifier, + docComments: List, modifiers : Set, typeParameters : List, extendsTypes : List, baseClassParams : List, implementsTypes : List, - members : List) : Class(converter, name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members) { + members : List) : Class(converter, name, docComments, modifiers, typeParameters, + extendsTypes, baseClassParams, implementsTypes, members) { override fun primaryConstructorSignatureToKotlin() : String { val s : String = super.primaryConstructorSignatureToKotlin() return if (s.equals("()")) "" else s } - override fun needOpenModifier() : Boolean = false + override fun needOpenModifier() = false public override fun toKotlin() : String { return modifiersToKotlin() + diff --git a/src/org/jetbrains/jet/j2k/ast/File.kt b/src/org/jetbrains/jet/j2k/ast/File.kt index 99541197f01..09045d48673 100644 --- a/src/org/jetbrains/jet/j2k/ast/File.kt +++ b/src/org/jetbrains/jet/j2k/ast/File.kt @@ -4,11 +4,11 @@ import java.util.List public open class File(val packageName: String, val imports: List, - val classes: List, + val body: List, val mainFunction: String): Node() { public override fun toKotlin(): String { - val common: String = imports.toKotlin("\n") + "\n\n" + classes.toKotlin("\n") + "\n" + mainFunction + val common: String = imports.toKotlin("\n") + "\n\n" + body.toKotlin("\n") + "\n" + mainFunction if (packageName.isEmpty()) { return common } diff --git a/src/org/jetbrains/jet/j2k/ast/Node.kt b/src/org/jetbrains/jet/j2k/ast/Node.kt index ecc2900a76e..6b857f74246 100644 --- a/src/org/jetbrains/jet/j2k/ast/Node.kt +++ b/src/org/jetbrains/jet/j2k/ast/Node.kt @@ -1,8 +1,5 @@ package org.jetbrains.jet.j2k.ast -import org.eclipse.jdt.internal.core.search.StringOperation -import java.util.Arrays -import java.util.HashSet import java.util.Set public abstract class Node() { diff --git a/src/org/jetbrains/jet/j2k/ast/Trait.kt b/src/org/jetbrains/jet/j2k/ast/Trait.kt index 8381ca0d93c..d3865f862af 100644 --- a/src/org/jetbrains/jet/j2k/ast/Trait.kt +++ b/src/org/jetbrains/jet/j2k/ast/Trait.kt @@ -7,12 +7,14 @@ import java.util.Set public open class Trait(converter : Converter, name : Identifier, + docComments: List, modifiers : Set, typeParameters : List, extendsTypes : List, baseClassParams : List, implementsTypes : List, - members : List) : Class(converter, name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members) { + members : List) : Class(converter, name, docComments, modifiers, typeParameters, + extendsTypes, baseClassParams, implementsTypes, members) { override val TYPE: String get() = "trait" diff --git a/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt b/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt index 36606d4bf33..aee18c2c023 100644 --- a/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt +++ b/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt @@ -61,4 +61,8 @@ public open class ElementVisitor(val myConverter : Converter) : JavaElementVisit public override fun visitParameterList(list : PsiParameterList?) : Unit { myResult = ParameterList(myConverter.parametersToParameterList(list!!.getParameters()).requireNoNulls()) } + + public override fun visitComment(comment: PsiComment?) { + myResult = Comment(comment?.getText()!!) + } } diff --git a/tests/testData/ast/issues/file/comments.jav b/tests/testData/ast/issues/file/comments.jav new file mode 100644 index 00000000000..95ca19a6442 --- /dev/null +++ b/tests/testData/ast/issues/file/comments.jav @@ -0,0 +1,14 @@ +// This is an end-of-line comment + +/* +This is a block comment +*/ + + +class C { + // This is a comment + + public void foo() { + /* This is a comment */ + } +} diff --git a/tests/testData/ast/issues/file/comments.kt b/tests/testData/ast/issues/file/comments.kt new file mode 100644 index 00000000000..cc169a6b8cb --- /dev/null +++ b/tests/testData/ast/issues/file/comments.kt @@ -0,0 +1,4 @@ +// This is an end-of-line comment +/* +This is a block comment +*/ diff --git a/tests/testData/ast/issues/file/kt-824-isDir.kt b/tests/testData/ast/issues/file/kt-824-isDir.kt index 34e7ddca7ec..0248b413bbd 100644 --- a/tests/testData/ast/issues/file/kt-824-isDir.kt +++ b/tests/testData/ast/issues/file/kt-824-isDir.kt @@ -1,5 +1,8 @@ package test import java.io.File +/** +* User: ignatov +*/ public open class Test() { class object { public open fun isDir(parent : File?) : Boolean {