diff --git a/j2k/src/org/jetbrains/jet/j2k/CommentConverter.kt b/j2k/src/org/jetbrains/jet/j2k/CommentConverter.kt index eec149b07d1..ce9f22c79cf 100644 --- a/j2k/src/org/jetbrains/jet/j2k/CommentConverter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/CommentConverter.kt @@ -20,7 +20,7 @@ import com.intellij.psi.* import java.util.ArrayList import org.jetbrains.jet.j2k.ast.Element -class CommentConverter(private val topElement: PsiElement) { +class CommentConverter(private val topElement: PsiElement?) { private enum class CommentPlacement { Before SameLineBefore @@ -42,7 +42,7 @@ class CommentConverter(private val topElement: PsiElement) { private val allComments: List = run { val list = ArrayList() - topElement.accept(object : JavaRecursiveElementVisitor(){ + topElement?.accept(object : JavaRecursiveElementVisitor(){ override fun visitComment(comment: PsiComment) { list.add(CommentInfo(comment)) } @@ -55,4 +55,8 @@ class CommentConverter(private val topElement: PsiElement) { } */ + + class object { + val Dummy: CommentConverter = CommentConverter(null) + } } diff --git a/j2k/src/org/jetbrains/jet/j2k/Converter.kt b/j2k/src/org/jetbrains/jet/j2k/Converter.kt index c0921baa502..6cbc279c55e 100644 --- a/j2k/src/org/jetbrains/jet/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/Converter.kt @@ -60,7 +60,7 @@ public class Converter private(val project: Project, val settings: ConverterSett = Converter(project, settings, conversionScope, State(typeConverter, state.methodReturnType, state.expressionVisitorFactory, factory)) public fun elementToKotlin(element: PsiElement): String - = convertTopElement(element)?.toKotlin(/*CommentConverter(element)*/) ?: "" + = convertTopElement(element)?.toKotlin(CommentConverter(element)) ?: "" private fun convertTopElement(element: PsiElement?): Element? = when(element) { is PsiJavaFile -> convertFile(element) diff --git a/j2k/src/org/jetbrains/jet/j2k/Utils.kt b/j2k/src/org/jetbrains/jet/j2k/Utils.kt index 196db199a0d..90dfa838385 100644 --- a/j2k/src/org/jetbrains/jet/j2k/Utils.kt +++ b/j2k/src/org/jetbrains/jet/j2k/Utils.kt @@ -23,7 +23,7 @@ import com.intellij.psi.search.LocalSearchScope import com.intellij.psi.search.searches.ReferencesSearch import org.jetbrains.jet.j2k.ast.* -fun quoteKeywords(packageName: String): String = packageName.split("\\.").map { Identifier(it).toKotlin() }.makeString(".") +fun quoteKeywords(packageName: String): String = packageName.split("\\.").map { Identifier.toKotlin(it) }.makeString(".") fun findVariableUsages(variable: PsiVariable, scope: PsiElement): Collection { return ReferencesSearch.search(variable, LocalSearchScope(scope)).findAll().filterIsInstance(javaClass()) diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Annotation.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Annotation.kt index 37cd44175cf..5345c90d6ff 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Annotation.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Annotation.kt @@ -16,30 +16,32 @@ package org.jetbrains.jet.j2k.ast -import java.util.HashSet +import org.jetbrains.jet.j2k.CommentConverter class Annotation(val name: Identifier, val arguments: List>, val brackets: Boolean) : Element() { private fun surroundWithBrackets(text: String) = if (brackets) "[$text]" else text - override fun toKotlin(): String { + override fun toKotlinImpl(commentConverter: CommentConverter): String { if (arguments.isEmpty()) { - return surroundWithBrackets(name.toKotlin()) + return surroundWithBrackets(name.toKotlin(commentConverter)) } val argsText = arguments.map { if (it.first != null) - it.first!!.toKotlin() + " = " + it.second.toKotlin() + it.first!!.toKotlin(commentConverter) + " = " + it.second.toKotlin(commentConverter) else - it.second.toKotlin() + it.second.toKotlin(commentConverter) }.makeString(", ") - return surroundWithBrackets(name.toKotlin() + "(" + argsText + ")") + return surroundWithBrackets(name.toKotlin(commentConverter) + "(" + argsText + ")") } } -class Annotations(val annotations: List, val newLines: Boolean) { +class Annotations(val annotations: List, val newLines: Boolean) : Element() { private val br = if (newLines) "\n" else " " - fun toKotlin(): String = if (annotations.isNotEmpty()) annotations.map { it.toKotlin() }.makeString(br) + br else "" + override fun toKotlinImpl(commentConverter: CommentConverter): String { + return if (annotations.isNotEmpty()) annotations.map { it.toKotlin(commentConverter) }.makeString(br) + br else "" + } fun plus(other: Annotations) = Annotations(annotations + other.annotations, newLines || other.newLines) diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClassBody.kt b/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClassBody.kt index 87535864a53..d2606aaba63 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClassBody.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClassBody.kt @@ -16,10 +16,9 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.Converter -import java.util.Collections +import org.jetbrains.jet.j2k.CommentConverter class AnonymousClassBody(body: ClassBody, val extendsTrait: Boolean) : Class(Identifier(""), MemberComments.Empty, Annotations.Empty, setOf(), TypeParameterList.Empty, listOf(), listOf(), listOf(), body) { - override fun toKotlin() = body.toKotlin(null) + override fun toKotlinImpl(commentConverter: CommentConverter) = body.toKotlin(null, commentConverter) } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt index 631196362b9..96eb2a3c8ee 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt @@ -16,38 +16,41 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + open class ArrayWithoutInitializationExpression(val `type`: ArrayType, val expressions: List) : Expression() { - override fun toKotlin(): String - = constructInnerType(`type`, expressions) - - private fun constructInnerType(hostType: ArrayType, expressions: List): String { - if (expressions.size() == 1) { - return oneDim(hostType, expressions[0]) + override fun toKotlinImpl(commentConverter: CommentConverter): String { + fun getConstructorName(`type`: ArrayType, hasInit: Boolean): String { + return when (`type`.elementType) { + is PrimitiveType -> + `type`.toNotNullType().toKotlin(commentConverter) + is ArrayType -> + if (hasInit) + `type`.toNotNullType().toKotlin(commentConverter) + else + "arrayOfNulls<" + `type`.elementType.toKotlin(commentConverter) + ">" + else -> + "arrayOfNulls<" + `type`.elementType.toKotlin(commentConverter) + ">" + } } - val innerType = hostType.elementType - if (expressions.size() > 1 && innerType is ArrayType) { - return oneDim(hostType, expressions[0], "{" + constructInnerType(innerType, expressions.subList(1, expressions.size())) + "}") + fun oneDim(`type`: ArrayType, size: Expression, init: String = ""): String { + return getConstructorName(`type`, !init.isEmpty()) + "(" + size.toKotlin(commentConverter) + init.withPrefix(", ") + ")" } - return getConstructorName(hostType, expressions.size() != 0) - } + fun constructInnerType(hostType: ArrayType, expressions: List): String { + if (expressions.size() == 1) { + return oneDim(hostType, expressions[0]) + } - private fun oneDim(`type`: ArrayType, size: Expression, init: String = ""): String { - return getConstructorName(`type`, !init.isEmpty()) + "(" + size.toKotlin() + init.withPrefix(", ") + ")" - } + val innerType = hostType.elementType + if (expressions.size() > 1 && innerType is ArrayType) { + return oneDim(hostType, expressions[0], "{" + constructInnerType(innerType, expressions.subList(1, expressions.size())) + "}") + } - private fun getConstructorName(`type`: ArrayType, hasInit: Boolean): String { - return when (`type`.elementType) { - is PrimitiveType -> - `type`.toNotNullType().toKotlin() - is ArrayType -> - if (hasInit) - `type`.toNotNullType().toKotlin() - else - "arrayOfNulls<" + `type`.elementType.toKotlin() + ">" - else -> - "arrayOfNulls<" + `type`.elementType.toKotlin() + ">" + return getConstructorName(hostType, expressions.size() != 0) } + + return constructInnerType(`type`, expressions) } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Block.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Block.kt index 807e51a27f0..ebccce581b1 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Block.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Block.kt @@ -17,6 +17,7 @@ package org.jetbrains.jet.j2k.ast import java.util.ArrayList +import org.jetbrains.jet.j2k.CommentConverter fun Block(statements: List, notEmpty: Boolean = false): Block { val elements = ArrayList() @@ -33,9 +34,9 @@ class Block(val statementList: StatementList, val notEmpty: Boolean = false) : S override val isEmpty: Boolean get() = !notEmpty && statements.all { it.isEmpty } - override fun toKotlin(): String { + override fun toKotlinImpl(commentConverter: CommentConverter): String { if (!isEmpty) { - return "{${statementList.toKotlin()}}" + return "{${statementList.toKotlin(commentConverter)}}" } return "" diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt index 89341e7f4ba..c9b80664aca 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt @@ -17,6 +17,7 @@ package org.jetbrains.jet.j2k.ast import java.util.ArrayList +import org.jetbrains.jet.j2k.CommentConverter open class Class( val name: Identifier, @@ -30,35 +31,35 @@ open class Class( val body: ClassBody ) : Member(comments, annotations, modifiers) { - override fun toKotlin(): String = - commentsToKotlin() + - annotations.toKotlin() + + override fun toKotlinImpl(commentConverter: CommentConverter): String = + commentsToKotlin(commentConverter) + + annotations.toKotlin(commentConverter) + modifiersToKotlin() + - keyword + " " + name.toKotlin() + - typeParameterList.toKotlin() + - primaryConstructorSignatureToKotlin() + - implementTypesToKotlin() + - typeParameterList.whereToKotlin().withPrefix(" ") + - body.toKotlin(this) + keyword + " " + name.toKotlin(commentConverter) + + typeParameterList.toKotlin(commentConverter) + + primaryConstructorSignatureToKotlin(commentConverter) + + implementTypesToKotlin(commentConverter) + + typeParameterList.whereToKotlin(commentConverter).withPrefix(" ") + + body.toKotlin(this, commentConverter) protected open val keyword: String get() = "class" - protected open fun primaryConstructorSignatureToKotlin(): String - = body.primaryConstructor?.signatureToKotlin() ?: "()" + protected open fun primaryConstructorSignatureToKotlin(commentConverter: CommentConverter): String + = body.primaryConstructor?.signatureToKotlin(commentConverter) ?: "()" - private fun baseClassSignatureWithParams(): List { + private fun baseClassSignatureWithParams(commentConverter: CommentConverter): List { if (keyword.equals("class") && extendsTypes.size() == 1) { - val baseParams = baseClassParams.toKotlin(", ") - return arrayListOf(extendsTypes[0].toKotlin() + "(" + baseParams + ")") + val baseParams = baseClassParams.toKotlin(commentConverter, ", ") + return arrayListOf(extendsTypes[0].toKotlin(commentConverter) + "(" + baseParams + ")") } - return extendsTypes.map { it.toKotlin() } + return extendsTypes.map { it.toKotlin(commentConverter) } } - protected fun implementTypesToKotlin(): String { + protected fun implementTypesToKotlin(commentConverter: CommentConverter): String { val allTypes = ArrayList() - allTypes.addAll(baseClassSignatureWithParams()) - allTypes.addAll(implementsTypes.map { it.toKotlin() }) + allTypes.addAll(baseClassSignatureWithParams(commentConverter)) + allTypes.addAll(implementsTypes.map { it.toKotlin(commentConverter) }) return if (allTypes.size() == 0) "" else diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt index bd33205e1cd..2f6c3287922 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt @@ -19,6 +19,7 @@ package org.jetbrains.jet.j2k.ast import org.jetbrains.jet.j2k.Converter import java.util.HashSet import java.util.ArrayList +import org.jetbrains.jet.j2k.CommentConverter abstract class Constructor( converter: Converter, @@ -37,13 +38,13 @@ class PrimaryConstructor(converter: Converter, block: Block) : Constructor(converter, comments, annotations, modifiers, parameterList, block) { - public fun signatureToKotlin(): String { + public fun signatureToKotlin(commentConverter: CommentConverter): String { val accessModifier = modifiers.accessModifier() val modifiersString = if (accessModifier != null && accessModifier != Modifier.PUBLIC) " " + accessModifier.toKotlin() else "" - return modifiersString + "(" + parameterList.toKotlin() + ")" + return modifiersString + "(" + parameterList.toKotlin(commentConverter) + ")" } - public fun bodyToKotlin(): String = block!!.toKotlin() + public fun bodyToKotlin(commentConverter: CommentConverter): String = block!!.toKotlin(commentConverter) } class SecondaryConstructor(converter: Converter, diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/DummyStringExpression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/DummyStringExpression.kt index 3971b3acb04..248b9bbf902 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/DummyStringExpression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/DummyStringExpression.kt @@ -16,6 +16,8 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class DummyStringExpression(val string: String) : Expression() { - override fun toKotlin(): String = string + override fun toKotlinImpl(commentConverter: CommentConverter): String = string } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Element.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Element.kt index 9ce7175baf5..83cee59e7de 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Element.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Element.kt @@ -16,17 +16,21 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + abstract class Element { - public abstract fun toKotlin(): String + public fun toKotlin(commentConverter: CommentConverter): String = toKotlinImpl(commentConverter) + + protected abstract fun toKotlinImpl(commentConverter: CommentConverter): String public open val isEmpty: Boolean get() = false object Empty : Element() { - override fun toKotlin() = "" + override fun toKotlinImpl(commentConverter: CommentConverter) = "" override val isEmpty: Boolean get() = true } } class Comment(val text: String) : Element() { - override fun toKotlin() = text + override fun toKotlinImpl(commentConverter: CommentConverter) = text } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt index f0ab0b3f621..1bf0f80eb70 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt @@ -16,6 +16,8 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class Enum( name: Identifier, comments: MemberComments, @@ -29,17 +31,17 @@ class Enum( ) : Class(name, comments, annotations, modifiers, typeParameterList, extendsTypes, baseClassParams, implementsTypes, body) { - override fun primaryConstructorSignatureToKotlin(): String - = body.primaryConstructor?.signatureToKotlin() ?: "" + override fun primaryConstructorSignatureToKotlin(commentConverter: CommentConverter): String + = body.primaryConstructor?.signatureToKotlin(commentConverter) ?: "" - override fun toKotlin(): String { - return commentsToKotlin() + - annotations.toKotlin() + + override fun toKotlinImpl(commentConverter: CommentConverter): String { + return commentsToKotlin(commentConverter) + + annotations.toKotlin(commentConverter) + modifiersToKotlin() + - "enum class " + name.toKotlin() + - primaryConstructorSignatureToKotlin() + - typeParameterList.toKotlin() + - implementTypesToKotlin() + - body.toKotlin(this) + "enum class " + name.toKotlin(commentConverter) + + primaryConstructorSignatureToKotlin(commentConverter) + + typeParameterList.toKotlin(commentConverter) + + implementTypesToKotlin(commentConverter) + + body.toKotlin(this, commentConverter) } } \ No newline at end of file diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt b/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt index a3c2b2808b4..d38ac5675f3 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt @@ -16,6 +16,8 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class EnumConstant( identifier: Identifier, members: MemberComments, @@ -25,12 +27,12 @@ class EnumConstant( params: Element ) : Field(identifier, members, annotations, modifiers, `type`.toNotNullType(), params, true, false) { - override fun toKotlin(): String { - if (initializer.toKotlin().isEmpty()) { - return annotations.toKotlin() + identifier.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter): String { + if (initializer.toKotlin(commentConverter).isEmpty()) { + return annotations.toKotlin(commentConverter) + identifier.toKotlin(commentConverter) } - return annotations.toKotlin() + identifier.toKotlin() + " : " + `type`.toKotlin() + "(" + initializer.toKotlin() + ")" + return annotations.toKotlin(commentConverter) + identifier.toKotlin(commentConverter) + " : " + `type`.toKotlin(commentConverter) + "(" + initializer.toKotlin(commentConverter) + ")" } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Expression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Expression.kt index 2152a1d6fa3..2aeba61b327 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Expression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Expression.kt @@ -16,12 +16,14 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + abstract class Expression() : Statement() { open val isNullable: Boolean get() = false object Empty : Expression() { - override fun toKotlin() = "" + override fun toKotlinImpl(commentConverter: CommentConverter) = "" override val isEmpty: Boolean get() = true } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/ExpressionList.kt b/j2k/src/org/jetbrains/jet/j2k/ast/ExpressionList.kt index 614dd5f9114..082acb95d3b 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/ExpressionList.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/ExpressionList.kt @@ -16,8 +16,10 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + open class ExpressionList(val expressions: List) : Expression() { - override fun toKotlin(): String = expressions.map { it.toKotlin() }.makeString(", ") + override fun toKotlinImpl(commentConverter: CommentConverter): String = expressions.map { it.toKotlin(commentConverter) }.makeString(", ") override val isEmpty: Boolean get() = expressions.isEmpty() diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt index d5eb98c534b..699e727752d 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt @@ -17,83 +17,84 @@ package org.jetbrains.jet.j2k.ast import org.jetbrains.jet.lang.types.expressions.OperatorConventions +import org.jetbrains.jet.j2k.CommentConverter class ArrayAccessExpression(val expression: Expression, val index: Expression, val lvalue: Boolean) : Expression() { - override fun toKotlin() = operandToKotlin(expression) + + override fun toKotlinImpl(commentConverter: CommentConverter) = operandToKotlin(expression, commentConverter) + (if (!lvalue && expression.isNullable) "!!" else "") + - "[" + index.toKotlin() + "]" + "[" + index.toKotlin(commentConverter) + "]" } class AssignmentExpression(val left: Expression, val right: Expression, val op: String) : Expression() { - override fun toKotlin() = operandToKotlin(left) + " " + op + " " + operandToKotlin(right) + override fun toKotlinImpl(commentConverter: CommentConverter) = operandToKotlin(left, commentConverter) + " " + op + " " + operandToKotlin(right, commentConverter) } class BangBangExpression(val expr: Expression) : Expression() { - override fun toKotlin() = operandToKotlin(expr) + "!!" + override fun toKotlinImpl(commentConverter: CommentConverter) = operandToKotlin(expr, commentConverter) + "!!" } class BinaryExpression(val left: Expression, val right: Expression, val op: String) : Expression() { - override fun toKotlin() = operandToKotlin(left, false) + " " + op + " " + operandToKotlin(right, true) + override fun toKotlinImpl(commentConverter: CommentConverter) = operandToKotlin(left, commentConverter, false) + " " + op + " " + operandToKotlin(right, commentConverter, true) } class IsOperator(val expression: Expression, val typeElement: TypeElement) : Expression() { - override fun toKotlin() = operandToKotlin(expression) + " is " + typeElement.toKotlinNotNull() + override fun toKotlinImpl(commentConverter: CommentConverter) = operandToKotlin(expression, commentConverter) + " is " + typeElement.`type`.toNotNullType().toKotlin(commentConverter) } class TypeCastExpression(val `type`: Type, val expression: Expression) : Expression() { - override fun toKotlin() = operandToKotlin(expression) + " as " + `type`.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter) = operandToKotlin(expression, commentConverter) + " as " + `type`.toKotlin(commentConverter) } class LiteralExpression(val literalText: String) : Expression() { - override fun toKotlin() = literalText + override fun toKotlinImpl(commentConverter: CommentConverter) = literalText } class ParenthesizedExpression(val expression: Expression) : Expression() { - override fun toKotlin() = "(" + expression.toKotlin() + ")" + override fun toKotlinImpl(commentConverter: CommentConverter) = "(" + expression.toKotlin(commentConverter) + ")" } class PrefixOperator(val op: String, val expression: Expression) : Expression() { - override fun toKotlin() = op + operandToKotlin(expression) + override fun toKotlinImpl(commentConverter: CommentConverter) = op + operandToKotlin(expression, commentConverter) override val isNullable: Boolean get() = expression.isNullable } class PostfixOperator(val op: String, val expression: Expression) : Expression() { - override fun toKotlin() = operandToKotlin(expression) + op + override fun toKotlinImpl(commentConverter: CommentConverter) = operandToKotlin(expression, commentConverter) + op } class ThisExpression(val identifier: Identifier) : Expression() { - override fun toKotlin() = "this" + identifier.withPrefix("@") + override fun toKotlinImpl(commentConverter: CommentConverter) = "this" + identifier.withPrefix("@", commentConverter) } class SuperExpression(val identifier: Identifier) : Expression() { - override fun toKotlin() = "super" + identifier.withPrefix("@") + override fun toKotlinImpl(commentConverter: CommentConverter) = "super" + identifier.withPrefix("@", commentConverter) } class QualifiedExpression(val qualifier: Expression, val identifier: Expression) : Expression() { override val isNullable: Boolean get() = identifier.isNullable - override fun toKotlin(): String { + override fun toKotlinImpl(commentConverter: CommentConverter): String { if (!qualifier.isEmpty) { - return operandToKotlin(qualifier) + (if (qualifier.isNullable) "!!." else ".") + identifier.toKotlin() + return operandToKotlin(qualifier, commentConverter) + (if (qualifier.isNullable) "!!." else ".") + identifier.toKotlin(commentConverter) } - return identifier.toKotlin() + return identifier.toKotlin(commentConverter) } } class PolyadicExpression(val expressions: List, val token: String) : Expression() { - override fun toKotlin(): String { - val expressionsWithConversions = expressions.map { it.toKotlin() } + override fun toKotlinImpl(commentConverter: CommentConverter): String { + val expressionsWithConversions = expressions.map { it.toKotlin(commentConverter) } return expressionsWithConversions.makeString(" " + token + " ") } } class LambdaExpression(val arguments: String?, val statementList: StatementList) : Expression() { - override fun toKotlin(): String { - val statementsText = statementList.toKotlin().trim() + override fun toKotlinImpl(commentConverter: CommentConverter): String { + val statementsText = statementList.toKotlin(commentConverter).trim() if (arguments != null) { val br = if (statementsText.indexOf('\n') < 0 && statementsText.indexOf('\r') < 0) " " else "\n" return "{ $arguments ->$br$statementsText }" @@ -105,25 +106,25 @@ class LambdaExpression(val arguments: String?, val statementList: StatementList) } class StarExpression(val methodCall: MethodCallExpression) : Expression() { - override fun toKotlin() = "*" + methodCall.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter) = "*" + methodCall.toKotlin(commentConverter) } fun createArrayInitializerExpression(arrayType: ArrayType, initializers: List, needExplicitType: Boolean) : MethodCallExpression { val elementType = arrayType.elementType - val createArrayFunction = if (elementType.isPrimitive()) - (elementType.toNotNullType().toKotlin() + "Array").decapitalize() + val createArrayFunction = if (elementType is PrimitiveType) + (elementType.toNotNullType().toKotlin(CommentConverter.Dummy) + "Array").decapitalize() else if (needExplicitType) - arrayType.toNotNullType().toKotlin().decapitalize() + arrayType.toNotNullType().toKotlin(CommentConverter.Dummy).decapitalize() else "array" val doubleOrFloatTypes = setOf("double", "float", "java.lang.double", "java.lang.float") - val afterReplace = arrayType.toNotNullType().toKotlin().replace("Array", "").toLowerCase().replace(">", "").replace("<", "").replace("?", "") + val afterReplace = arrayType.toNotNullType().toKotlin(CommentConverter.Dummy).replace("Array", "").toLowerCase().replace(">", "").replace("<", "").replace("?", "") fun explicitConvertIfNeeded(initializer: Expression): Expression { if (doubleOrFloatTypes.contains(afterReplace)) { if (initializer is LiteralExpression) { - if (!initializer.toKotlin().contains(".")) { + if (!initializer.toKotlin(CommentConverter.Dummy).contains(".")) { return LiteralExpression(initializer.literalText + ".0") } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt index ac07c21bd4f..3498fabfd9c 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt @@ -30,12 +30,18 @@ open class Field( private val hasWriteAccesses: Boolean ) : Member(comments, annotations, modifiers) { - override fun toKotlin(): String { - val declaration = commentsToKotlin() + annotations.toKotlin() + modifiersToKotlin() + (if (isVal) "val " else "var ") + identifier.toKotlin() + " : " + `type`.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter): String { + val declaration = commentsToKotlin(commentConverter) + + annotations.toKotlin(commentConverter) + + modifiersToKotlin() + + (if (isVal) "val " else "var ") + + identifier.toKotlin(commentConverter) + + " : " + + `type`.toKotlin(commentConverter) return if (initializer.isEmpty) - declaration + (if (isVal && hasWriteAccesses) "" else " = " + getDefaultInitializer(this).toKotlin()) + declaration + (if (isVal && hasWriteAccesses) "" else " = " + getDefaultInitializer(this).toKotlin(commentConverter)) else - declaration + " = " + initializer.toKotlin() + declaration + " = " + initializer.toKotlin(commentConverter) } private fun modifiersToKotlin(): String { diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/File.kt b/j2k/src/org/jetbrains/jet/j2k/ast/File.kt index 2e625434767..d1175ca8806 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/File.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/File.kt @@ -16,10 +16,12 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class FileMemberList(elements: List) : WhiteSpaceSeparatedElementList(elements, WhiteSpace.NewLine, false) class PackageStatement(val packageName: String) : Element() { - override fun toKotlin(): String = "package " + packageName + override fun toKotlinImpl(commentConverter: CommentConverter): String = "package " + packageName } class File( @@ -27,7 +29,7 @@ class File( val mainFunction: String ) : Element() { - override fun toKotlin(): String { - return body.toKotlin() + mainFunction + override fun toKotlinImpl(commentConverter: CommentConverter): String { + return body.toKotlin(commentConverter) + mainFunction } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt index 0bb87b07cfb..6020b9777a4 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt @@ -18,6 +18,7 @@ package org.jetbrains.jet.j2k.ast import java.util.ArrayList import org.jetbrains.jet.j2k.Converter +import org.jetbrains.jet.j2k.CommentConverter open class Function( val converter: Converter, @@ -55,16 +56,14 @@ open class Function( return resultingModifiers.toKotlin() } - private fun returnTypeToKotlin() = if (!`type`.isUnit()) " : " + `type`.toKotlin() + " " else " " - - override fun toKotlin(): String { - return commentsToKotlin() + - annotations.toKotlin() + + override fun toKotlinImpl(commentConverter: CommentConverter): String { + return commentsToKotlin(commentConverter) + + annotations.toKotlin(commentConverter) + modifiersToKotlin() + - "fun ${typeParameterList.toKotlin().withSuffix(" ")}${name.toKotlin()}" + - "(${parameterList.toKotlin()})" + - returnTypeToKotlin() + - typeParameterList.whereToKotlin() + - block?.toKotlin() + "fun ${typeParameterList.toKotlin(commentConverter).withSuffix(" ")}${name.toKotlin(commentConverter)}" + + "(${parameterList.toKotlin(commentConverter)})" + + (if (!`type`.isUnit()) " : " + `type`.toKotlin(commentConverter) + " " else " ") + + typeParameterList.whereToKotlin(commentConverter) + + block?.toKotlin(commentConverter) } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Identifier.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Identifier.kt index fb417e38a9a..9e229d17ca7 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Identifier.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Identifier.kt @@ -16,6 +16,8 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class Identifier( val name: String, @@ -26,7 +28,7 @@ class Identifier( override val isEmpty: Boolean get() = name.isEmpty() - private fun identifierToKotlin(): String { + private fun toKotlin(): String { if (quotingNeeded && ONLY_KOTLIN_KEYWORDS.contains(name) || name.contains("$")) { return quote(name) } @@ -34,7 +36,7 @@ class Identifier( return name } - override fun toKotlin(): String = identifierToKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter): String = toKotlin() private fun quote(str: String): String = "`" + str + "`" @@ -47,6 +49,6 @@ class Identifier( "package", "as", "type", "val", "var", "fun", "is", "in", "object", "when", "trait", "This" ) - fun toKotlin(name: String): String = Identifier(name).identifierToKotlin() + fun toKotlin(name: String): String = Identifier(name).toKotlin() } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Imports.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Imports.kt index ce658abb8a2..82f85682e0e 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Imports.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Imports.kt @@ -25,14 +25,14 @@ import com.intellij.psi.PsiJavaCodeReferenceElement import org.jetbrains.jet.asJava.KotlinLightClassForPackage class Import(val name: String) : Element() { - override fun toKotlin() = "import " + name + override fun toKotlinImpl(commentConverter: CommentConverter) = "import " + name } class ImportList(public val imports: List) : Element() { override val isEmpty: Boolean get() = imports.isEmpty() - override fun toKotlin() = imports.toKotlin("\n") + override fun toKotlinImpl(commentConverter: CommentConverter) = imports.toKotlin(commentConverter, "\n") } public fun Converter.convertImportList(importList: PsiImportList): ImportList = diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Initializer.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Initializer.kt index 6f2adb2cec6..ca90d460077 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Initializer.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Initializer.kt @@ -16,8 +16,10 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class Initializer(val block: Block, modifiers: Set) : Member(MemberComments.Empty, Annotations.Empty, modifiers) { - override fun toKotlin(): String { - return block.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter): String { + return block.toKotlin(commentConverter) } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt b/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt index c3668b6563d..a98f47ba5b4 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt @@ -17,6 +17,7 @@ package org.jetbrains.jet.j2k.ast import org.jetbrains.jet.j2k.ConverterSettings +import org.jetbrains.jet.j2k.CommentConverter class LocalVariable( private val identifier: Identifier, @@ -28,17 +29,17 @@ class LocalVariable( private val settings: ConverterSettings ) : Element() { - override fun toKotlin(): String { - val start = annotations.toKotlin() + if (isVal) "val" else "var" + override fun toKotlinImpl(commentConverter: CommentConverter): String { + val start = annotations.toKotlin(commentConverter) + if (isVal) "val" else "var" return if (initializer.isEmpty) { - "$start ${identifier.toKotlin()} : ${typeCalculator().toKotlin()}" + "$start ${identifier.toKotlin(commentConverter)} : ${typeCalculator().toKotlin(commentConverter)}" } else { val shouldSpecifyType = settings.specifyLocalVariableTypeByDefault if (shouldSpecifyType) - "$start ${identifier.toKotlin()} : ${typeCalculator().toKotlin()} = ${initializer.toKotlin()}" + "$start ${identifier.toKotlin(commentConverter)} : ${typeCalculator().toKotlin(commentConverter)} = ${initializer.toKotlin(commentConverter)}" else - "$start ${identifier.toKotlin()} = ${initializer.toKotlin()}" + "$start ${identifier.toKotlin(commentConverter)} = ${initializer.toKotlin(commentConverter)}" } } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt index abf43f9d002..846a6b39498 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt @@ -17,12 +17,7 @@ package org.jetbrains.jet.j2k.ast import java.util.ArrayList -import com.intellij.psi.PsiClass -import org.jetbrains.jet.j2k.Converter -import java.util.HashSet -import com.intellij.psi.PsiMember -import java.util.LinkedHashMap -import com.intellij.psi.PsiElement +import org.jetbrains.jet.j2k.CommentConverter class MemberComments(elements: List) : WhiteSpaceSeparatedElementList(elements, WhiteSpace.NoSpace) { class object { @@ -31,7 +26,7 @@ class MemberComments(elements: List) : WhiteSpaceSeparatedElementList(e } abstract class Member(val comments: MemberComments, val annotations: Annotations, val modifiers: Set) : Element() { - fun commentsToKotlin(): String = comments.toKotlin() + fun commentsToKotlin(commentConverter: CommentConverter): String = comments.toKotlin(commentConverter) } //member itself and all the elements before it in the code (comments, whitespaces) @@ -48,23 +43,25 @@ class ClassBody ( val normalMembers: MemberList, val classObjectMembers: MemberList) { - fun toKotlin(containingClass: Class?): String { - val innerBody = normalMembers.toKotlin() + primaryConstructorBodyToKotlin() + classObjectToKotlin(containingClass) + fun toKotlin(containingClass: Class?, commentConverter: CommentConverter): String { + val innerBody = normalMembers.toKotlin(commentConverter) + + primaryConstructorBodyToKotlin(commentConverter) + + classObjectToKotlin(containingClass, commentConverter) return if (innerBody.trim().isNotEmpty()) " {" + innerBody + "}" else "" } - private fun primaryConstructorBodyToKotlin(): String { + private fun primaryConstructorBodyToKotlin(commentConverter: CommentConverter): String { val constructor = primaryConstructor if (constructor != null && !(constructor.block?.isEmpty ?: true)) { - return "\n" + constructor.bodyToKotlin() + "\n" + return "\n" + constructor.bodyToKotlin(commentConverter) + "\n" } return "" } - private fun classObjectToKotlin(containingClass: Class?): String { + private fun classObjectToKotlin(containingClass: Class?, commentConverter: CommentConverter): String { val secondaryConstructorsAsStaticInitFunctions = secondaryConstructorsAsStaticInitFunctions(containingClass) if (secondaryConstructorsAsStaticInitFunctions.isEmpty() && classObjectMembers.isEmpty()) return "" - return "\nclass object {${secondaryConstructorsAsStaticInitFunctions.toKotlin()}${classObjectMembers.toKotlin()}}" + return "\nclass object {${secondaryConstructorsAsStaticInitFunctions.toKotlin(commentConverter)}${classObjectMembers.toKotlin(commentConverter)}}" } private fun secondaryConstructorsAsStaticInitFunctions(containingClass: Class?): MemberList { diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt index aefcd1c5cc2..30795dd45a0 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt @@ -16,6 +16,8 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class MethodCallExpression( val methodExpression: Expression, val arguments: List, @@ -24,15 +26,15 @@ class MethodCallExpression( val lambdaArgument: LambdaExpression? = null ) : Expression() { - override fun toKotlin(): String { + override fun toKotlinImpl(commentConverter: CommentConverter): String { val builder = StringBuilder() - builder.append(operandToKotlin(methodExpression)) - builder.append(typeArguments.toKotlin(", ", "<", ">")) + builder.append(operandToKotlin(methodExpression, commentConverter)) + builder.append(typeArguments.toKotlin(commentConverter, ", ", "<", ">")) if (arguments.isNotEmpty() || lambdaArgument == null) { - builder.append("(").append(arguments.map { it.toKotlin() }.makeString(", ")).append(")") + builder.append("(").append(arguments.map { it.toKotlin(commentConverter) }.makeString(", ")).append(")") } if (lambdaArgument != null) { - builder.append(lambdaArgument.toKotlin()) + builder.append(lambdaArgument.toKotlin(commentConverter)) } return builder.toString() } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt index b8655b41024..59511daa58c 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt @@ -16,6 +16,8 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + enum class Modifier(val name: String) { PUBLIC: Modifier("public") PROTECTED: Modifier("protected") diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/NewClassExpression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/NewClassExpression.kt index 77e4427e170..e931089712f 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/NewClassExpression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/NewClassExpression.kt @@ -16,6 +16,8 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class NewClassExpression( val name: Element, val arguments: List, @@ -23,18 +25,18 @@ class NewClassExpression( val anonymousClass: AnonymousClassBody? = null ) : Expression() { - override fun toKotlin(): String { + override fun toKotlinImpl(commentConverter: CommentConverter): String { val callOperator = if (qualifier.isNullable) "!!." else "." - val qualifier = if (qualifier.isEmpty) "" else qualifier.toKotlin() + callOperator - val appliedArguments = arguments.toKotlin(", ") + val qualifier = if (qualifier.isEmpty) "" else qualifier.toKotlin(commentConverter) + callOperator + val appliedArguments = arguments.toKotlin(commentConverter, ", ") return if (anonymousClass != null) { if (anonymousClass.extendsTrait) - "object : " + qualifier + name.toKotlin() + anonymousClass.toKotlin() + "object : " + qualifier + name.toKotlin(commentConverter) + anonymousClass.toKotlin(commentConverter) else - "object : " + qualifier + name.toKotlin() + "(" + appliedArguments + ")" + anonymousClass.toKotlin() + "object : " + qualifier + name.toKotlin(commentConverter) + "(" + appliedArguments + ")" + anonymousClass.toKotlin(commentConverter) } else{ - qualifier + name.toKotlin() + "(" + appliedArguments + ")" + qualifier + name.toKotlin(commentConverter) + "(" + appliedArguments + ")" } } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Parameter.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Parameter.kt index 1e133700619..2c1692907df 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Parameter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Parameter.kt @@ -16,6 +16,8 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class Parameter(val identifier: Identifier, val `type`: Type, val varVal: Parameter.VarValModifier, @@ -27,10 +29,10 @@ class Parameter(val identifier: Identifier, Var } - override fun toKotlin(): String { + override fun toKotlinImpl(commentConverter: CommentConverter): String { val builder = StringBuilder() - builder.append(annotations.toKotlin()) + builder.append(annotations.toKotlin(commentConverter)) builder.append(modifiers.toKotlin()) if (`type` is VarArgType) { @@ -43,7 +45,7 @@ class Parameter(val identifier: Identifier, VarValModifier.Val -> builder.append("val ") } - builder.append(identifier.toKotlin()).append(": ").append(`type`.toKotlin()) + builder.append(identifier.toKotlin(commentConverter)).append(": ").append(`type`.toKotlin(commentConverter)) return builder.toString() } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/ParameterList.kt b/j2k/src/org/jetbrains/jet/j2k/ast/ParameterList.kt index f4b35a9cc3f..8a3e770801c 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/ParameterList.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/ParameterList.kt @@ -16,8 +16,10 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + open class ParameterList(val parameters: List) : Element() { - override fun toKotlin() = parameters.map { it.toKotlin() }.makeString(", ") + override fun toKotlinImpl(commentConverter: CommentConverter) = parameters.map { it.toKotlin(commentConverter) }.makeString(", ") } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/ReferenceElement.kt b/j2k/src/org/jetbrains/jet/j2k/ast/ReferenceElement.kt index b2045e8dd63..98b7eff616c 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/ReferenceElement.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/ReferenceElement.kt @@ -16,6 +16,8 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class ReferenceElement(val reference: Identifier, val types: List) : Element() { - override fun toKotlin() = reference.toKotlin() + types.toKotlin(", ", "<", ">") + override fun toKotlinImpl(commentConverter: CommentConverter) = reference.toKotlin(commentConverter) + types.toKotlin(commentConverter, ", ", "<", ">") } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Statements.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Statements.kt index 577e66b663c..a059e1bafea 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Statements.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Statements.kt @@ -16,10 +16,12 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + abstract class Statement() : Element() { object Empty : Statement() { - override fun toKotlin() = "" + override fun toKotlinImpl(commentConverter: CommentConverter) = "" override val isEmpty: Boolean get() = true @@ -27,20 +29,20 @@ abstract class Statement() : Element() { } class DeclarationStatement(val elements: List) : Statement() { - override fun toKotlin(): String - = elements.filterIsInstance(javaClass()).map { it.toKotlin() }.makeString("\n") + override fun toKotlinImpl(commentConverter: CommentConverter): String + = elements.filterIsInstance(javaClass()).map { it.toKotlin(commentConverter) }.makeString("\n") } class ExpressionListStatement(val expressions: List) : Expression() { - override fun toKotlin() = expressions.toKotlin("\n") + override fun toKotlinImpl(commentConverter: CommentConverter) = expressions.toKotlin(commentConverter, "\n") } class LabelStatement(val name: Identifier, val statement: Element) : Statement() { - override fun toKotlin(): String = "@" + name.toKotlin() + " " + statement.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter): String = "@" + name.toKotlin(commentConverter) + " " + statement.toKotlin(commentConverter) } class ReturnStatement(val expression: Expression) : Statement() { - override fun toKotlin() = "return " + expression.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter) = "return " + expression.toKotlin(commentConverter) } class IfStatement( @@ -51,10 +53,10 @@ class IfStatement( ) : Expression() { private val br = if (singleLine) " " else "\n" - override fun toKotlin(): String { - val result = "if (" + condition.toKotlin() + ")$br" + thenStatement.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter): String { + val result = "if (" + condition.toKotlin(commentConverter) + ")$br" + thenStatement.toKotlin(commentConverter) if (!elseStatement.isEmpty) { - return "$result${br}else$br${elseStatement.toKotlin()}" + return "$result${br}else$br${elseStatement.toKotlin(commentConverter)}" } return result } @@ -65,13 +67,13 @@ class IfStatement( class WhileStatement(val condition: Expression, val body: Element, singleLine: Boolean) : Statement() { private val br = if (singleLine) " " else "\n" - override fun toKotlin() = "while (" + condition.toKotlin() + ")$br" + body.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter) = "while (" + condition.toKotlin(commentConverter) + ")$br" + body.toKotlin(commentConverter) } class DoWhileStatement(val condition: Expression, val body: Element, singleLine: Boolean) : Statement() { private val br = if (singleLine) " " else "\n" - override fun toKotlin() = "do$br" + body.toKotlin() + "${br}while (" + condition.toKotlin() + ")" + override fun toKotlinImpl(commentConverter: CommentConverter) = "do$br" + body.toKotlin(commentConverter) + "${br}while (" + condition.toKotlin(commentConverter) + ")" } class ForeachStatement( @@ -83,7 +85,7 @@ class ForeachStatement( private val br = if (singleLine) " " else "\n" - override fun toKotlin() = "for (" + variable.identifier.toKotlin() + " in " + expression.toKotlin() + ")$br" + body.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter) = "for (" + variable.identifier.toKotlin(commentConverter) + " in " + expression.toKotlin(commentConverter) + ")$br" + body.toKotlin(commentConverter) } class ForeachWithRangeStatement(val identifier: Identifier, @@ -93,66 +95,66 @@ class ForeachWithRangeStatement(val identifier: Identifier, singleLine: Boolean) : Statement() { private val br = if (singleLine) " " else "\n" - override fun toKotlin() = "for (" + identifier.toKotlin() + " in " + start.toKotlin() + ".." + end.toKotlin() + ")$br" + body.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter) = "for (" + identifier.toKotlin(commentConverter) + " in " + start.toKotlin(commentConverter) + ".." + end.toKotlin(commentConverter) + ")$br" + body.toKotlin(commentConverter) } class BreakStatement(val label: Identifier = Identifier.Empty) : Statement() { - override fun toKotlin() = "break" + label.withPrefix("@") + override fun toKotlinImpl(commentConverter: CommentConverter) = "break" + label.withPrefix("@", commentConverter) } class ContinueStatement(val label: Identifier = Identifier.Empty) : Statement() { - override fun toKotlin() = "continue" + label.withPrefix("@") + override fun toKotlinImpl(commentConverter: CommentConverter) = "continue" + label.withPrefix("@", commentConverter) } // Exceptions ---------------------------------------------------------------------------------------------- class TryStatement(val block: Block, val catches: List, val finallyBlock: Block) : Statement() { - override fun toKotlin(): String { + override fun toKotlinImpl(commentConverter: CommentConverter): String { val builder = StringBuilder() .append("try\n") - .append(block.toKotlin()) + .append(block.toKotlin(commentConverter)) .append("\n") - .append(catches.toKotlin("\n")) + .append(catches.toKotlin(commentConverter, "\n")) .append("\n") if (!finallyBlock.isEmpty) { - builder.append("finally\n").append(finallyBlock.toKotlin()) + builder.append("finally\n").append(finallyBlock.toKotlin(commentConverter)) } return builder.toString() } } class ThrowStatement(val expression: Expression) : Expression() { - override fun toKotlin() = "throw " + expression.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter) = "throw " + expression.toKotlin(commentConverter) } class CatchStatement(val variable: Parameter, val block: Block) : Statement() { - override fun toKotlin(): String = "catch (" + variable.toKotlin() + ") " + block.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter): String = "catch (" + variable.toKotlin(commentConverter) + ") " + block.toKotlin(commentConverter) } // Switch -------------------------------------------------------------------------------------------------- class SwitchContainer(val expression: Expression, val caseContainers: List) : Statement() { - override fun toKotlin() = "when (" + expression.toKotlin() + ") {\n" + caseContainers.toKotlin("\n") + "\n}" + override fun toKotlinImpl(commentConverter: CommentConverter) = "when (" + expression.toKotlin(commentConverter) + ") {\n" + caseContainers.toKotlin(commentConverter, "\n") + "\n}" } class CaseContainer(val caseStatement: List, statements: List) : Statement() { private val block = Block(statements.filterNot { it is BreakStatement || it is ContinueStatement }, true) - override fun toKotlin() = caseStatement.toKotlin(", ") + " -> " + block.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter) = caseStatement.toKotlin(commentConverter, ", ") + " -> " + block.toKotlin(commentConverter) } class SwitchLabelStatement(val expression: Expression) : Statement() { - override fun toKotlin() = expression.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter) = expression.toKotlin(commentConverter) } class DefaultSwitchLabelStatement() : Statement() { - override fun toKotlin() = "else" + override fun toKotlinImpl(commentConverter: CommentConverter) = "else" } // Other ------------------------------------------------------------------------------------------------------ class SynchronizedStatement(val expression: Expression, val block: Block) : Statement() { - override fun toKotlin() = "synchronized (" + expression.toKotlin() + ") " + block.toKotlin() + override fun toKotlinImpl(commentConverter: CommentConverter) = "synchronized (" + expression.toKotlin(commentConverter) + ") " + block.toKotlin(commentConverter) } class StatementList(elements: List) diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt index f5ff5c77fbc..881c04e3e6e 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt @@ -16,8 +16,8 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.Converter import java.util.ArrayList +import org.jetbrains.jet.j2k.CommentConverter class Trait(name: Identifier, comments: MemberComments, @@ -33,7 +33,7 @@ class Trait(name: Identifier, override val keyword: String get() = "trait" - override fun primaryConstructorSignatureToKotlin() = "" + override fun primaryConstructorSignatureToKotlin(commentConverter: CommentConverter) = "" override fun modifiersToKotlin(): String { val modifierList = ArrayList() diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/TypeElement.kt b/j2k/src/org/jetbrains/jet/j2k/ast/TypeElement.kt index 320efd119b8..0a4a7961270 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/TypeElement.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/TypeElement.kt @@ -16,8 +16,8 @@ package org.jetbrains.jet.j2k.ast -class TypeElement(val `type`: Type) : Element() { - override fun toKotlin() = `type`.toKotlin() +import org.jetbrains.jet.j2k.CommentConverter - fun toKotlinNotNull(): String = `type`.toNotNullType().toKotlin() +class TypeElement(val `type`: Type) : Element() { + override fun toKotlinImpl(commentConverter: CommentConverter) = `type`.toKotlin(commentConverter) } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt b/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt index 87c1a0ef95c..7ecbb5ba7f0 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt @@ -20,37 +20,39 @@ import com.intellij.psi.PsiTypeParameter import org.jetbrains.jet.j2k.Converter import com.intellij.psi.PsiTypeParameterList import java.util.ArrayList +import org.jetbrains.jet.j2k.CommentConverter class TypeParameter(val name: Identifier, val extendsTypes: List) : Element() { fun hasWhere(): Boolean = extendsTypes.size() > 1 - fun getWhereToKotlin(): String { + fun whereToKotlin(commentConverter: CommentConverter): String { if (hasWhere()) { - return name.toKotlin() + " : " + extendsTypes[1].toKotlin() + return name.toKotlin(commentConverter) + " : " + extendsTypes[1].toKotlin(commentConverter) } return "" } - override fun toKotlin(): String { + override fun toKotlinImpl(commentConverter: CommentConverter): String { if (extendsTypes.size() > 0) { - return name.toKotlin() + " : " + extendsTypes[0].toKotlin() + return name.toKotlin(commentConverter) + " : " + extendsTypes[0].toKotlin(commentConverter) } - return name.toKotlin() + return name.toKotlin(commentConverter) } } class TypeParameterList(val parameters: List) : Element() { - override fun toKotlin(): String = if (!parameters.isEmpty()) - parameters.map { - it.toKotlin() - }.makeString(", ", "<", ">") - else "" + override fun toKotlinImpl(commentConverter: CommentConverter): String { + return if (parameters.isNotEmpty()) + parameters.map { it.toKotlin(commentConverter) }.makeString(", ", "<", ">") + else + "" + } - fun whereToKotlin(): String { + fun whereToKotlin(commentConverter: CommentConverter): String { if (hasWhere()) { - val wheres = parameters.map { it.getWhereToKotlin() } + val wheres = parameters.map { it.whereToKotlin(commentConverter) } return "where " + wheres.makeString(", ") } return "" @@ -71,7 +73,9 @@ fun Converter.convertTypeParameter(psiTypeParameter: PsiTypeParameter): TypePara return convertElement(psiTypeParameter) as TypeParameter } -fun Converter.convertTypeParameterList(psiTypeParameterlist: PsiTypeParameterList?): TypeParameterList { - return if (psiTypeParameterlist == null) TypeParameterList.Empty - else TypeParameterList(psiTypeParameterlist.getTypeParameters()!!.toList().map { convertTypeParameter(it) }) +fun Converter.convertTypeParameterList(typeParameterList: PsiTypeParameterList?): TypeParameterList { + return if (typeParameterList != null) + TypeParameterList(typeParameterList.getTypeParameters()!!.toList().map { convertTypeParameter(it) }) + else + TypeParameterList.Empty } \ No newline at end of file diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt index d9323120e59..2c81c825e2c 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt @@ -16,10 +16,9 @@ package org.jetbrains.jet.j2k.ast -import java.util.ArrayList import org.jetbrains.jet.j2k.ConverterSettings +import org.jetbrains.jet.j2k.CommentConverter -fun Type.isPrimitive(): Boolean = this is PrimitiveType fun Type.isUnit(): Boolean = this == Type.Unit enum class Nullability { @@ -34,17 +33,20 @@ fun Nullability.isNullable(settings: ConverterSettings) = when(this) { Nullability.Default -> !settings.forceNotNullTypes } -abstract class MayBeNullableType(nullability: Nullability, val settings: ConverterSettings) : Type { +abstract class MayBeNullableType(nullability: Nullability, val settings: ConverterSettings) : Type() { override val isNullable: Boolean = nullability.isNullable(settings) + + protected val isNullableStr: String + get() = if (isNullable) "?" else "" } -trait NotNullType : Type { +abstract class NotNullType() : Type() { override val isNullable: Boolean get() = false } -trait Type : Element { - val isNullable: Boolean +abstract class Type() : Element() { + abstract val isNullable: Boolean open fun toNotNullType(): Type { if (isNullable) throw UnsupportedOperationException("toNotNullType must be defined") @@ -56,31 +58,27 @@ trait Type : Element { return this } - protected fun isNullableStr(): String? { - return if (isNullable) "?" else "" + object Empty : NotNullType() { + override fun toKotlinImpl(commentConverter: CommentConverter): String = "UNRESOLVED_TYPE" } - object Empty : NotNullType { - override fun toKotlin(): String = "UNRESOLVED_TYPE" + object Unit: NotNullType() { + override fun toKotlinImpl(commentConverter: CommentConverter) = "Unit" } - object Unit: NotNullType { - override fun toKotlin() = "Unit" - } + override fun equals(other: Any?): Boolean = other is Type && other.toKotlin(CommentConverter.Dummy) == this.toKotlin(CommentConverter.Dummy) - override fun equals(other: Any?): Boolean = other is Type && other.toKotlin() == this.toKotlin() + override fun hashCode(): Int = toKotlin(CommentConverter.Dummy).hashCode() - override fun hashCode(): Int = toKotlin().hashCode() - - override fun toString(): String = toKotlin() + override fun toString(): String = toKotlin(CommentConverter.Dummy) } class ClassType(val `type`: Identifier, val typeArgs: List, nullability: Nullability, settings: ConverterSettings) : MayBeNullableType(nullability, settings) { - override fun toKotlin(): String { - var params = if (typeArgs.isEmpty()) "" else typeArgs.map { it.toKotlin() }.makeString(", ", "<", ">") - return `type`.toKotlin() + params + isNullableStr() + override fun toKotlinImpl(commentConverter: CommentConverter): String { + var params = if (typeArgs.isEmpty()) "" else typeArgs.map { it.toKotlin(commentConverter) }.makeString(", ", "<", ">") + return `type`.toKotlin(commentConverter) + params + isNullableStr } @@ -91,34 +89,34 @@ class ClassType(val `type`: Identifier, val typeArgs: List, nullability class ArrayType(val elementType: Type, nullability: Nullability, settings: ConverterSettings) : MayBeNullableType(nullability, settings) { - override fun toKotlin(): String { + override fun toKotlinImpl(commentConverter: CommentConverter): String { if (elementType is PrimitiveType) { - return elementType.toKotlin() + "Array" + isNullableStr() + return elementType.toKotlin(commentConverter) + "Array" + isNullableStr } - return "Array<" + elementType.toKotlin() + ">" + isNullableStr() + return "Array<" + elementType.toKotlin(commentConverter) + ">" + isNullableStr } override fun toNotNullType(): Type = ArrayType(elementType, Nullability.NotNull, settings) override fun toNullableType(): Type = ArrayType(elementType, Nullability.Nullable, settings) } -class InProjectionType(val bound: Type) : NotNullType { - override fun toKotlin(): String = "in " + bound.toKotlin() +class InProjectionType(val bound: Type) : NotNullType() { + override fun toKotlinImpl(commentConverter: CommentConverter): String = "in " + bound.toKotlin(commentConverter) } -class OutProjectionType(val bound: Type) : NotNullType { - override fun toKotlin(): String = "out " + bound.toKotlin() +class OutProjectionType(val bound: Type) : NotNullType() { + override fun toKotlinImpl(commentConverter: CommentConverter): String = "out " + bound.toKotlin(commentConverter) } -class StarProjectionType() : NotNullType { - override fun toKotlin(): String = "*" +class StarProjectionType() : NotNullType() { + override fun toKotlinImpl(commentConverter: CommentConverter): String = "*" } -class PrimitiveType(val `type`: Identifier) : NotNullType { - override fun toKotlin(): String = `type`.toKotlin() +class PrimitiveType(val `type`: Identifier) : NotNullType() { + override fun toKotlinImpl(commentConverter: CommentConverter): String = `type`.toKotlin(commentConverter) } -class VarArgType(val `type`: Type) : NotNullType { - override fun toKotlin(): String = `type`.toKotlin() +class VarArgType(val `type`: Type) : NotNullType() { + override fun toKotlinImpl(commentConverter: CommentConverter): String = `type`.toKotlin(commentConverter) } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt index 1df00b18f67..39282ad01f4 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt @@ -17,13 +17,14 @@ package org.jetbrains.jet.j2k.ast import java.util.ArrayList +import org.jetbrains.jet.j2k.CommentConverter -fun List.toKotlin(separator: String, prefix: String = "", postfix: String = ""): String - = if (isNotEmpty()) map { it.toKotlin() }.makeString(separator, prefix, postfix) else "" +fun List.toKotlin(commentConverter: CommentConverter, separator: String, prefix: String = "", postfix: String = ""): String + = if (isNotEmpty()) map { it.toKotlin(commentConverter) }.makeString(separator, prefix, postfix) else "" fun String.withSuffix(suffix: String): String = if (isEmpty()) "" else this + suffix fun String.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + this -fun Expression.withPrefix(prefix: String): String = if (isEmpty) "" else prefix + toKotlin() +fun Expression.withPrefix(prefix: String, commentConverter: CommentConverter): String = if (isEmpty) "" else prefix + toKotlin(commentConverter) open class WhiteSpaceSeparatedElementList( val elements: List, @@ -34,9 +35,9 @@ open class WhiteSpaceSeparatedElementList( fun isEmpty() = nonEmptyElements.all { it is WhiteSpace } - fun toKotlin(): String { + fun toKotlin(commentConverter: CommentConverter): String { if (isEmpty()) return "" - return nonEmptyElements.surroundWithWhiteSpaces().insertAndMergeWhiteSpaces().map { it.toKotlin() }.makeString("") + return nonEmptyElements.surroundWithWhiteSpaces().insertAndMergeWhiteSpaces().map { it.toKotlin(commentConverter) }.makeString("") } private fun List.surroundWithWhiteSpaces(): List @@ -71,9 +72,9 @@ open class WhiteSpaceSeparatedElementList( } } -fun Expression.operandToKotlin(operand: Expression, parenthesisForSamePrecedence: Boolean = false): String { +fun Expression.operandToKotlin(operand: Expression, commentConverter: CommentConverter, parenthesisForSamePrecedence: Boolean = false): String { val parentPrecedence = precedence() ?: throw IllegalArgumentException("Unknown precendence for $this") - val kotlinCode = operand.toKotlin() + val kotlinCode = operand.toKotlin(commentConverter) val operandPrecedence = operand.precedence() ?: return kotlinCode val needParenthesis = parentPrecedence < operandPrecedence || parentPrecedence == operandPrecedence && parenthesisForSamePrecedence return if (needParenthesis) "($kotlinCode)" else kotlinCode diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt b/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt index 3f5c1b8835c..30e53f184fa 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt @@ -16,9 +16,11 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.CommentConverter + class WhiteSpace(val text: String) : Element() { - override fun toKotlin() = text + override fun toKotlinImpl(commentConverter: CommentConverter) = text override val isEmpty: Boolean get() = text.isEmpty()