diff --git a/j2k/src/org/jetbrains/jet/j2k/Converter.kt b/j2k/src/org/jetbrains/jet/j2k/Converter.kt index 6ca52816057..fb26febc97d 100644 --- a/j2k/src/org/jetbrains/jet/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/Converter.kt @@ -31,7 +31,6 @@ import com.intellij.psi.CommonClassNames.* import org.jetbrains.jet.lang.types.expressions.OperatorConventions.* import com.intellij.psi.util.PsiUtil import com.intellij.openapi.project.Project -import com.intellij.psi.javadoc.PsiDocComment public class Converter(val project: Project, val settings: ConverterSettings) { @@ -89,19 +88,24 @@ public class Converter(val project: Project, val settings: ConverterSettings) { private fun convertMembers(psiClass: PsiClass): List { val members = ArrayList() - for (e in psiClass.getChildren()) { - if (psiClass is PsiAnonymousClass && psiClass.getBaseClassReference() == e) { - continue - } + val allChildren = psiClass.getChildren().toList() + for (e in allChildren.subList(allChildren.indexOf(psiClass.getLBrace()), allChildren.size)) { val converted = convertMember(e, psiClass) if (converted != null) members.add(converted) } return members } - private fun getDocComment(element: PsiDocCommentOwner): Comment? { - val psiDocComment = element.getDocComment() - return if (psiDocComment != null) Comment(psiDocComment.getText()!!) else null + private fun getComments(member: PsiMember): MemberComments { + var relevantChildren = member.getChildren().toList() + if (member is PsiClass) { + val leftBraceIndex = relevantChildren.indexOf(member.getLBrace()) + relevantChildren = relevantChildren.subList(0, leftBraceIndex) + } + val whiteSpacesAndComments = relevantChildren + .filter { it is PsiWhiteSpace || it is PsiComment } + .map { convertElement(it) } + return MemberComments(whiteSpacesAndComments) } private fun convertMember(e: PsiElement?, containingClass: PsiClass): Element? = when(e) { @@ -109,7 +113,6 @@ public class Converter(val project: Project, val settings: ConverterSettings) { is PsiField -> convertField(e, containingClass) is PsiClass -> convertClass(e) is PsiClassInitializer -> convertInitializer(e) - is PsiDocComment -> null else -> convertElement(e) } @@ -169,7 +172,8 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } } } - members.add(Constructor(this, Identifier.Empty, null, Collections.emptySet(), + //TODO: comments? + members.add(Constructor(this, Identifier.Empty, MemberComments.Empty, Collections.emptySet(), ClassType(name, Collections.emptyList(), false, this), TypeParameterList.Empty, ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)), @@ -178,14 +182,14 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } if (psiClass.isInterface()) { - return Trait(this, name, getDocComment(psiClass), modifiers, typeParameters, extendsTypes, Collections.emptyList(), implementsTypes, members) + return Trait(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, Collections.emptyList(), implementsTypes, members) } if (psiClass.isEnum()) { - return Enum(this, name, getDocComment(psiClass), modifiers, typeParameters, Collections.emptyList(), Collections.emptyList(), implementsTypes, members) + return Enum(this, name, getComments(psiClass), modifiers, typeParameters, Collections.emptyList(), Collections.emptyList(), implementsTypes, members) } - return Class(this, name, getDocComment(psiClass), modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members) + return Class(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members) } private fun convertInitializer(i: PsiClassInitializer): Initializer { @@ -200,7 +204,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) { val modifiers = convertModifierList(field.getModifierList()) if (field is PsiEnumConstant) { return EnumConstant(Identifier(field.getName()!!), - getDocComment(field), + getComments(field), modifiers, convertType(field.getType()), convertElement(field.getArgumentList())) @@ -212,7 +216,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } return Field(Identifier(field.getName()!!), - getDocComment(field), + getComments(field), modifiers, kType, convertExpression(field.getInitializer(), field.getType()), @@ -252,11 +256,11 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } if (method.isConstructor()) { - return Constructor(this, identifier, getDocComment(method), modifiers, returnType, typeParameterList, params, + return Constructor(this, identifier, getComments(method), modifiers, returnType, typeParameterList, params, Block(body.statements), isConstructorPrimary(method)) } - return Function(this, identifier, getDocComment(method), modifiers, returnType, typeParameterList, params, body) + return Function(this, identifier, getComments(method), modifiers, returnType, typeParameterList, params, body) } private fun createFunctionParameters(method: PsiMethod): ParameterList { diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt b/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt index 8c2e0d97590..e4838ef51d4 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt @@ -23,7 +23,7 @@ import java.util.Collections public class AnonymousClass(converter: Converter, members: List) : Class(converter, Identifier("anonClass"), - null, + MemberComments.Empty, Collections.emptySet(), TypeParameterList.Empty, Collections.emptyList(), diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt index 4c3e99027ea..e922ae2c9ee 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt @@ -24,13 +24,13 @@ import java.util.ArrayList public open class Class(val converter: Converter, val name: Identifier, - docComment: Comment?, + comments: MemberComments, modifiers: Set, val typeParameterList: TypeParameterList, val extendsTypes: List, val baseClassParams: List, val implementsTypes: List, - val members: List) : Member(docComment, modifiers) { + val members: List) : Member(comments, modifiers) { open val TYPE: String get() = "class" @@ -49,7 +49,7 @@ public open class Class(val converter: Converter, return "" } - fun secondaryConstructorsAsStaticInitFunction(): MemberList { + fun secondaryConstructorsAsStaticInitFunctions(): MemberList { return MemberList(classMembers.secondaryConstructors.elements.map { if (it is Constructor) constructorToInit(it) else it }) } @@ -62,7 +62,7 @@ public open class Class(val converter: Converter, val constructorTypeParameters = ArrayList() constructorTypeParameters.addAll(typeParameterList.parameters) constructorTypeParameters.addAll(f.typeParameterList.parameters) - return Function(converter, Identifier("init"), null, modifiers, + return Function(converter, Identifier("init"), MemberComments.Empty, modifiers, ClassType(name, constructorTypeParameters, false, converter), TypeParameterList(constructorTypeParameters), f.params, block) } @@ -109,16 +109,16 @@ public open class Class(val converter: Converter, } fun classObjectToKotlin(): String { - val secondaryConstructorsAsStaticInitFunction = secondaryConstructorsAsStaticInitFunction() + val secondaryConstructorsAsStaticInitFunctions = secondaryConstructorsAsStaticInitFunctions() val staticMembers = classMembers.staticMembers - if (secondaryConstructorsAsStaticInitFunction.isEmpty() && staticMembers.isEmpty()) { + if (secondaryConstructorsAsStaticInitFunctions.isEmpty() && staticMembers.isEmpty()) { return "" } - return "\nclass object {${secondaryConstructorsAsStaticInitFunction.toKotlin()}${staticMembers.toKotlin()}}" + return "\nclass object {${secondaryConstructorsAsStaticInitFunctions.toKotlin()}${staticMembers.toKotlin()}}" } override fun toKotlin(): String = - docCommentToKotlin() + + commentsToKotlin() + modifiersToKotlin() + TYPE + " " + name.toKotlin() + typeParameterList.toKotlin() + @@ -126,13 +126,4 @@ public open class Class(val converter: Converter, implementTypesToKotlin() + typeParameterList.whereToKotlin().withPrefix(" ") + bodyToKotlin() - - - private fun getStatic(members: List): List { - return members.filter { it is Member && it.isStatic() } - } - - private fun getNonStatic(members: List): List { - return members.filterNot { it is Member && it.isStatic() } - } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Constructor.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Constructor.kt index 75878a721b9..f92746f20a1 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Constructor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Constructor.kt @@ -20,15 +20,15 @@ import org.jetbrains.jet.j2k.ast.types.Type import org.jetbrains.jet.j2k.Converter public class Constructor(converter: Converter, - identifier: Identifier, - docComment: Comment?, - modifiers: Set, - `type`: Type, - typeParameters: TypeParameterList, - params: Element, - block: Block, - val isPrimary: Boolean) : Function(converter, identifier, docComment, modifiers, - `type`, typeParameters, params, block) { + identifier: Identifier, + comments: MemberComments, + modifiers: Set, + `type`: Type, + typeParameters: TypeParameterList, + params: Element, + block: Block, + val isPrimary: Boolean) : Function(converter, identifier, comments, modifiers, + `type`, typeParameters, params, block) { public fun primarySignatureToKotlin(): String { return "(" + params.toKotlin() + ")" diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt index f2e9d9111c4..3098d574e8e 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt @@ -21,14 +21,14 @@ import org.jetbrains.jet.j2k.ast.types.Type public class Enum(converter: Converter, name: Identifier, - docComments: Comment?, + comments: MemberComments, modifiers: Set, typeParameterList: TypeParameterList, extendsTypes: List, baseClassParams: List, implementsTypes: List, - members: List) : Class(converter, name, docComments, modifiers, typeParameterList, - extendsTypes, baseClassParams, implementsTypes, members) { + members: List) : Class(converter, name, comments, modifiers, typeParameterList, + extendsTypes, baseClassParams, implementsTypes, members) { override fun primaryConstructorSignatureToKotlin(): String { val s: String = super.primaryConstructorSignatureToKotlin() diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt b/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt index 28425be8e70..dcba09127d7 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt @@ -19,10 +19,10 @@ package org.jetbrains.jet.j2k.ast import org.jetbrains.jet.j2k.ast.types.Type public open class EnumConstant(identifier: Identifier, - docComment: Comment?, + members: MemberComments, modifiers: Set, `type`: Type, - params: Element) : Field(identifier, docComment, modifiers, `type`.convertedToNotNull(), params, 0) { + params: Element) : Field(identifier, members, modifiers, `type`.convertedToNotNull(), params, 0) { public override fun toKotlin(): String { if (initializer.toKotlin().isEmpty()) { diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt index fa8b39a0956..090e30b2c38 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt @@ -21,11 +21,11 @@ import org.jetbrains.jet.j2k.* import java.util.ArrayList public open class Field(val identifier: Identifier, - docComment: Comment?, + comments: MemberComments, modifiers: Set, val `type`: Type, val initializer: Element, - val writingAccesses: Int) : Member(docComment, modifiers) { + val writingAccesses: Int) : Member(comments, modifiers) { fun modifiersToKotlin(): String { val modifierList = ArrayList() @@ -44,7 +44,7 @@ public open class Field(val identifier: Identifier, public fun isVal(): Boolean = modifiers.contains(Modifier.FINAL) public override fun toKotlin(): String { - val declaration: String = docCommentToKotlin() + + val declaration: String = commentsToKotlin() + modifiersToKotlin() + identifier.toKotlin() + " : " + `type`.toKotlin() if (initializer.isEmpty()) { return declaration + ((if (isVal() && !isStatic() && writingAccesses != 0) diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt index eaba2a1fa58..c20c986ea55 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt @@ -23,12 +23,12 @@ import org.jetbrains.jet.j2k.Converter public open class Function(val converter: Converter, val name: Identifier, - docComment: Comment?, + comments: MemberComments, modifiers: Set, val `type`: Type, val typeParameterList: TypeParameterList, val params: Element, - var block: Block?) : Member(docComment, modifiers) { + var block: Block?) : Member(comments, modifiers) { private fun modifiersToKotlin(): String { val resultingModifiers = ArrayList() @@ -64,7 +64,7 @@ public open class Function(val converter: Converter, private fun returnTypeToKotlin() = if (!`type`.isUnit()) " : " + `type`.toKotlin() + " " else " " public override fun toKotlin(): String { - return docCommentToKotlin() + + return commentsToKotlin() + modifiersToKotlin() + "fun ${typeParameterList.toKotlin().withSuffix(" ")}${name.toKotlin()}" + "(${params.toKotlin()})" + diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Initializer.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Initializer.kt index 53d6c80484b..1ce967b2133 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Initializer.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Initializer.kt @@ -18,7 +18,7 @@ package org.jetbrains.jet.j2k.ast //TODO: is a member? -public class Initializer(val block: Block, modifiers: Set) : Member(null, modifiers) { +public class Initializer(val block: Block, modifiers: Set) : Member(MemberComments.Empty, modifiers) { public override fun toKotlin(): String { return block.toKotlin() } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt index 77ff733eea6..5719660dc3f 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt @@ -18,14 +18,20 @@ package org.jetbrains.jet.j2k.ast import java.util.ArrayList -public abstract class Member(val docComment: Comment?, val modifiers: Set) : Element { +public class MemberComments(elements: List) : WhiteSpaceSeparatedElementList(elements, WhiteSpace.NoSpace) { + class object { + public val Empty: MemberComments = MemberComments(ArrayList()) + } +} + +public abstract class Member(val comments: MemberComments, val modifiers: Set) : Element { fun accessModifier(): Modifier? { return modifiers.find { m -> m == Modifier.PUBLIC || m == Modifier.PROTECTED || m == Modifier.PRIVATE } } public fun isAbstract(): Boolean = modifiers.contains(Modifier.ABSTRACT) public fun isStatic(): Boolean = modifiers.contains(Modifier.STATIC) - public fun docCommentToKotlin(): String = if (docComment != null) docComment.toKotlin() + "\n" else "" + public fun commentsToKotlin(): String = comments.toKotlin() } //member itself and all the elements before it in the code (comments, whitespaces) diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt index 9074e53b4e6..90b2acc66c3 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt @@ -21,13 +21,13 @@ import org.jetbrains.jet.j2k.ast.types.Type public class Trait(converter: Converter, name: Identifier, - docComment: Comment?, + comments: MemberComments, modifiers: Set, typeParameterList: TypeParameterList, extendsTypes: List, baseClassParams: List, implementsTypes: List, - members: List) : Class(converter, name, docComment, modifiers, typeParameterList, + members: List) : Class(converter, name, comments, modifiers, typeParameterList, extendsTypes, baseClassParams, implementsTypes, members) { override val TYPE: String diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt b/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt index 5b561c285b0..bce4e6d3bf5 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt @@ -37,6 +37,7 @@ public class WhiteSpace(val text: String) : Element { class object { public val NewLine: WhiteSpace = WhiteSpace("\n") + public val NoSpace: WhiteSpace = WhiteSpace("") } } diff --git a/j2k/tests/testData/ast/issues/comments.ide.kt b/j2k/tests/testData/ast/issues/comments.ide.kt index ff80c727415..4e6b25e7e7f 100644 --- a/j2k/tests/testData/ast/issues/comments.ide.kt +++ b/j2k/tests/testData/ast/issues/comments.ide.kt @@ -16,4 +16,44 @@ class C() { public fun foo() { /* This is a function comment */ } + + //simple one line comment for function + fun f1() { + } + + //simple one line comment for field + var j: Int = 0 + + //double c style + //comment before function + fun f2() { + } + + //double c style + //comment before field + var k: Int = 0 + + //combination + /** of + */ + // + /** + * different + */ + //comments + fun f3() { + } + + //combination + /** of + */ + // + /** + * different + */ + //comments + var l: Int = 0 + + /*two*/ /*comments*//*line*/ + var z: Int = 0 } \ No newline at end of file diff --git a/j2k/tests/testData/ast/issues/comments.jav b/j2k/tests/testData/ast/issues/comments.jav index 61547baf89e..1ba21924138 100644 --- a/j2k/tests/testData/ast/issues/comments.jav +++ b/j2k/tests/testData/ast/issues/comments.jav @@ -7,17 +7,56 @@ This is a block comment class C { - // This is a class comment + // This is a class comment - /** + /** * This is a field doc comment. */ - private int i; + private int i; - /** + /** * This is a function doc comment. */ - public void foo() { - /* This is a function comment */ - } + public void foo() { + /* This is a function comment */ + } + + //simple one line comment for function + void f1() { + } + + //simple one line comment for field + int j; + + //double c style + //comment before function + void f2() { + } + + //double c style + //comment before field + int k; + + //combination + /** of + */ + // + /** + * different + */ + //comments + void f3() {} + + //combination + /** of + */ + // + /** + * different + */ + //comments + int l; + + /*two*/ /*comments*//*line*/ + int z; } diff --git a/j2k/tests/testData/ast/issues/comments.kt b/j2k/tests/testData/ast/issues/comments.kt index 6c0f6c36712..4e7a846602e 100644 --- a/j2k/tests/testData/ast/issues/comments.kt +++ b/j2k/tests/testData/ast/issues/comments.kt @@ -16,4 +16,44 @@ open class C() { public open fun foo() { /* This is a function comment */ } + + //simple one line comment for function + open fun f1() { + } + + //simple one line comment for field + var j: Int = 0 + + //double c style + //comment before function + open fun f2() { + } + + //double c style + //comment before field + var k: Int = 0 + + //combination + /** of + */ + // + /** + * different + */ + //comments + open fun f3() { + } + + //combination + /** of + */ + // + /** + * different + */ + //comments + var l: Int = 0 + + /*two*/ /*comments*//*line*/ + var z: Int = 0 } \ No newline at end of file