Converter:

Member comments are preserved (not only doc comments)
This commit is contained in:
Pavel Talanov
2013-12-09 16:12:01 +04:00
committed by Pavel V. Talanov
parent f08861c14a
commit 098a80a2af
15 changed files with 188 additions and 67 deletions
+21 -17
View File
@@ -31,7 +31,6 @@ import com.intellij.psi.CommonClassNames.*
import org.jetbrains.jet.lang.types.expressions.OperatorConventions.* import org.jetbrains.jet.lang.types.expressions.OperatorConventions.*
import com.intellij.psi.util.PsiUtil import com.intellij.psi.util.PsiUtil
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.javadoc.PsiDocComment
public class Converter(val project: Project, val settings: ConverterSettings) { 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<Element> { private fun convertMembers(psiClass: PsiClass): List<Element> {
val members = ArrayList<Element>() val members = ArrayList<Element>()
for (e in psiClass.getChildren()) { val allChildren = psiClass.getChildren().toList()
if (psiClass is PsiAnonymousClass && psiClass.getBaseClassReference() == e) { for (e in allChildren.subList(allChildren.indexOf(psiClass.getLBrace()), allChildren.size)) {
continue
}
val converted = convertMember(e, psiClass) val converted = convertMember(e, psiClass)
if (converted != null) members.add(converted) if (converted != null) members.add(converted)
} }
return members return members
} }
private fun getDocComment(element: PsiDocCommentOwner): Comment? { private fun getComments(member: PsiMember): MemberComments {
val psiDocComment = element.getDocComment() var relevantChildren = member.getChildren().toList()
return if (psiDocComment != null) Comment(psiDocComment.getText()!!) else null 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) { 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 PsiField -> convertField(e, containingClass)
is PsiClass -> convertClass(e) is PsiClass -> convertClass(e)
is PsiClassInitializer -> convertInitializer(e) is PsiClassInitializer -> convertInitializer(e)
is PsiDocComment -> null
else -> convertElement(e) 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<Modifier>(), //TODO: comments?
members.add(Constructor(this, Identifier.Empty, MemberComments.Empty, Collections.emptySet<Modifier>(),
ClassType(name, Collections.emptyList<Element>(), false, this), ClassType(name, Collections.emptyList<Element>(), false, this),
TypeParameterList.Empty, TypeParameterList.Empty,
ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)), ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)),
@@ -178,14 +182,14 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
} }
if (psiClass.isInterface()) { if (psiClass.isInterface()) {
return Trait(this, name, getDocComment(psiClass), modifiers, typeParameters, extendsTypes, Collections.emptyList<Expression>(), implementsTypes, members) return Trait(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, Collections.emptyList<Expression>(), implementsTypes, members)
} }
if (psiClass.isEnum()) { if (psiClass.isEnum()) {
return Enum(this, name, getDocComment(psiClass), modifiers, typeParameters, Collections.emptyList<Type>(), Collections.emptyList<Expression>(), implementsTypes, members) return Enum(this, name, getComments(psiClass), modifiers, typeParameters, Collections.emptyList<Type>(), Collections.emptyList<Expression>(), 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 { private fun convertInitializer(i: PsiClassInitializer): Initializer {
@@ -200,7 +204,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
val modifiers = convertModifierList(field.getModifierList()) val modifiers = convertModifierList(field.getModifierList())
if (field is PsiEnumConstant) { if (field is PsiEnumConstant) {
return EnumConstant(Identifier(field.getName()!!), return EnumConstant(Identifier(field.getName()!!),
getDocComment(field), getComments(field),
modifiers, modifiers,
convertType(field.getType()), convertType(field.getType()),
convertElement(field.getArgumentList())) convertElement(field.getArgumentList()))
@@ -212,7 +216,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
} }
return Field(Identifier(field.getName()!!), return Field(Identifier(field.getName()!!),
getDocComment(field), getComments(field),
modifiers, modifiers,
kType, kType,
convertExpression(field.getInitializer(), field.getType()), convertExpression(field.getInitializer(), field.getType()),
@@ -252,11 +256,11 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
} }
if (method.isConstructor()) { 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)) 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 { private fun createFunctionParameters(method: PsiMethod): ParameterList {
@@ -23,7 +23,7 @@ import java.util.Collections
public class AnonymousClass(converter: Converter, members: List<Element>) public class AnonymousClass(converter: Converter, members: List<Element>)
: Class(converter, : Class(converter,
Identifier("anonClass"), Identifier("anonClass"),
null, MemberComments.Empty,
Collections.emptySet<Modifier>(), Collections.emptySet<Modifier>(),
TypeParameterList.Empty, TypeParameterList.Empty,
Collections.emptyList<Type>(), Collections.emptyList<Type>(),
+8 -17
View File
@@ -24,13 +24,13 @@ import java.util.ArrayList
public open class Class(val converter: Converter, public open class Class(val converter: Converter,
val name: Identifier, val name: Identifier,
docComment: Comment?, comments: MemberComments,
modifiers: Set<Modifier>, modifiers: Set<Modifier>,
val typeParameterList: TypeParameterList, val typeParameterList: TypeParameterList,
val extendsTypes: List<Type>, val extendsTypes: List<Type>,
val baseClassParams: List<Expression>, val baseClassParams: List<Expression>,
val implementsTypes: List<Type>, val implementsTypes: List<Type>,
val members: List<Element>) : Member(docComment, modifiers) { val members: List<Element>) : Member(comments, modifiers) {
open val TYPE: String open val TYPE: String
get() = "class" get() = "class"
@@ -49,7 +49,7 @@ public open class Class(val converter: Converter,
return "" return ""
} }
fun secondaryConstructorsAsStaticInitFunction(): MemberList { fun secondaryConstructorsAsStaticInitFunctions(): MemberList {
return MemberList(classMembers.secondaryConstructors.elements.map { if (it is Constructor) constructorToInit(it) else it }) 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<TypeParameter>() val constructorTypeParameters = ArrayList<TypeParameter>()
constructorTypeParameters.addAll(typeParameterList.parameters) constructorTypeParameters.addAll(typeParameterList.parameters)
constructorTypeParameters.addAll(f.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), ClassType(name, constructorTypeParameters, false, converter),
TypeParameterList(constructorTypeParameters), f.params, block) TypeParameterList(constructorTypeParameters), f.params, block)
} }
@@ -109,16 +109,16 @@ public open class Class(val converter: Converter,
} }
fun classObjectToKotlin(): String { fun classObjectToKotlin(): String {
val secondaryConstructorsAsStaticInitFunction = secondaryConstructorsAsStaticInitFunction() val secondaryConstructorsAsStaticInitFunctions = secondaryConstructorsAsStaticInitFunctions()
val staticMembers = classMembers.staticMembers val staticMembers = classMembers.staticMembers
if (secondaryConstructorsAsStaticInitFunction.isEmpty() && staticMembers.isEmpty()) { if (secondaryConstructorsAsStaticInitFunctions.isEmpty() && staticMembers.isEmpty()) {
return "" return ""
} }
return "\nclass object {${secondaryConstructorsAsStaticInitFunction.toKotlin()}${staticMembers.toKotlin()}}" return "\nclass object {${secondaryConstructorsAsStaticInitFunctions.toKotlin()}${staticMembers.toKotlin()}}"
} }
override fun toKotlin(): String = override fun toKotlin(): String =
docCommentToKotlin() + commentsToKotlin() +
modifiersToKotlin() + modifiersToKotlin() +
TYPE + " " + name.toKotlin() + TYPE + " " + name.toKotlin() +
typeParameterList.toKotlin() + typeParameterList.toKotlin() +
@@ -126,13 +126,4 @@ public open class Class(val converter: Converter,
implementTypesToKotlin() + implementTypesToKotlin() +
typeParameterList.whereToKotlin().withPrefix(" ") + typeParameterList.whereToKotlin().withPrefix(" ") +
bodyToKotlin() bodyToKotlin()
private fun getStatic(members: List<Node>): List<Node> {
return members.filter { it is Member && it.isStatic() }
}
private fun getNonStatic(members: List<Node>): List<Node> {
return members.filterNot { it is Member && it.isStatic() }
}
} }
@@ -20,15 +20,15 @@ import org.jetbrains.jet.j2k.ast.types.Type
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
public class Constructor(converter: Converter, public class Constructor(converter: Converter,
identifier: Identifier, identifier: Identifier,
docComment: Comment?, comments: MemberComments,
modifiers: Set<Modifier>, modifiers: Set<Modifier>,
`type`: Type, `type`: Type,
typeParameters: TypeParameterList, typeParameters: TypeParameterList,
params: Element, params: Element,
block: Block, block: Block,
val isPrimary: Boolean) : Function(converter, identifier, docComment, modifiers, val isPrimary: Boolean) : Function(converter, identifier, comments, modifiers,
`type`, typeParameters, params, block) { `type`, typeParameters, params, block) {
public fun primarySignatureToKotlin(): String { public fun primarySignatureToKotlin(): String {
return "(" + params.toKotlin() + ")" return "(" + params.toKotlin() + ")"
+3 -3
View File
@@ -21,14 +21,14 @@ import org.jetbrains.jet.j2k.ast.types.Type
public class Enum(converter: Converter, public class Enum(converter: Converter,
name: Identifier, name: Identifier,
docComments: Comment?, comments: MemberComments,
modifiers: Set<Modifier>, modifiers: Set<Modifier>,
typeParameterList: TypeParameterList, typeParameterList: TypeParameterList,
extendsTypes: List<Type>, extendsTypes: List<Type>,
baseClassParams: List<Expression>, baseClassParams: List<Expression>,
implementsTypes: List<Type>, implementsTypes: List<Type>,
members: List<Element>) : Class(converter, name, docComments, modifiers, typeParameterList, members: List<Element>) : Class(converter, name, comments, modifiers, typeParameterList,
extendsTypes, baseClassParams, implementsTypes, members) { extendsTypes, baseClassParams, implementsTypes, members) {
override fun primaryConstructorSignatureToKotlin(): String { override fun primaryConstructorSignatureToKotlin(): String {
val s: String = super.primaryConstructorSignatureToKotlin() val s: String = super.primaryConstructorSignatureToKotlin()
@@ -19,10 +19,10 @@ package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type import org.jetbrains.jet.j2k.ast.types.Type
public open class EnumConstant(identifier: Identifier, public open class EnumConstant(identifier: Identifier,
docComment: Comment?, members: MemberComments,
modifiers: Set<Modifier>, modifiers: Set<Modifier>,
`type`: Type, `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 { public override fun toKotlin(): String {
if (initializer.toKotlin().isEmpty()) { if (initializer.toKotlin().isEmpty()) {
+3 -3
View File
@@ -21,11 +21,11 @@ import org.jetbrains.jet.j2k.*
import java.util.ArrayList import java.util.ArrayList
public open class Field(val identifier: Identifier, public open class Field(val identifier: Identifier,
docComment: Comment?, comments: MemberComments,
modifiers: Set<Modifier>, modifiers: Set<Modifier>,
val `type`: Type, val `type`: Type,
val initializer: Element, val initializer: Element,
val writingAccesses: Int) : Member(docComment, modifiers) { val writingAccesses: Int) : Member(comments, modifiers) {
fun modifiersToKotlin(): String { fun modifiersToKotlin(): String {
val modifierList = ArrayList<Modifier>() val modifierList = ArrayList<Modifier>()
@@ -44,7 +44,7 @@ public open class Field(val identifier: Identifier,
public fun isVal(): Boolean = modifiers.contains(Modifier.FINAL) public fun isVal(): Boolean = modifiers.contains(Modifier.FINAL)
public override fun toKotlin(): String { public override fun toKotlin(): String {
val declaration: String = docCommentToKotlin() + val declaration: String = commentsToKotlin() +
modifiersToKotlin() + identifier.toKotlin() + " : " + `type`.toKotlin() modifiersToKotlin() + identifier.toKotlin() + " : " + `type`.toKotlin()
if (initializer.isEmpty()) { if (initializer.isEmpty()) {
return declaration + ((if (isVal() && !isStatic() && writingAccesses != 0) return declaration + ((if (isVal() && !isStatic() && writingAccesses != 0)
@@ -23,12 +23,12 @@ import org.jetbrains.jet.j2k.Converter
public open class Function(val converter: Converter, public open class Function(val converter: Converter,
val name: Identifier, val name: Identifier,
docComment: Comment?, comments: MemberComments,
modifiers: Set<Modifier>, modifiers: Set<Modifier>,
val `type`: Type, val `type`: Type,
val typeParameterList: TypeParameterList, val typeParameterList: TypeParameterList,
val params: Element, val params: Element,
var block: Block?) : Member(docComment, modifiers) { var block: Block?) : Member(comments, modifiers) {
private fun modifiersToKotlin(): String { private fun modifiersToKotlin(): String {
val resultingModifiers = ArrayList<Modifier>() val resultingModifiers = ArrayList<Modifier>()
@@ -64,7 +64,7 @@ public open class Function(val converter: Converter,
private fun returnTypeToKotlin() = if (!`type`.isUnit()) " : " + `type`.toKotlin() + " " else " " private fun returnTypeToKotlin() = if (!`type`.isUnit()) " : " + `type`.toKotlin() + " " else " "
public override fun toKotlin(): String { public override fun toKotlin(): String {
return docCommentToKotlin() + return commentsToKotlin() +
modifiersToKotlin() + modifiersToKotlin() +
"fun ${typeParameterList.toKotlin().withSuffix(" ")}${name.toKotlin()}" + "fun ${typeParameterList.toKotlin().withSuffix(" ")}${name.toKotlin()}" +
"(${params.toKotlin()})" + "(${params.toKotlin()})" +
@@ -18,7 +18,7 @@ package org.jetbrains.jet.j2k.ast
//TODO: is a member? //TODO: is a member?
public class Initializer(val block: Block, modifiers: Set<Modifier>) : Member(null, modifiers) { public class Initializer(val block: Block, modifiers: Set<Modifier>) : Member(MemberComments.Empty, modifiers) {
public override fun toKotlin(): String { public override fun toKotlin(): String {
return block.toKotlin() return block.toKotlin()
} }
+8 -2
View File
@@ -18,14 +18,20 @@ package org.jetbrains.jet.j2k.ast
import java.util.ArrayList import java.util.ArrayList
public abstract class Member(val docComment: Comment?, val modifiers: Set<Modifier>) : Element { public class MemberComments(elements: List<Element>) : WhiteSpaceSeparatedElementList(elements, WhiteSpace.NoSpace) {
class object {
public val Empty: MemberComments = MemberComments(ArrayList())
}
}
public abstract class Member(val comments: MemberComments, val modifiers: Set<Modifier>) : Element {
fun accessModifier(): Modifier? { fun accessModifier(): Modifier? {
return modifiers.find { m -> m == Modifier.PUBLIC || m == Modifier.PROTECTED || m == Modifier.PRIVATE } return modifiers.find { m -> m == Modifier.PUBLIC || m == Modifier.PROTECTED || m == Modifier.PRIVATE }
} }
public fun isAbstract(): Boolean = modifiers.contains(Modifier.ABSTRACT) public fun isAbstract(): Boolean = modifiers.contains(Modifier.ABSTRACT)
public fun isStatic(): Boolean = modifiers.contains(Modifier.STATIC) 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) //member itself and all the elements before it in the code (comments, whitespaces)
+2 -2
View File
@@ -21,13 +21,13 @@ import org.jetbrains.jet.j2k.ast.types.Type
public class Trait(converter: Converter, public class Trait(converter: Converter,
name: Identifier, name: Identifier,
docComment: Comment?, comments: MemberComments,
modifiers: Set<Modifier>, modifiers: Set<Modifier>,
typeParameterList: TypeParameterList, typeParameterList: TypeParameterList,
extendsTypes: List<Type>, extendsTypes: List<Type>,
baseClassParams: List<Expression>, baseClassParams: List<Expression>,
implementsTypes: List<Type>, implementsTypes: List<Type>,
members: List<Element>) : Class(converter, name, docComment, modifiers, typeParameterList, members: List<Element>) : Class(converter, name, comments, modifiers, typeParameterList,
extendsTypes, baseClassParams, implementsTypes, members) { extendsTypes, baseClassParams, implementsTypes, members) {
override val TYPE: String override val TYPE: String
@@ -37,6 +37,7 @@ public class WhiteSpace(val text: String) : Element {
class object { class object {
public val NewLine: WhiteSpace = WhiteSpace("\n") public val NewLine: WhiteSpace = WhiteSpace("\n")
public val NoSpace: WhiteSpace = WhiteSpace("")
} }
} }
@@ -16,4 +16,44 @@ class C() {
public fun foo() { public fun foo() {
/* This is a function comment */ /* 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
} }
+46 -7
View File
@@ -7,17 +7,56 @@ This is a block comment
class C { class C {
// This is a class comment // This is a class comment
/** /**
* This is a field doc comment. * This is a field doc comment.
*/ */
private int i; private int i;
/** /**
* This is a function doc comment. * This is a function doc comment.
*/ */
public void foo() { public void foo() {
/* This is a function comment */ /* 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;
} }
+40
View File
@@ -16,4 +16,44 @@ open class C() {
public open fun foo() { public open fun foo() {
/* This is a function comment */ /* 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
} }