Java to Kotlin converter: working on not loosing comments - CommentConverter is passed when converting to Kotlin

This commit is contained in:
Valentin Kipyatkov
2014-06-17 14:11:08 +04:00
parent c4bac83cc9
commit d01a2237b5
37 changed files with 308 additions and 254 deletions
@@ -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<CommentInfo> = run {
val list = ArrayList<CommentInfo>()
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)
}
}
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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<PsiReferenceExpression> {
return ReferencesSearch.search(variable, LocalSearchScope(scope)).findAll().filterIsInstance(javaClass<PsiReferenceExpression>())
@@ -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<Pair<Identifier?, Expression>>, 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<Annotation>, val newLines: Boolean) {
class Annotations(val annotations: List<Annotation>, 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)
@@ -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)
}
@@ -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>) : Expression() {
override fun toKotlin(): String
= constructInnerType(`type`, expressions)
private fun constructInnerType(hostType: ArrayType, expressions: List<Expression>): 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<Expression>): 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)
}
}
+3 -2
View File
@@ -17,6 +17,7 @@
package org.jetbrains.jet.j2k.ast
import java.util.ArrayList
import org.jetbrains.jet.j2k.CommentConverter
fun Block(statements: List<Statement>, notEmpty: Boolean = false): Block {
val elements = ArrayList<Element>()
@@ -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 ""
+19 -18
View File
@@ -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<String> {
private fun baseClassSignatureWithParams(commentConverter: CommentConverter): List<String> {
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<String>()
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
@@ -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,
@@ -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
}
+7 -3
View File
@@ -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
}
+12 -10
View File
@@ -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)
}
}
@@ -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) + ")"
}
@@ -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
}
@@ -16,8 +16,10 @@
package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.CommentConverter
open class ExpressionList(val expressions: List<Expression>) : 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()
@@ -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<Expression>, 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<Expression>, 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")
}
}
+10 -4
View File
@@ -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 {
+5 -3
View File
@@ -16,10 +16,12 @@
package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.CommentConverter
class FileMemberList(elements: List<Element>) : 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
}
}
+9 -10
View File
@@ -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)
}
}
@@ -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()
}
}
+2 -2
View File
@@ -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<Import>) : 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 =
@@ -16,8 +16,10 @@
package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.CommentConverter
class Initializer(val block: Block, modifiers: Set<Modifier>) : Member(MemberComments.Empty, Annotations.Empty, modifiers) {
override fun toKotlin(): String {
return block.toKotlin()
override fun toKotlinImpl(commentConverter: CommentConverter): String {
return block.toKotlin(commentConverter)
}
}
@@ -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)}"
}
}
}
+10 -13
View File
@@ -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<Element>) : WhiteSpaceSeparatedElementList(elements, WhiteSpace.NoSpace) {
class object {
@@ -31,7 +26,7 @@ class MemberComments(elements: List<Element>) : WhiteSpaceSeparatedElementList(e
}
abstract class Member(val comments: MemberComments, val annotations: Annotations, val modifiers: Set<Modifier>) : 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 {
@@ -16,6 +16,8 @@
package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.CommentConverter
class MethodCallExpression(
val methodExpression: Expression,
val arguments: List<Expression>,
@@ -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()
}
@@ -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")
@@ -16,6 +16,8 @@
package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.CommentConverter
class NewClassExpression(
val name: Element,
val arguments: List<Expression>,
@@ -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 + ")"
}
}
}
@@ -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()
}
}
@@ -16,8 +16,10 @@
package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.CommentConverter
open class ParameterList(val parameters: List<Parameter>) : Element() {
override fun toKotlin() = parameters.map { it.toKotlin() }.makeString(", ")
override fun toKotlinImpl(commentConverter: CommentConverter) = parameters.map { it.toKotlin(commentConverter) }.makeString(", ")
}
@@ -16,6 +16,8 @@
package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.CommentConverter
class ReferenceElement(val reference: Identifier, val types: List<Type>) : Element() {
override fun toKotlin() = reference.toKotlin() + types.toKotlin(", ", "<", ">")
override fun toKotlinImpl(commentConverter: CommentConverter) = reference.toKotlin(commentConverter) + types.toKotlin(commentConverter, ", ", "<", ">")
}
+28 -26
View File
@@ -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<Element>) : Statement() {
override fun toKotlin(): String
= elements.filterIsInstance(javaClass<LocalVariable>()).map { it.toKotlin() }.makeString("\n")
override fun toKotlinImpl(commentConverter: CommentConverter): String
= elements.filterIsInstance(javaClass<LocalVariable>()).map { it.toKotlin(commentConverter) }.makeString("\n")
}
class ExpressionListStatement(val expressions: List<Expression>) : 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<CatchStatement>, 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<CaseContainer>) : 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<Element>, statements: List<Statement>) : 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<Element>)
+2 -2
View File
@@ -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<Modifier>()
@@ -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)
}
@@ -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<Type>) : 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<TypeParameter>) : 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
}
+31 -33
View File
@@ -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<Element>, 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<Element>, 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)
}
+8 -7
View File
@@ -17,13 +17,14 @@
package org.jetbrains.jet.j2k.ast
import java.util.ArrayList
import org.jetbrains.jet.j2k.CommentConverter
fun List<Element>.toKotlin(separator: String, prefix: String = "", postfix: String = ""): String
= if (isNotEmpty()) map { it.toKotlin() }.makeString(separator, prefix, postfix) else ""
fun List<Element>.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<Element>,
@@ -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<Element>.surroundWithWhiteSpaces(): List<Element>
@@ -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
@@ -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()