Java to Kotlin converter: big refactoring of code generation to never allow end of line comments to stick together with further code
#KT-4421 Fixed
This commit is contained in:
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.j2k
|
||||||
|
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import java.util.HashSet
|
||||||
|
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
|
||||||
|
import java.util.ArrayList
|
||||||
|
import org.jetbrains.jet.j2k.ast.Element
|
||||||
|
import kotlin.platform.platformName
|
||||||
|
|
||||||
|
fun<T> CodeBuilder.append(generators: Collection<() -> T>, separator: String, prefix: String = "", suffix: String = ""): CodeBuilder {
|
||||||
|
if (generators.isNotEmpty()) {
|
||||||
|
append(prefix)
|
||||||
|
var first = true
|
||||||
|
for (generator in generators) {
|
||||||
|
if (!first) {
|
||||||
|
append(separator)
|
||||||
|
}
|
||||||
|
generator()
|
||||||
|
first = false
|
||||||
|
}
|
||||||
|
append(suffix)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
platformName("appendElements")
|
||||||
|
fun CodeBuilder.append(elements: Collection<Element>, separator: String, prefix: String = "", suffix: String = ""): CodeBuilder {
|
||||||
|
return append(elements.filter { !it.isEmpty }.map { { append(it) } }, separator, prefix, suffix)
|
||||||
|
}
|
||||||
|
|
||||||
|
class CodeBuilder(private val topElement: PsiElement?) {
|
||||||
|
private val builder = StringBuilder()
|
||||||
|
private var endOfLineCommentAtEnd = false
|
||||||
|
|
||||||
|
private val commentsAndSpacesUsed = HashSet<PsiElement>()
|
||||||
|
|
||||||
|
public fun append(text: String, endOfLineComment: Boolean = false): CodeBuilder {
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
assert(!endOfLineComment)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endOfLineCommentAtEnd) {
|
||||||
|
if (text[0] != '\n' && text[0] != '\r') builder.append('\n')
|
||||||
|
endOfLineCommentAtEnd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(text)
|
||||||
|
endOfLineCommentAtEnd = endOfLineComment
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public val result: String
|
||||||
|
get() = builder.toString()
|
||||||
|
|
||||||
|
public fun append(element: Element): CodeBuilder {
|
||||||
|
if (element.isEmpty) return this // do not insert comment and spaces for empty elements to avoid multiple blank lines
|
||||||
|
|
||||||
|
if (element.prototypes.isEmpty() || topElement == null) {
|
||||||
|
element.generateCode(this)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
val prefixElements = ArrayList<PsiElement>(2)
|
||||||
|
val postfixElements = ArrayList<PsiElement>(2)
|
||||||
|
for ((prototype, inheritBlankLinesBefore) in element.prototypes) {
|
||||||
|
assert(prototype !is PsiComment)
|
||||||
|
assert(prototype !is PsiWhiteSpace)
|
||||||
|
assert(topElement.isAncestor(prototype))
|
||||||
|
prefixElements.collectPrefixElements(prototype, inheritBlankLinesBefore)
|
||||||
|
postfixElements.collectPostfixElements(prototype)
|
||||||
|
}
|
||||||
|
|
||||||
|
commentsAndSpacesUsed.addAll(prefixElements)
|
||||||
|
commentsAndSpacesUsed.addAll(postfixElements)
|
||||||
|
|
||||||
|
for (i in prefixElements.indices) {
|
||||||
|
val e = prefixElements[i]
|
||||||
|
if (i == 0 && e is PsiWhiteSpace) {
|
||||||
|
if (e.newLinesCount() > 1) { // insert at maximum one blank line
|
||||||
|
append("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
append(e.getText()!!, e.isEndOfLineComment())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
element.generateCode(this)
|
||||||
|
|
||||||
|
postfixElements.forEach { append(it.getText()!!, it.isEndOfLineComment()) }
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableList<PsiElement>.collectPrefixElements(element: PsiElement, allowBlankLinesBefore: Boolean) {
|
||||||
|
val atStart = ArrayList<PsiElement>(2).collectCommentsAndSpacesAtStart(element)
|
||||||
|
|
||||||
|
val before = ArrayList<PsiElement>(2).collectCommentsAndSpacesBefore(element)
|
||||||
|
if (!allowBlankLinesBefore && before.lastOrNull() is PsiWhiteSpace) {
|
||||||
|
before.remove(before.size - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
addAll(before.reverse())
|
||||||
|
addAll(atStart)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableList<PsiElement>.collectPostfixElements(element: PsiElement) {
|
||||||
|
val atEnd = ArrayList<PsiElement>(2).collectCommentsAndSpacesAtEnd(element)
|
||||||
|
|
||||||
|
val after = ArrayList<PsiElement>(2).collectCommentsAndSpacesAfter(element)
|
||||||
|
if (after.isNotEmpty()) {
|
||||||
|
val last = after.last()
|
||||||
|
if (last is PsiWhiteSpace) {
|
||||||
|
after.remove(after.size - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addAll(atEnd.reverse())
|
||||||
|
addAll(after)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableList<PsiElement>.collectCommentsAndSpacesBefore(element: PsiElement): MutableList<PsiElement> {
|
||||||
|
if (element == topElement) return this
|
||||||
|
|
||||||
|
val prev = element.getPrevSibling()
|
||||||
|
if (prev != null) {
|
||||||
|
if (prev.isCommentOrSpace()) {
|
||||||
|
if (prev !in commentsAndSpacesUsed) {
|
||||||
|
add(prev)
|
||||||
|
collectCommentsAndSpacesBefore(prev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (prev.isEmptyElement()){
|
||||||
|
collectCommentsAndSpacesBefore(prev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
collectCommentsAndSpacesBefore(element.getParent()!!)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableList<PsiElement>.collectCommentsAndSpacesAfter(element: PsiElement): MutableList<PsiElement> {
|
||||||
|
if (element == topElement) return this
|
||||||
|
|
||||||
|
val next = element.getNextSibling()
|
||||||
|
if (next != null) {
|
||||||
|
if (next.isCommentOrSpace()) {
|
||||||
|
if (next is PsiWhiteSpace && next.hasNewLines()) return this // do not attach anything on next line after element
|
||||||
|
if (next !in commentsAndSpacesUsed) {
|
||||||
|
add(next)
|
||||||
|
collectCommentsAndSpacesAfter(next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (next.isEmptyElement()){
|
||||||
|
collectCommentsAndSpacesAfter(next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
collectCommentsAndSpacesAfter(element.getParent()!!)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableList<PsiElement>.collectCommentsAndSpacesAtStart(element: PsiElement): MutableList<PsiElement> {
|
||||||
|
var child = element.getFirstChild()
|
||||||
|
while(child != null) {
|
||||||
|
if (child!!.isCommentOrSpace()) {
|
||||||
|
if (child !in commentsAndSpacesUsed) add(child!!) else break
|
||||||
|
}
|
||||||
|
else if (!child!!.isEmptyElement()) {
|
||||||
|
collectCommentsAndSpacesAtStart(child!!)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
child = child!!.getNextSibling()
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableList<PsiElement>.collectCommentsAndSpacesAtEnd(element: PsiElement): MutableList<PsiElement> {
|
||||||
|
var child = element.getLastChild()
|
||||||
|
while(child != null) {
|
||||||
|
if (child!!.isCommentOrSpace()) {
|
||||||
|
if (child !in commentsAndSpacesUsed) add(child!!) else break
|
||||||
|
}
|
||||||
|
else if (!child!!.isEmptyElement()) {
|
||||||
|
collectCommentsAndSpacesAtEnd(child!!)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
child = child!!.getPrevSibling()
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.isCommentOrSpace() = this is PsiComment || this is PsiWhiteSpace
|
||||||
|
|
||||||
|
private fun PsiElement.isEndOfLineComment() = this is PsiComment && getTokenType() == JavaTokenType.END_OF_LINE_COMMENT
|
||||||
|
|
||||||
|
private fun PsiElement.isEmptyElement() = getFirstChild() == null && getTextLength() == 0
|
||||||
|
|
||||||
|
private fun PsiWhiteSpace.newLinesCount() = getText()!!.count { it == '\n' } //TODO: this is not correct!!
|
||||||
|
|
||||||
|
private fun PsiWhiteSpace.hasNewLines() = getText()!!.any { it == '\n' || it == '\r' }
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2014 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.jet.j2k
|
|
||||||
|
|
||||||
import com.intellij.psi.*
|
|
||||||
import java.util.HashSet
|
|
||||||
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
|
|
||||||
import java.util.ArrayList
|
|
||||||
import org.jetbrains.jet.j2k.ast.PrototypeInfo
|
|
||||||
|
|
||||||
class CommentsAndSpaces(private val topElement: PsiElement?) {
|
|
||||||
private val commentsAndSpacesUsed = HashSet<PsiElement>()
|
|
||||||
|
|
||||||
public fun wrapElement(elementToKotlin: () -> String, prototypes: List<PrototypeInfo>): String {
|
|
||||||
if (prototypes.isEmpty() || topElement == null) return elementToKotlin()
|
|
||||||
|
|
||||||
val prefix = StringBuilder()
|
|
||||||
val postfix = StringBuilder()
|
|
||||||
for ((element, inheritBlankLinesBefore) in prototypes) {
|
|
||||||
assert(element !is PsiComment)
|
|
||||||
assert(element !is PsiWhiteSpace)
|
|
||||||
assert(topElement.isAncestor(element))
|
|
||||||
prefix.collectPrefix(element, inheritBlankLinesBefore)
|
|
||||||
postfix.collectPostfix(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
return prefix.toString() + elementToKotlin() + postfix.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun StringBuilder.collectPrefix(element: PsiElement, allowBlankLinesBefore: Boolean) {
|
|
||||||
val atStart = ArrayList<PsiElement>(2).addCommentsAndSpacesAtStart(element)
|
|
||||||
|
|
||||||
val before = ArrayList<PsiElement>(2).addCommentsAndSpacesBefore(element)
|
|
||||||
if (before.isNotEmpty()) {
|
|
||||||
val last = before.last()
|
|
||||||
if (last is PsiWhiteSpace) {
|
|
||||||
if (allowBlankLinesBefore) {
|
|
||||||
val blankLines = last.newLinesCount() - 1
|
|
||||||
if (blankLines > 0) {
|
|
||||||
append("\n") // insert at maximum one blank line
|
|
||||||
commentsAndSpacesUsed.add(last)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
before.remove(before.size - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (before.isEmpty() && atStart.isEmpty()) return
|
|
||||||
|
|
||||||
for (e in before.reverse() + atStart) {
|
|
||||||
append(e.getText())
|
|
||||||
commentsAndSpacesUsed.add(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun StringBuilder.collectPostfix(element: PsiElement) {
|
|
||||||
val atEnd = ArrayList<PsiElement>(2).addCommentsAndSpacesAtEnd(element)
|
|
||||||
|
|
||||||
val after = ArrayList<PsiElement>(2).addCommentsAndSpacesAfter(element)
|
|
||||||
if (after.isNotEmpty()) {
|
|
||||||
val last = after.last()
|
|
||||||
if (last is PsiWhiteSpace) {
|
|
||||||
after.remove(after.size - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (after.isEmpty() && atEnd.isEmpty()) return
|
|
||||||
|
|
||||||
for (e in atEnd.reverse() + after) {
|
|
||||||
append(e.getText())
|
|
||||||
commentsAndSpacesUsed.add(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MutableList<PsiElement>.addCommentsAndSpacesBefore(element: PsiElement): MutableList<PsiElement> {
|
|
||||||
if (element == topElement) return this
|
|
||||||
|
|
||||||
val prev = element.getPrevSibling()
|
|
||||||
if (prev != null) {
|
|
||||||
if (prev.isCommentOrSpace()) {
|
|
||||||
if (prev !in commentsAndSpacesUsed) {
|
|
||||||
add(prev)
|
|
||||||
addCommentsAndSpacesBefore(prev)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (prev.isEmptyElement()){
|
|
||||||
addCommentsAndSpacesBefore(prev)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addCommentsAndSpacesBefore(element.getParent()!!)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MutableList<PsiElement>.addCommentsAndSpacesAfter(element: PsiElement): MutableList<PsiElement> {
|
|
||||||
if (element == topElement) return this
|
|
||||||
|
|
||||||
val next = element.getNextSibling()
|
|
||||||
if (next != null) {
|
|
||||||
if (next.isCommentOrSpace()) {
|
|
||||||
if (next is PsiWhiteSpace && next.hasNewLines()) return this // do not attach anything on next line after element
|
|
||||||
if (next !in commentsAndSpacesUsed) {
|
|
||||||
add(next)
|
|
||||||
addCommentsAndSpacesAfter(next)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (next.isEmptyElement()){
|
|
||||||
addCommentsAndSpacesAfter(next)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addCommentsAndSpacesAfter(element.getParent()!!)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MutableList<PsiElement>.addCommentsAndSpacesAtStart(element: PsiElement): MutableList<PsiElement> {
|
|
||||||
var child = element.getFirstChild()
|
|
||||||
while(child != null) {
|
|
||||||
if (child!!.isCommentOrSpace()) {
|
|
||||||
if (child !in commentsAndSpacesUsed) add(child!!) else break
|
|
||||||
}
|
|
||||||
else if (!child!!.isEmptyElement()) {
|
|
||||||
addCommentsAndSpacesAtStart(child!!)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
child = child!!.getNextSibling()
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MutableList<PsiElement>.addCommentsAndSpacesAtEnd(element: PsiElement): MutableList<PsiElement> {
|
|
||||||
var child = element.getLastChild()
|
|
||||||
while(child != null) {
|
|
||||||
if (child!!.isCommentOrSpace()) {
|
|
||||||
if (child !in commentsAndSpacesUsed) add(child!!) else break
|
|
||||||
}
|
|
||||||
else if (!child!!.isEmptyElement()) {
|
|
||||||
addCommentsAndSpacesAtEnd(child!!)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
child = child!!.getPrevSibling()
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PsiElement.isCommentOrSpace() = this is PsiComment || this is PsiWhiteSpace
|
|
||||||
|
|
||||||
private fun PsiElement.isEmptyElement() = getFirstChild() == null && getTextLength() == 0
|
|
||||||
|
|
||||||
private fun PsiWhiteSpace.newLinesCount() = getText()!!.count { it == '\n' } //TODO: this is not correct!!
|
|
||||||
|
|
||||||
private fun PsiWhiteSpace.hasNewLines() = getText()!!.any { it == '\n' || it == '\r' }
|
|
||||||
|
|
||||||
class object {
|
|
||||||
val None: CommentsAndSpaces = CommentsAndSpaces(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -59,8 +59,12 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
|||||||
fun withStatementVisitor(factory: (Converter) -> StatementVisitor): Converter
|
fun withStatementVisitor(factory: (Converter) -> StatementVisitor): Converter
|
||||||
= Converter(project, settings, conversionScope, State(typeConverter, state.methodReturnType, state.expressionVisitorFactory, factory))
|
= Converter(project, settings, conversionScope, State(typeConverter, state.methodReturnType, state.expressionVisitorFactory, factory))
|
||||||
|
|
||||||
public fun elementToKotlin(element: PsiElement): String
|
public fun elementToKotlin(element: PsiElement): String {
|
||||||
= convertTopElement(element)?.toKotlin(CommentsAndSpaces(element)) ?: ""
|
val converted = convertTopElement(element) ?: return ""
|
||||||
|
val builder = CodeBuilder(element)
|
||||||
|
builder.append(converted)
|
||||||
|
return builder.result
|
||||||
|
}
|
||||||
|
|
||||||
private fun convertTopElement(element: PsiElement?): Element? = when(element) {
|
private fun convertTopElement(element: PsiElement?): Element? = when(element) {
|
||||||
is PsiJavaFile -> convertFile(element)
|
is PsiJavaFile -> convertFile(element)
|
||||||
@@ -519,7 +523,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
|||||||
fun convertParameter(parameter: PsiParameter,
|
fun convertParameter(parameter: PsiParameter,
|
||||||
nullability: Nullability = Nullability.Default,
|
nullability: Nullability = Nullability.Default,
|
||||||
varValModifier: Parameter.VarValModifier = Parameter.VarValModifier.None,
|
varValModifier: Parameter.VarValModifier = Parameter.VarValModifier.None,
|
||||||
modifiers: Collection<Modifier> = listOf()): Parameter {
|
modifiers: List<Modifier> = listOf()): Parameter {
|
||||||
var `type` = typeConverter.convertVariableType(parameter)
|
var `type` = typeConverter.convertVariableType(parameter)
|
||||||
when (nullability) {
|
when (nullability) {
|
||||||
Nullability.NotNull -> `type` = `type`.toNotNullType()
|
Nullability.NotNull -> `type` = `type`.toNotNullType()
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ fun getDefaultInitializer(field: Field): Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (t is PrimitiveType) {
|
if (t is PrimitiveType) {
|
||||||
when(t.`type`.name) {
|
when(t.name.name) {
|
||||||
"Boolean" -> return LiteralExpression("false")
|
"Boolean" -> return LiteralExpression("false")
|
||||||
"Char" -> return LiteralExpression("' '")
|
"Char" -> return LiteralExpression("' '")
|
||||||
"Double" -> return MethodCallExpression.buildNotNull(LiteralExpression("0"), OperatorConventions.DOUBLE.toString())
|
"Double" -> return MethodCallExpression.buildNotNull(LiteralExpression("0"), OperatorConventions.DOUBLE.toString())
|
||||||
|
|||||||
@@ -16,31 +16,46 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class Annotation(val name: Identifier, val arguments: List<Pair<Identifier?, Expression>>, val brackets: Boolean) : Element() {
|
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
|
private fun CodeBuilder.surroundWithBrackets(action: () -> Unit) {
|
||||||
|
if (brackets) append("[")
|
||||||
|
action()
|
||||||
|
if (brackets) append("]")
|
||||||
|
}
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
if (arguments.isEmpty()) {
|
if (arguments.isEmpty()) {
|
||||||
return surroundWithBrackets(name.toKotlin(commentsAndSpaces))
|
builder.surroundWithBrackets { builder.append(name) }
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val argsText = arguments.map {
|
builder.surroundWithBrackets {
|
||||||
if (it.first != null)
|
builder.append(name)
|
||||||
it.first!!.toKotlin(commentsAndSpaces) + " = " + it.second.toKotlin(commentsAndSpaces)
|
.append("(")
|
||||||
else
|
.append(arguments.map {
|
||||||
it.second.toKotlin(commentsAndSpaces)
|
{
|
||||||
}.makeString(", ")
|
if (it.first != null) {
|
||||||
return surroundWithBrackets(name.toKotlin(commentsAndSpaces) + "(" + argsText + ")")
|
builder append it.first!! append " = " append it.second
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder append it.second
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, ", ")
|
||||||
|
.append(")")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Annotations(val annotations: List<Annotation>, val newLines: Boolean) : Element() {
|
class Annotations(val annotations: List<Annotation>, val newLines: Boolean) : Element() {
|
||||||
private val br = if (newLines) "\n" else " "
|
private val br = if (newLines) "\n" else " "
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
return if (annotations.isNotEmpty()) annotations.map { it.toKotlin(commentsAndSpaces) }.makeString(br) + br else ""
|
if (annotations.isNotEmpty()) {
|
||||||
|
builder.append(annotations, br, "", br)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun plus(other: Annotations) = Annotations(annotations + other.annotations, newLines || other.newLines)
|
fun plus(other: Annotations) = Annotations(annotations + other.annotations, newLines || other.newLines)
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.CodeBuilder
|
||||||
|
|
||||||
class AnonymousClassBody(body: ClassBody, val extendsTrait: Boolean)
|
class AnonymousClassBody(body: ClassBody, val extendsTrait: Boolean)
|
||||||
: Class(Identifier.Empty, Annotations.Empty, setOf(), TypeParameterList.Empty, listOf(), listOf(), listOf(), body) {
|
: Class(Identifier.Empty, Annotations.Empty, setOf(), TypeParameterList.Empty, listOf(), listOf(), listOf(), body) {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = body.toKotlin(null, commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
body.append(builder, null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,41 +16,51 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.CodeBuilder
|
||||||
|
import org.jetbrains.jet.j2k.append
|
||||||
|
|
||||||
class ArrayWithoutInitializationExpression(val `type`: ArrayType, val expressions: List<Expression>) : Expression() {
|
class ArrayWithoutInitializationExpression(val `type`: ArrayType, val expressions: List<Expression>) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
fun getConstructorName(`type`: ArrayType, hasInit: Boolean): String {
|
fun appendConstructorName(`type`: ArrayType, hasInit: Boolean): CodeBuilder = when (`type`.elementType) {
|
||||||
return when (`type`.elementType) {
|
is PrimitiveType -> builder.append(`type`.toNotNullType())
|
||||||
is PrimitiveType ->
|
|
||||||
`type`.toNotNullType().toKotlin(commentsAndSpaces)
|
is ArrayType ->
|
||||||
is ArrayType ->
|
if (hasInit) {
|
||||||
if (hasInit)
|
builder.append(`type`.toNotNullType())
|
||||||
`type`.toNotNullType().toKotlin(commentsAndSpaces)
|
}
|
||||||
else
|
else {
|
||||||
"arrayOfNulls<" + `type`.elementType.toKotlin(commentsAndSpaces) + ">"
|
builder.append("arrayOfNulls<").append(`type`.elementType).append(">")
|
||||||
else ->
|
}
|
||||||
"arrayOfNulls<" + `type`.elementType.toKotlin(commentsAndSpaces) + ">"
|
|
||||||
|
else -> builder.append("arrayOfNulls<").append(`type`.elementType).append(">")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun oneDim(`type`: ArrayType, size: Expression, init: (() -> Unit)? = null): CodeBuilder {
|
||||||
|
appendConstructorName(`type`, init != null).append("(").append(size)
|
||||||
|
if (init != null) {
|
||||||
|
builder.append(", ")
|
||||||
|
init()
|
||||||
}
|
}
|
||||||
|
return builder.append(")")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun oneDim(`type`: ArrayType, size: Expression, init: String = ""): String {
|
fun constructInnerType(hostType: ArrayType, expressions: List<Expression>): CodeBuilder {
|
||||||
return getConstructorName(`type`, !init.isEmpty()) + "(" + size.toKotlin(commentsAndSpaces) + init.withPrefix(", ") + ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun constructInnerType(hostType: ArrayType, expressions: List<Expression>): String {
|
|
||||||
if (expressions.size() == 1) {
|
if (expressions.size() == 1) {
|
||||||
return oneDim(hostType, expressions[0])
|
return oneDim(hostType, expressions[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
val innerType = hostType.elementType
|
val innerType = hostType.elementType
|
||||||
if (expressions.size() > 1 && innerType is ArrayType) {
|
if (expressions.size() > 1 && innerType is ArrayType) {
|
||||||
return oneDim(hostType, expressions[0], "{" + constructInnerType(innerType, expressions.subList(1, expressions.size())) + "}")
|
return oneDim(hostType, expressions[0], {
|
||||||
|
builder.append("{")
|
||||||
|
constructInnerType(innerType, expressions.subList(1, expressions.size()))
|
||||||
|
builder.append("}")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return getConstructorName(hostType, expressions.size() != 0)
|
return appendConstructorName(hostType, expressions.isNotEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
return constructInnerType(`type`, expressions)
|
constructInnerType(`type`, expressions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,21 +16,19 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class Block(val statements: List<Statement>, val lBrace: LBrace, val rBrace: RBrace, val notEmpty: Boolean = false) : Statement() {
|
class Block(val statements: List<Statement>, val lBrace: LBrace, val rBrace: RBrace, val notEmpty: Boolean = false) : Statement() {
|
||||||
override val isEmpty: Boolean
|
override val isEmpty: Boolean
|
||||||
get() = !notEmpty && statements.all { it.isEmpty }
|
get() = !notEmpty && statements.all { it.isEmpty }
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
if (statements.all { it.isEmpty }) {
|
if (statements.all { it.isEmpty }) {
|
||||||
return if (isEmpty) "" else lBrace.toKotlin(commentsAndSpaces) + rBrace.toKotlin(commentsAndSpaces)
|
if (!isEmpty) builder.append(lBrace).append(rBrace)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return lBrace.toKotlin(commentsAndSpaces) +
|
|
||||||
"\n" +
|
builder.append(lBrace).append(statements, "\n", "\n", "\n").append(rBrace)
|
||||||
statements.toKotlin(commentsAndSpaces, "\n") +
|
|
||||||
"\n" +
|
|
||||||
rBrace.toKotlin(commentsAndSpaces)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class object {
|
class object {
|
||||||
@@ -40,9 +38,13 @@ class Block(val statements: List<Statement>, val lBrace: LBrace, val rBrace: RBr
|
|||||||
|
|
||||||
// we use LBrace and RBrace elements to better handle comments around them
|
// we use LBrace and RBrace elements to better handle comments around them
|
||||||
class LBrace() : Element() {
|
class LBrace() : Element() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "{"
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("{")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RBrace() : Element() {
|
class RBrace() : Element() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "}"
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
open class Class(
|
open class Class(
|
||||||
val name: Identifier,
|
val name: Identifier,
|
||||||
@@ -30,41 +30,38 @@ open class Class(
|
|||||||
val body: ClassBody
|
val body: ClassBody
|
||||||
) : Member(annotations, modifiers) {
|
) : Member(annotations, modifiers) {
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String =
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
annotations.toKotlin(commentsAndSpaces) +
|
builder.append(annotations)
|
||||||
modifiersToKotlin() +
|
appendModifiers(builder).append(keyword).append(" ").append(name).append(typeParameterList)
|
||||||
keyword + " " + name.toKotlin(commentsAndSpaces) +
|
appendPrimaryConstructorSignature(builder)
|
||||||
typeParameterList.toKotlin(commentsAndSpaces) +
|
appendBaseTypes(builder)
|
||||||
primaryConstructorSignatureToKotlin(commentsAndSpaces) +
|
typeParameterList.appendWhere(builder)
|
||||||
implementTypesToKotlin(commentsAndSpaces) +
|
body.append(builder, this)
|
||||||
typeParameterList.whereToKotlin(commentsAndSpaces).withPrefix(" ") +
|
}
|
||||||
body.toKotlin(this, commentsAndSpaces)
|
|
||||||
|
|
||||||
protected open val keyword: String
|
protected open val keyword: String
|
||||||
get() = "class"
|
get() = "class"
|
||||||
|
|
||||||
protected open fun primaryConstructorSignatureToKotlin(commentsAndSpaces: CommentsAndSpaces): String
|
protected open fun appendPrimaryConstructorSignature(builder: CodeBuilder) {
|
||||||
= body.primaryConstructor?.signatureToKotlin(commentsAndSpaces) ?: "()"
|
body.primaryConstructor?.appendSignature(builder) ?: builder.append("()")
|
||||||
|
}
|
||||||
|
|
||||||
private fun baseClassSignatureWithParams(commentsAndSpaces: CommentsAndSpaces): List<String> {
|
protected fun appendBaseTypes(builder: CodeBuilder) {
|
||||||
|
builder.append(baseClassSignatureWithParams(builder) + implementsTypes.map { { builder.append(it) } }, ", ", ":")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun baseClassSignatureWithParams(builder: CodeBuilder): List<() -> CodeBuilder> {
|
||||||
if (keyword.equals("class") && extendsTypes.size() == 1) {
|
if (keyword.equals("class") && extendsTypes.size() == 1) {
|
||||||
val baseParams = baseClassParams.toKotlin(commentsAndSpaces, ", ")
|
return listOf({
|
||||||
return arrayListOf(extendsTypes[0].toKotlin(commentsAndSpaces) + "(" + baseParams + ")")
|
builder append extendsTypes[0] append "("
|
||||||
|
builder.append(baseClassParams, ", ")
|
||||||
|
builder append ")"
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return extendsTypes.map { it.toKotlin(commentsAndSpaces) }
|
return extendsTypes.map { { builder.append(it) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun implementTypesToKotlin(commentsAndSpaces: CommentsAndSpaces): String {
|
protected open fun appendModifiers(builder: CodeBuilder): CodeBuilder {
|
||||||
val allTypes = ArrayList<String>()
|
|
||||||
allTypes.addAll(baseClassSignatureWithParams(commentsAndSpaces))
|
|
||||||
allTypes.addAll(implementsTypes.map { it.toKotlin(commentsAndSpaces) })
|
|
||||||
return if (allTypes.size() == 0)
|
|
||||||
""
|
|
||||||
else
|
|
||||||
" : " + allTypes.makeString(", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun modifiersToKotlin(): String {
|
|
||||||
val modifierList = ArrayList<Modifier>()
|
val modifierList = ArrayList<Modifier>()
|
||||||
|
|
||||||
modifiers.accessModifier()?.let { modifierList.add(it) }
|
modifiers.accessModifier()?.let { modifierList.add(it) }
|
||||||
@@ -80,6 +77,6 @@ open class Class(
|
|||||||
modifierList.add(Modifier.INNER)
|
modifierList.add(Modifier.INNER)
|
||||||
}
|
}
|
||||||
|
|
||||||
return modifierList.toKotlin()
|
return builder.append(modifierList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
abstract class Member(val annotations: Annotations, val modifiers: Set<Modifier>) : Element()
|
abstract class Member(val annotations: Annotations, val modifiers: Set<Modifier>) : Element()
|
||||||
|
|
||||||
@@ -28,37 +28,33 @@ class ClassBody (
|
|||||||
val lBrace: LBrace,
|
val lBrace: LBrace,
|
||||||
val rBrace: RBrace) {
|
val rBrace: RBrace) {
|
||||||
|
|
||||||
fun toKotlin(containingClass: Class?, commentsAndSpaces: CommentsAndSpaces): String {
|
fun append(builder: CodeBuilder, containingClass: Class?) {
|
||||||
val builder = StringBuilder()
|
if (normalMembers.isEmpty() && classObjectMembers.isEmpty() && secondaryConstructors.isEmpty() && (primaryConstructor?.block?.isEmpty ?: true)) return
|
||||||
builder.append(normalMembers.toKotlin(commentsAndSpaces, "\n"))
|
|
||||||
|
|
||||||
val primaryConstructor = primaryConstructorBodyToKotlin(commentsAndSpaces)
|
builder append " " append lBrace append "\n"
|
||||||
if (primaryConstructor.isNotEmpty() && builder.length() > 0) {
|
|
||||||
builder.append("\n\n") // blank line before constructor body
|
|
||||||
}
|
|
||||||
builder.append(primaryConstructor)
|
|
||||||
|
|
||||||
val classObject = classObjectToKotlin(containingClass, commentsAndSpaces)
|
builder.append(normalMembers, "\n")
|
||||||
if (classObject.isNotEmpty() && builder.length() > 0) {
|
var notEmpty = normalMembers.isNotEmpty()
|
||||||
builder.append("\n\n") // blank line before class object
|
|
||||||
}
|
|
||||||
builder.append(classObject)
|
|
||||||
|
|
||||||
return if (builder.length() > 0)
|
notEmpty = appendPrimaryConstructorBody(builder, notEmpty) || notEmpty
|
||||||
" " + lBrace.toKotlin(commentsAndSpaces) + "\n" + builder + "\n" + rBrace.toKotlin(commentsAndSpaces)
|
|
||||||
else
|
appendClassObject(builder, containingClass, notEmpty)
|
||||||
""
|
|
||||||
|
builder append "\n" append rBrace
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun primaryConstructorBodyToKotlin(commentsAndSpaces: CommentsAndSpaces): String {
|
private fun appendPrimaryConstructorBody(builder: CodeBuilder, blankLineBefore: Boolean): Boolean {
|
||||||
val constructor = primaryConstructor
|
val constructor = primaryConstructor
|
||||||
if (constructor == null || constructor.block?.isEmpty ?: true) return ""
|
if (constructor == null || constructor.block?.isEmpty ?: true) return false
|
||||||
return constructor.bodyToKotlin(commentsAndSpaces)
|
if (blankLineBefore) builder.append("\n\n")
|
||||||
|
constructor.appendBody(builder)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun classObjectToKotlin(containingClass: Class?, commentsAndSpaces: CommentsAndSpaces): String {
|
private fun appendClassObject(builder: CodeBuilder, containingClass: Class?, blankLineBefore: Boolean) {
|
||||||
if (secondaryConstructors.isEmpty() && classObjectMembers.isEmpty()) return ""
|
if (secondaryConstructors.isEmpty() && classObjectMembers.isEmpty()) return
|
||||||
|
if (blankLineBefore) builder.append("\n\n")
|
||||||
val factoryFunctions = secondaryConstructors.map { it.toFactoryFunction(containingClass) }
|
val factoryFunctions = secondaryConstructors.map { it.toFactoryFunction(containingClass) }
|
||||||
return "class object {\n" + (factoryFunctions + classObjectMembers).toKotlin(commentsAndSpaces, "\n") + "\n}"
|
builder.append(factoryFunctions + classObjectMembers, "\n", "class object {\n", "\n}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.Converter
|
|
||||||
import java.util.HashSet
|
import java.util.HashSet
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
abstract class Constructor(
|
abstract class Constructor(
|
||||||
converter: Converter,
|
converter: Converter,
|
||||||
@@ -36,13 +35,13 @@ class PrimaryConstructor(converter: Converter,
|
|||||||
block: Block)
|
block: Block)
|
||||||
: Constructor(converter, annotations, modifiers, parameterList, block) {
|
: Constructor(converter, annotations, modifiers, parameterList, block) {
|
||||||
|
|
||||||
public fun signatureToKotlin(commentsAndSpaces: CommentsAndSpaces): String {
|
public fun appendSignature(builder: CodeBuilder): CodeBuilder {
|
||||||
val accessModifier = modifiers.accessModifier()
|
val accessModifier = modifiers.accessModifier()
|
||||||
val modifiersString = if (accessModifier != null && accessModifier != Modifier.PUBLIC) " " + accessModifier.toKotlin() else ""
|
val modifiersString = if (accessModifier != null && accessModifier != Modifier.PUBLIC) " " + accessModifier.toKotlin() else ""
|
||||||
return modifiersString + "(" + parameterList.toKotlin(commentsAndSpaces) + ")"
|
return builder.append(modifiersString).append("(").append(parameterList).append(")")
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun bodyToKotlin(commentsAndSpaces: CommentsAndSpaces): String = block!!.toKotlin(commentsAndSpaces)
|
public fun appendBody(builder: CodeBuilder): CodeBuilder = builder.append(block!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
class SecondaryConstructor(converter: Converter,
|
class SecondaryConstructor(converter: Converter,
|
||||||
|
|||||||
@@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.CodeBuilder
|
||||||
|
|
||||||
class DummyStringExpression(val string: String) : Expression() {
|
class DummyStringExpression(val string: String) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = string
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(string)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
|
||||||
fun <TElement: Element> TElement.assignPrototype(prototype: PsiElement?): TElement {
|
fun <TElement: Element> TElement.assignPrototype(prototype: PsiElement?): TElement {
|
||||||
@@ -36,6 +36,12 @@ fun <TElement: Element> TElement.assignPrototypesFrom(element: Element): TElemen
|
|||||||
|
|
||||||
data class PrototypeInfo(val element: PsiElement, val inheritBlankLinesBefore: Boolean)
|
data class PrototypeInfo(val element: PsiElement, val inheritBlankLinesBefore: Boolean)
|
||||||
|
|
||||||
|
fun Element.canonicalCode(): String {
|
||||||
|
val builder = CodeBuilder(null)
|
||||||
|
builder.append(this)
|
||||||
|
return builder.result
|
||||||
|
}
|
||||||
|
|
||||||
abstract class Element {
|
abstract class Element {
|
||||||
public var prototypes: List<PrototypeInfo> = listOf()
|
public var prototypes: List<PrototypeInfo> = listOf()
|
||||||
private set
|
private set
|
||||||
@@ -44,19 +50,13 @@ abstract class Element {
|
|||||||
this.prototypes = prototypes
|
this.prototypes = prototypes
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun toKotlin(commentsAndSpaces: CommentsAndSpaces): String {
|
/** This method should not be used anywhere except for CodeBuilder! Use CodeBuilder.append instead. */
|
||||||
return if (isEmpty) // do not insert comment and spaces for empty elements to avoid multiple blank lines
|
public abstract fun generateCode(builder: CodeBuilder)
|
||||||
""
|
|
||||||
else
|
|
||||||
commentsAndSpaces.wrapElement({ toKotlinImpl(commentsAndSpaces) }, prototypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String
|
|
||||||
|
|
||||||
public open val isEmpty: Boolean get() = false
|
public open val isEmpty: Boolean get() = false
|
||||||
|
|
||||||
object Empty : Element() {
|
object Empty : Element() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = ""
|
override fun generateCode(builder: CodeBuilder) { }
|
||||||
override val isEmpty: Boolean get() = true
|
override val isEmpty: Boolean get() = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class Enum(
|
class Enum(
|
||||||
name: Identifier,
|
name: Identifier,
|
||||||
@@ -30,16 +30,16 @@ class Enum(
|
|||||||
) : Class(name, annotations, modifiers, typeParameterList,
|
) : Class(name, annotations, modifiers, typeParameterList,
|
||||||
extendsTypes, baseClassParams, implementsTypes, body) {
|
extendsTypes, baseClassParams, implementsTypes, body) {
|
||||||
|
|
||||||
override fun primaryConstructorSignatureToKotlin(commentsAndSpaces: CommentsAndSpaces): String
|
override fun appendPrimaryConstructorSignature(builder: CodeBuilder) {
|
||||||
= body.primaryConstructor?.signatureToKotlin(commentsAndSpaces) ?: ""
|
body.primaryConstructor?.appendSignature(builder)
|
||||||
|
}
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
return annotations.toKotlin(commentsAndSpaces) +
|
builder append annotations
|
||||||
modifiersToKotlin() +
|
appendModifiers(builder) append "enum class " append name
|
||||||
"enum class " + name.toKotlin(commentsAndSpaces) +
|
appendPrimaryConstructorSignature(builder)
|
||||||
primaryConstructorSignatureToKotlin(commentsAndSpaces) +
|
builder append typeParameterList
|
||||||
typeParameterList.toKotlin(commentsAndSpaces) +
|
appendBaseTypes(builder)
|
||||||
implementTypesToKotlin(commentsAndSpaces) +
|
body.append(builder, this)
|
||||||
body.toKotlin(this, commentsAndSpaces)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class EnumConstant(
|
class EnumConstant(
|
||||||
identifier: Identifier,
|
identifier: Identifier,
|
||||||
@@ -26,12 +26,13 @@ class EnumConstant(
|
|||||||
params: Element
|
params: Element
|
||||||
) : Field(identifier, annotations, modifiers, `type`.toNotNullType(), params, true, false) {
|
) : Field(identifier, annotations, modifiers, `type`.toNotNullType(), params, true, false) {
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
if (initializer.toKotlin(commentsAndSpaces).isEmpty()) {
|
if (initializer.isEmpty) {
|
||||||
return annotations.toKotlin(commentsAndSpaces) + identifier.toKotlin(commentsAndSpaces)
|
builder append annotations append identifier
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return annotations.toKotlin(commentsAndSpaces) + identifier.toKotlin(commentsAndSpaces) + " : " + `type`.toKotlin(commentsAndSpaces) + "(" + initializer.toKotlin(commentsAndSpaces) + ")"
|
builder append annotations append identifier append " : " append `type` append "(" append initializer append ")"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.CodeBuilder
|
||||||
|
|
||||||
|
|
||||||
abstract class Expression() : Statement() {
|
abstract class Expression() : Statement() {
|
||||||
open val isNullable: Boolean get() = false
|
open val isNullable: Boolean get() = false
|
||||||
|
|
||||||
object Empty : Expression() {
|
object Empty : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = ""
|
override fun generateCode(builder: CodeBuilder) {}
|
||||||
|
|
||||||
override val isEmpty: Boolean get() = true
|
override val isEmpty: Boolean get() = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class ExpressionList(val expressions: List<Expression>) : Expression() {
|
class ExpressionList(val expressions: List<Expression>) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = expressions.map { it.toKotlin(commentsAndSpaces) }.makeString(", ")
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(expressions, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
override val isEmpty: Boolean
|
override val isEmpty: Boolean
|
||||||
get() = expressions.isEmpty()
|
get() = expressions.isEmpty()
|
||||||
|
|||||||
@@ -17,115 +17,144 @@
|
|||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
|
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class ArrayAccessExpression(val expression: Expression, val index: Expression, val lvalue: Boolean) : Expression() {
|
class ArrayAccessExpression(val expression: Expression, val index: Expression, val lvalue: Boolean) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = operandToKotlin(expression, commentsAndSpaces) +
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
(if (!lvalue && expression.isNullable) "!!" else "") +
|
builder.appendOperand(this, expression)
|
||||||
"[" + index.toKotlin(commentsAndSpaces) + "]"
|
if (!lvalue && expression.isNullable) builder.append("!!")
|
||||||
|
builder append "[" append index append "]"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AssignmentExpression(val left: Expression, val right: Expression, val op: String) : Expression() {
|
class AssignmentExpression(val left: Expression, val right: Expression, val op: String) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = operandToKotlin(left, commentsAndSpaces) + " " + op + " " + operandToKotlin(right, commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.appendOperand(this, left).append(op).appendOperand(this, right)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BangBangExpression(val expr: Expression) : Expression() {
|
class BangBangExpression(val expr: Expression) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = operandToKotlin(expr, commentsAndSpaces) + "!!"
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.appendOperand(this, expr).append("!!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BinaryExpression(val left: Expression, val right: Expression, val op: String) : Expression() {
|
class BinaryExpression(val left: Expression, val right: Expression, val op: String) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = operandToKotlin(left, commentsAndSpaces, false) + " " + op + " " + operandToKotlin(right, commentsAndSpaces, true)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.appendOperand(this, left, false).append(" ").append(op).append(" ").appendOperand(this, right, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IsOperator(val expression: Expression, val typeElement: TypeElement) : Expression() {
|
class IsOperator(val expression: Expression, val typeElement: TypeElement) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = operandToKotlin(expression, commentsAndSpaces) + " is " + typeElement.`type`.toNotNullType().toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.appendOperand(this, expression).append(" is ").append(typeElement.`type`.toNotNullType())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeCastExpression(val `type`: Type, val expression: Expression) : Expression() {
|
class TypeCastExpression(val `type`: Type, val expression: Expression) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = operandToKotlin(expression, commentsAndSpaces) + " as " + `type`.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.appendOperand(this, expression).append(" as ").append(`type`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LiteralExpression(val literalText: String) : Expression() {
|
class LiteralExpression(val literalText: String) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = literalText
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(literalText)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParenthesizedExpression(val expression: Expression) : Expression() {
|
class ParenthesizedExpression(val expression: Expression) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "(" + expression.toKotlin(commentsAndSpaces) + ")"
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "(" append expression append ")"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrefixOperator(val op: String, val expression: Expression) : Expression() {
|
class PrefixOperator(val op: String, val expression: Expression) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = op + operandToKotlin(expression, commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder){
|
||||||
|
builder.append(op).appendOperand(this, expression)
|
||||||
|
}
|
||||||
|
|
||||||
override val isNullable: Boolean
|
override val isNullable: Boolean
|
||||||
get() = expression.isNullable
|
get() = expression.isNullable
|
||||||
}
|
}
|
||||||
|
|
||||||
class PostfixOperator(val op: String, val expression: Expression) : Expression() {
|
class PostfixOperator(val op: String, val expression: Expression) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = operandToKotlin(expression, commentsAndSpaces) + op
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.appendOperand(this, expression) append op
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ThisExpression(val identifier: Identifier) : Expression() {
|
class ThisExpression(val identifier: Identifier) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "this" + identifier.withPrefix("@", commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("this").appendWithPrefix(identifier, "@")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SuperExpression(val identifier: Identifier) : Expression() {
|
class SuperExpression(val identifier: Identifier) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "super" + identifier.withPrefix("@", commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("super").appendWithPrefix(identifier, "@")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class QualifiedExpression(val qualifier: Expression, val identifier: Expression) : Expression() {
|
class QualifiedExpression(val qualifier: Expression, val identifier: Expression) : Expression() {
|
||||||
override val isNullable: Boolean
|
override val isNullable: Boolean
|
||||||
get() = identifier.isNullable
|
get() = identifier.isNullable
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
if (!qualifier.isEmpty) {
|
if (!qualifier.isEmpty) {
|
||||||
return operandToKotlin(qualifier, commentsAndSpaces) + (if (qualifier.isNullable) "!!." else ".") + identifier.toKotlin(commentsAndSpaces)
|
builder.appendOperand(this, qualifier).append(if (qualifier.isNullable) "!!." else ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
return identifier.toKotlin(commentsAndSpaces)
|
builder.append(identifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PolyadicExpression(val expressions: List<Expression>, val token: String) : Expression() {
|
class PolyadicExpression(val expressions: List<Expression>, val token: String) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
val expressionsWithConversions = expressions.map { it.toKotlin(commentsAndSpaces) }
|
builder.append(expressions, " " + token + " ")
|
||||||
return expressionsWithConversions.makeString(" " + token + " ")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LambdaExpression(val arguments: String?, val block: Block) : Expression() {
|
class LambdaExpression(val arguments: String?, val block: Block) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
val statementsText = block.statements.toKotlin(commentsAndSpaces, "\n").trim()
|
builder append block.lBrace append " "
|
||||||
val innerBody = if (arguments != null) {
|
|
||||||
val br = if (statementsText.indexOf('\n') < 0 && statementsText.indexOf('\r') < 0) " " else "\n"
|
if (arguments != null) {
|
||||||
"$arguments ->$br$statementsText"
|
builder.append(arguments)
|
||||||
|
.append("->")
|
||||||
|
.append(if (block.statements.size > 1) "\n" else " ")
|
||||||
|
.append(block.statements, "\n")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
statementsText
|
builder.append(block.statements, "\n")
|
||||||
}
|
}
|
||||||
return block.lBrace.toKotlin(commentsAndSpaces) + " " + innerBody + " " + block.rBrace.toKotlin(commentsAndSpaces)
|
|
||||||
|
builder append " " append block.rBrace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StarExpression(val methodCall: MethodCallExpression) : Expression() {
|
class StarExpression(val methodCall: MethodCallExpression) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "*" + methodCall.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "*" append methodCall
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createArrayInitializerExpression(arrayType: ArrayType, initializers: List<Expression>, needExplicitType: Boolean) : MethodCallExpression {
|
fun createArrayInitializerExpression(arrayType: ArrayType, initializers: List<Expression>, needExplicitType: Boolean) : MethodCallExpression {
|
||||||
val elementType = arrayType.elementType
|
val elementType = arrayType.elementType
|
||||||
val createArrayFunction = if (elementType is PrimitiveType)
|
val createArrayFunction = if (elementType is PrimitiveType)
|
||||||
(elementType.toNotNullType().toKotlin(CommentsAndSpaces.None) + "Array").decapitalize()
|
(elementType.toNotNullType().canonicalCode() + "Array").decapitalize()
|
||||||
else if (needExplicitType)
|
else if (needExplicitType)
|
||||||
arrayType.toNotNullType().toKotlin(CommentsAndSpaces.None).decapitalize()
|
arrayType.toNotNullType().canonicalCode().decapitalize()
|
||||||
else
|
else
|
||||||
"array"
|
"array"
|
||||||
|
|
||||||
val doubleOrFloatTypes = setOf("double", "float", "java.lang.double", "java.lang.float")
|
val doubleOrFloatTypes = setOf("double", "float", "java.lang.double", "java.lang.float")
|
||||||
val afterReplace = arrayType.toNotNullType().toKotlin(CommentsAndSpaces.None).replace("Array", "").toLowerCase().replace(">", "").replace("<", "").replace("?", "")
|
val afterReplace = arrayType.toNotNullType().canonicalCode().replace("Array", "").toLowerCase().replace(">", "").replace("<", "").replace("?", "")
|
||||||
|
|
||||||
fun explicitConvertIfNeeded(initializer: Expression): Expression {
|
fun explicitConvertIfNeeded(initializer: Expression): Expression {
|
||||||
if (doubleOrFloatTypes.contains(afterReplace)) {
|
if (doubleOrFloatTypes.contains(afterReplace)) {
|
||||||
if (initializer is LiteralExpression) {
|
if (initializer is LiteralExpression) {
|
||||||
if (!initializer.toKotlin(CommentsAndSpaces.None).contains(".")) {
|
if (!initializer.canonicalCode().contains(".")) {
|
||||||
return LiteralExpression(initializer.literalText + ".0")
|
return LiteralExpression(initializer.literalText + ".0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,20 +29,24 @@ open class Field(
|
|||||||
private val hasWriteAccesses: Boolean
|
private val hasWriteAccesses: Boolean
|
||||||
) : Member(annotations, modifiers) {
|
) : Member(annotations, modifiers) {
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
val declaration = annotations.toKotlin(commentsAndSpaces) +
|
builder.append(annotations)
|
||||||
modifiersToKotlin() +
|
.appendModifiers()
|
||||||
(if (isVal) "val " else "var ") +
|
.append(if (isVal) "val " else "var ")
|
||||||
identifier.toKotlin(commentsAndSpaces) +
|
.append(identifier)
|
||||||
" : " +
|
.append(" : ")
|
||||||
`type`.toKotlin(commentsAndSpaces)
|
.append(`type`)
|
||||||
return if (initializer.isEmpty)
|
|
||||||
declaration + (if (isVal && hasWriteAccesses) "" else " = " + getDefaultInitializer(this).toKotlin(commentsAndSpaces))
|
var initializerToUse = initializer
|
||||||
else
|
if (initializerToUse.isEmpty && !(isVal && hasWriteAccesses)) {
|
||||||
declaration + " = " + initializer.toKotlin(commentsAndSpaces)
|
initializerToUse = getDefaultInitializer(this)
|
||||||
|
}
|
||||||
|
if (!initializerToUse.isEmpty) {
|
||||||
|
builder append "=" append initializerToUse
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun modifiersToKotlin(): String {
|
private fun CodeBuilder.appendModifiers(): CodeBuilder {
|
||||||
val modifierList = ArrayList<Modifier>()
|
val modifierList = ArrayList<Modifier>()
|
||||||
if (modifiers.contains(Modifier.ABSTRACT)) {
|
if (modifiers.contains(Modifier.ABSTRACT)) {
|
||||||
modifierList.add(Modifier.ABSTRACT)
|
modifierList.add(Modifier.ABSTRACT)
|
||||||
@@ -50,6 +54,6 @@ open class Field(
|
|||||||
|
|
||||||
modifiers.accessModifier()?.let { modifierList.add(it) }
|
modifiers.accessModifier()?.let { modifierList.add(it) }
|
||||||
|
|
||||||
return modifierList.toKotlin()
|
return append(modifierList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.CodeBuilder
|
||||||
|
import org.jetbrains.jet.j2k.append
|
||||||
|
|
||||||
class PackageStatement(val packageName: String) : Element() {
|
class PackageStatement(val packageName: String) : Element() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = "package " + packageName
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "package " append packageName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class File(
|
class File(
|
||||||
@@ -27,7 +30,7 @@ class File(
|
|||||||
val mainFunction: String
|
val mainFunction: String
|
||||||
) : Element() {
|
) : Element() {
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
return elements.toKotlin(commentsAndSpaces, "\n") + mainFunction
|
builder.append(elements, "\n").append(mainFunction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,7 @@
|
|||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.jetbrains.jet.j2k.Converter
|
import org.jetbrains.jet.j2k.*
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
|
||||||
|
|
||||||
open class Function(
|
open class Function(
|
||||||
val converter: Converter,
|
val converter: Converter,
|
||||||
@@ -32,7 +31,7 @@ open class Function(
|
|||||||
val isInTrait: Boolean
|
val isInTrait: Boolean
|
||||||
) : Member(annotations, modifiers) {
|
) : Member(annotations, modifiers) {
|
||||||
|
|
||||||
private fun modifiersToKotlin(): String {
|
private fun CodeBuilder.appendModifiers(): CodeBuilder {
|
||||||
val resultingModifiers = ArrayList<Modifier>()
|
val resultingModifiers = ArrayList<Modifier>()
|
||||||
val isOverride = modifiers.contains(Modifier.OVERRIDE)
|
val isOverride = modifiers.contains(Modifier.OVERRIDE)
|
||||||
if (isOverride) {
|
if (isOverride) {
|
||||||
@@ -52,16 +51,27 @@ open class Function(
|
|||||||
resultingModifiers.add(Modifier.OPEN)
|
resultingModifiers.add(Modifier.OPEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultingModifiers.toKotlin()
|
return append(resultingModifiers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
return annotations.toKotlin(commentsAndSpaces) +
|
builder.append(annotations)
|
||||||
modifiersToKotlin() +
|
.appendModifiers()
|
||||||
"fun ${typeParameterList.toKotlin(commentsAndSpaces).withSuffix(" ")}${name.toKotlin(commentsAndSpaces)}" +
|
.append(" fun ")
|
||||||
"(${parameterList.toKotlin(commentsAndSpaces)})" +
|
.appendWithSuffix(typeParameterList, " ")
|
||||||
(if (!`type`.isUnit()) " : " + `type`.toKotlin(commentsAndSpaces) + " " else " ") +
|
.append(name)
|
||||||
typeParameterList.whereToKotlin(commentsAndSpaces) +
|
.append("(")
|
||||||
block?.toKotlin(commentsAndSpaces)
|
.append(parameterList)
|
||||||
|
.append(")")
|
||||||
|
|
||||||
|
if (!`type`.isUnit()) {
|
||||||
|
builder append ":" append `type`
|
||||||
|
}
|
||||||
|
|
||||||
|
typeParameterList.appendWhere(builder)
|
||||||
|
|
||||||
|
if (block != null) {
|
||||||
|
builder append " " append block!!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.CodeBuilder
|
||||||
import com.intellij.psi.PsiNameIdentifierOwner
|
import com.intellij.psi.PsiNameIdentifierOwner
|
||||||
|
|
||||||
fun PsiNameIdentifierOwner.declarationIdentifier(): Identifier {
|
fun PsiNameIdentifierOwner.declarationIdentifier(): Identifier {
|
||||||
@@ -41,7 +41,9 @@ class Identifier(
|
|||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = toKotlin()
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(toKotlin())
|
||||||
|
}
|
||||||
|
|
||||||
private fun quote(str: String): String = "`" + str + "`"
|
private fun quote(str: String): String = "`" + str + "`"
|
||||||
|
|
||||||
|
|||||||
@@ -25,14 +25,18 @@ import com.intellij.psi.PsiJavaCodeReferenceElement
|
|||||||
import org.jetbrains.jet.asJava.KotlinLightClassForPackage
|
import org.jetbrains.jet.asJava.KotlinLightClassForPackage
|
||||||
|
|
||||||
class Import(val name: String) : Element() {
|
class Import(val name: String) : Element() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "import " + name
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "import " append name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ImportList(public val imports: List<Import>) : Element() {
|
class ImportList(public val imports: List<Import>) : Element() {
|
||||||
override val isEmpty: Boolean
|
override val isEmpty: Boolean
|
||||||
get() = imports.isEmpty()
|
get() = imports.isEmpty()
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = imports.toKotlin(commentsAndSpaces, "\n")
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(imports, "\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Converter.convertImportList(importList: PsiImportList): ImportList =
|
public fun Converter.convertImportList(importList: PsiImportList): ImportList =
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class Initializer(val block: Block, modifiers: Set<Modifier>) : Member(Annotations.Empty, modifiers) {
|
class Initializer(val block: Block, modifiers: Set<Modifier>) : Member(Annotations.Empty, modifiers) {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
return block.toKotlin(commentsAndSpaces)
|
builder.append(block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.ConverterSettings
|
import org.jetbrains.jet.j2k.ConverterSettings
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.CodeBuilder
|
||||||
|
import org.jetbrains.jet.j2k.append
|
||||||
|
|
||||||
class LocalVariable(
|
class LocalVariable(
|
||||||
private val identifier: Identifier,
|
private val identifier: Identifier,
|
||||||
@@ -29,17 +30,17 @@ class LocalVariable(
|
|||||||
private val settings: ConverterSettings
|
private val settings: ConverterSettings
|
||||||
) : Element() {
|
) : Element() {
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
val start = annotations.toKotlin(commentsAndSpaces) + if (isVal) "val" else "var"
|
builder.append(annotations).append(if (isVal) "val " else "var ")
|
||||||
return if (initializer.isEmpty) {
|
if (initializer.isEmpty) {
|
||||||
"$start ${identifier.toKotlin(commentsAndSpaces)} : ${typeCalculator().toKotlin(commentsAndSpaces)}"
|
builder append identifier append ":" append typeCalculator()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val shouldSpecifyType = settings.specifyLocalVariableTypeByDefault
|
val shouldSpecifyType = settings.specifyLocalVariableTypeByDefault
|
||||||
if (shouldSpecifyType)
|
if (shouldSpecifyType)
|
||||||
"$start ${identifier.toKotlin(commentsAndSpaces)} : ${typeCalculator().toKotlin(commentsAndSpaces)} = ${initializer.toKotlin(commentsAndSpaces)}"
|
builder append identifier append ":" append typeCalculator() append "=" append initializer
|
||||||
else
|
else
|
||||||
"$start ${identifier.toKotlin(commentsAndSpaces)} = ${initializer.toKotlin(commentsAndSpaces)}"
|
builder append identifier append "=" append initializer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class MethodCallExpression(
|
class MethodCallExpression(
|
||||||
val methodExpression: Expression,
|
val methodExpression: Expression,
|
||||||
@@ -26,17 +26,14 @@ class MethodCallExpression(
|
|||||||
val lambdaArgument: LambdaExpression? = null
|
val lambdaArgument: LambdaExpression? = null
|
||||||
) : Expression() {
|
) : Expression() {
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
val builder = StringBuilder()
|
builder.appendOperand(this, methodExpression).append(typeArguments, ", ", "<", ">")
|
||||||
builder.append(operandToKotlin(methodExpression, commentsAndSpaces))
|
|
||||||
builder.append(typeArguments.toKotlin(commentsAndSpaces, ", ", "<", ">"))
|
|
||||||
if (arguments.isNotEmpty() || lambdaArgument == null) {
|
if (arguments.isNotEmpty() || lambdaArgument == null) {
|
||||||
builder.append("(").append(arguments.map { it.toKotlin(commentsAndSpaces) }.makeString(", ")).append(")")
|
builder.append("(").append(arguments, ", ").append(")")
|
||||||
}
|
}
|
||||||
if (lambdaArgument != null) {
|
if (lambdaArgument != null) {
|
||||||
builder.append(lambdaArgument.toKotlin(commentsAndSpaces))
|
builder.append(lambdaArgument)
|
||||||
}
|
}
|
||||||
return builder.toString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class object {
|
class object {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.CodeBuilder
|
||||||
|
|
||||||
enum class Modifier(val name: String) {
|
enum class Modifier(val name: String) {
|
||||||
PUBLIC: Modifier("public")
|
PUBLIC: Modifier("public")
|
||||||
@@ -36,7 +36,13 @@ fun Collection<Modifier>.accessModifier(): Modifier? {
|
|||||||
return firstOrNull { ACCESS_MODIFIERS.contains(it) }
|
return firstOrNull { ACCESS_MODIFIERS.contains(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Collection<Modifier>.toKotlin(): String
|
fun CodeBuilder.append(modifiers: List<Modifier>): CodeBuilder {
|
||||||
= if (isNotEmpty()) map { it.toKotlin() }.makeString(" ") + " " else ""
|
if (!modifiers.isEmpty()) {
|
||||||
|
for (modifier in modifiers) {
|
||||||
|
append(modifier.toKotlin()).append(" ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class NewClassExpression(
|
class NewClassExpression(
|
||||||
val name: Element,
|
val name: Element,
|
||||||
@@ -25,18 +25,23 @@ class NewClassExpression(
|
|||||||
val anonymousClass: AnonymousClassBody? = null
|
val anonymousClass: AnonymousClassBody? = null
|
||||||
) : Expression() {
|
) : Expression() {
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
val callOperator = if (qualifier.isNullable) "!!." else "."
|
if (anonymousClass != null) {
|
||||||
val qualifier = if (qualifier.isEmpty) "" else qualifier.toKotlin(commentsAndSpaces) + callOperator
|
builder.append("object:")
|
||||||
val appliedArguments = arguments.toKotlin(commentsAndSpaces, ", ")
|
|
||||||
return if (anonymousClass != null) {
|
|
||||||
if (anonymousClass.extendsTrait)
|
|
||||||
"object : " + qualifier + name.toKotlin(commentsAndSpaces) + anonymousClass.toKotlin(commentsAndSpaces)
|
|
||||||
else
|
|
||||||
"object : " + qualifier + name.toKotlin(commentsAndSpaces) + "(" + appliedArguments + ")" + anonymousClass.toKotlin(commentsAndSpaces)
|
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
qualifier + name.toKotlin(commentsAndSpaces) + "(" + appliedArguments + ")"
|
if (!qualifier.isEmpty) {
|
||||||
|
builder.append(qualifier).append(if (qualifier.isNullable) "!!." else ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(name)
|
||||||
|
|
||||||
|
if (anonymousClass == null || !anonymousClass.extendsTrait) {
|
||||||
|
builder.append("(").append(arguments, ", ").append(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anonymousClass != null) {
|
||||||
|
builder.append(anonymousClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,24 +16,21 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class Parameter(val identifier: Identifier,
|
class Parameter(val identifier: Identifier,
|
||||||
val `type`: Type,
|
val `type`: Type,
|
||||||
val varVal: Parameter.VarValModifier,
|
val varVal: Parameter.VarValModifier,
|
||||||
val annotations: Annotations,
|
val annotations: Annotations,
|
||||||
val modifiers: Collection<Modifier>) : Element() {
|
val modifiers: List<Modifier>) : Element() {
|
||||||
public enum class VarValModifier {
|
public enum class VarValModifier {
|
||||||
None
|
None
|
||||||
Val
|
Val
|
||||||
Var
|
Var
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
val builder = StringBuilder()
|
builder.append(annotations).append(modifiers)
|
||||||
|
|
||||||
builder.append(annotations.toKotlin(commentsAndSpaces))
|
|
||||||
builder.append(modifiers.toKotlin())
|
|
||||||
|
|
||||||
if (`type` is VarArgType) {
|
if (`type` is VarArgType) {
|
||||||
assert(varVal == VarValModifier.None)
|
assert(varVal == VarValModifier.None)
|
||||||
@@ -45,7 +42,6 @@ class Parameter(val identifier: Identifier,
|
|||||||
VarValModifier.Val -> builder.append("val ")
|
VarValModifier.Val -> builder.append("val ")
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append(identifier.toKotlin(commentsAndSpaces)).append(": ").append(`type`.toKotlin(commentsAndSpaces))
|
builder.append(identifier).append(":").append(`type`)
|
||||||
return builder.toString()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class ParameterList(val parameters: List<Parameter>) : Element() {
|
class ParameterList(val parameters: List<Parameter>) : Element() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = parameters.map { it.toKotlin(commentsAndSpaces) }.makeString(", ")
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(parameters, ", ")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class ReferenceElement(val reference: Identifier, val types: List<Type>) : Element() {
|
class ReferenceElement(val reference: Identifier, val types: List<Type>) : Element() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = reference.toKotlin(commentsAndSpaces) + types.toKotlin(commentsAndSpaces, ", ", "<", ">")
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(reference).append(types, ", ", "<", ">")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
|
|
||||||
abstract class Statement() : Element() {
|
abstract class Statement() : Element() {
|
||||||
object Empty : Statement() {
|
object Empty : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = ""
|
override fun generateCode(builder: CodeBuilder) { }
|
||||||
|
|
||||||
override val isEmpty: Boolean
|
override val isEmpty: Boolean
|
||||||
get() = true
|
get() = true
|
||||||
@@ -29,20 +29,27 @@ abstract class Statement() : Element() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DeclarationStatement(val elements: List<Element>) : Statement() {
|
class DeclarationStatement(val elements: List<Element>) : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
= elements.filterIsInstance(javaClass<LocalVariable>()).map { it.toKotlin(commentsAndSpaces) }.makeString("\n")
|
builder.append(elements, "\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExpressionListStatement(val expressions: List<Expression>) : Expression() {
|
class ExpressionListStatement(val expressions: List<Expression>) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = expressions.toKotlin(commentsAndSpaces, "\n")
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(expressions, "\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LabelStatement(val name: Identifier, val statement: Element) : Statement() {
|
class LabelStatement(val name: Identifier, val statement: Element) : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = "@" + name.toKotlin(commentsAndSpaces) + " " + statement.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "@" append name append " " append statement
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReturnStatement(val expression: Expression) : Statement() {
|
class ReturnStatement(val expression: Expression) : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "return " + expression.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "return " append expression
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IfStatement(
|
class IfStatement(
|
||||||
@@ -53,12 +60,11 @@ class IfStatement(
|
|||||||
) : Expression() {
|
) : Expression() {
|
||||||
private val br = if (singleLine) " " else "\n"
|
private val br = if (singleLine) " " else "\n"
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
val result = "if (" + condition.toKotlin(commentsAndSpaces) + ")$br" + thenStatement.toKotlin(commentsAndSpaces)
|
builder append "if (" append condition append ")" append br append thenStatement
|
||||||
if (!elseStatement.isEmpty) {
|
if (!elseStatement.isEmpty) {
|
||||||
return "$result${br}else$br${elseStatement.toKotlin(commentsAndSpaces)}"
|
builder append br append "else" append br append elseStatement
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,13 +73,17 @@ class IfStatement(
|
|||||||
class WhileStatement(val condition: Expression, val body: Element, singleLine: Boolean) : Statement() {
|
class WhileStatement(val condition: Expression, val body: Element, singleLine: Boolean) : Statement() {
|
||||||
private val br = if (singleLine) " " else "\n"
|
private val br = if (singleLine) " " else "\n"
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "while (" + condition.toKotlin(commentsAndSpaces) + ")$br" + body.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "while (" append condition append ")" append br append body
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DoWhileStatement(val condition: Expression, val body: Element, singleLine: Boolean) : Statement() {
|
class DoWhileStatement(val condition: Expression, val body: Element, singleLine: Boolean) : Statement() {
|
||||||
private val br = if (singleLine) " " else "\n"
|
private val br = if (singleLine) " " else "\n"
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "do$br" + body.toKotlin(commentsAndSpaces) + "${br}while (" + condition.toKotlin(commentsAndSpaces) + ")"
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "do" append br append body append br append "while (" append condition append ")"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ForeachStatement(
|
class ForeachStatement(
|
||||||
@@ -85,7 +95,9 @@ class ForeachStatement(
|
|||||||
|
|
||||||
private val br = if (singleLine) " " else "\n"
|
private val br = if (singleLine) " " else "\n"
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "for (" + variable.identifier.toKotlin(commentsAndSpaces) + " in " + expression.toKotlin(commentsAndSpaces) + ")$br" + body.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "for (" append variable.identifier append " in " append expression append ")" append br append body
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ForeachWithRangeStatement(val identifier: Identifier,
|
class ForeachWithRangeStatement(val identifier: Identifier,
|
||||||
@@ -95,64 +107,78 @@ class ForeachWithRangeStatement(val identifier: Identifier,
|
|||||||
singleLine: Boolean) : Statement() {
|
singleLine: Boolean) : Statement() {
|
||||||
private val br = if (singleLine) " " else "\n"
|
private val br = if (singleLine) " " else "\n"
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "for (" + identifier.toKotlin(commentsAndSpaces) + " in " + start.toKotlin(commentsAndSpaces) + ".." + end.toKotlin(commentsAndSpaces) + ")$br" + body.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "for (" append identifier append " in " append start append ".." append end append ")" append br append body
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BreakStatement(val label: Identifier = Identifier.Empty) : Statement() {
|
class BreakStatement(val label: Identifier = Identifier.Empty) : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "break" + label.withPrefix("@", commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("break").appendWithPrefix(label, "@")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContinueStatement(val label: Identifier = Identifier.Empty) : Statement() {
|
class ContinueStatement(val label: Identifier = Identifier.Empty) : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "continue" + label.withPrefix("@", commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("continue").appendWithPrefix(label, "@")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exceptions ----------------------------------------------------------------------------------------------
|
// Exceptions ----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class TryStatement(val block: Block, val catches: List<CatchStatement>, val finallyBlock: Block) : Statement() {
|
class TryStatement(val block: Block, val catches: List<CatchStatement>, val finallyBlock: Block) : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
val builder = StringBuilder()
|
builder.append("try\n").append(block).append("\n").append(catches, "\n").append("\n")
|
||||||
.append("try\n")
|
|
||||||
.append(block.toKotlin(commentsAndSpaces))
|
|
||||||
.append("\n")
|
|
||||||
.append(catches.toKotlin(commentsAndSpaces, "\n"))
|
|
||||||
.append("\n")
|
|
||||||
if (!finallyBlock.isEmpty) {
|
if (!finallyBlock.isEmpty) {
|
||||||
builder.append("finally\n").append(finallyBlock.toKotlin(commentsAndSpaces))
|
builder append "finally\n" append finallyBlock
|
||||||
}
|
}
|
||||||
return builder.toString()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ThrowStatement(val expression: Expression) : Expression() {
|
class ThrowStatement(val expression: Expression) : Expression() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "throw " + expression.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "throw " append expression
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CatchStatement(val variable: Parameter, val block: Block) : Statement() {
|
class CatchStatement(val variable: Parameter, val block: Block) : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = "catch (" + variable.toKotlin(commentsAndSpaces) + ") " + block.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "catch (" append variable append ") " append block
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch --------------------------------------------------------------------------------------------------
|
// Switch --------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class SwitchContainer(val expression: Expression, val caseContainers: List<CaseContainer>) : Statement() {
|
class SwitchContainer(val expression: Expression, val caseContainers: List<CaseContainer>) : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "when (" + expression.toKotlin(commentsAndSpaces) + ") {\n" + caseContainers.toKotlin(commentsAndSpaces, "\n") + "\n}"
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("when (").append(expression).append(") {\n").append(caseContainers, "\n").append("\n}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CaseContainer(val caseStatement: List<Element>, statements: List<Statement>) : Statement() {
|
class CaseContainer(val caseStatement: List<Element>, statements: List<Statement>) : Statement() {
|
||||||
private val block = Block(statements.filterNot { it is BreakStatement || it is ContinueStatement }, LBrace(), RBrace(), true)
|
private val block = Block(statements.filterNot { it is BreakStatement || it is ContinueStatement }, LBrace(), RBrace(), true)
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = caseStatement.toKotlin(commentsAndSpaces, ", ") + " -> " + block.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(caseStatement, ", ").append(" -> ").append(block)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SwitchLabelStatement(val expression: Expression) : Statement() {
|
class SwitchLabelStatement(val expression: Expression) : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = expression.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(expression)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultSwitchLabelStatement() : Statement() {
|
class DefaultSwitchLabelStatement() : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "else"
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("else")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other ------------------------------------------------------------------------------------------------------
|
// Other ------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class SynchronizedStatement(val expression: Expression, val block: Block) : Statement() {
|
class SynchronizedStatement(val expression: Expression, val block: Block) : Statement() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "synchronized (" + expression.toKotlin(commentsAndSpaces) + ") " + block.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "synchronized (" append expression append ") " append block
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.CodeBuilder
|
||||||
|
|
||||||
class Trait(name: Identifier,
|
class Trait(name: Identifier,
|
||||||
annotations: Annotations,
|
annotations: Annotations,
|
||||||
@@ -32,12 +32,12 @@ class Trait(name: Identifier,
|
|||||||
override val keyword: String
|
override val keyword: String
|
||||||
get() = "trait"
|
get() = "trait"
|
||||||
|
|
||||||
override fun primaryConstructorSignatureToKotlin(commentsAndSpaces: CommentsAndSpaces) = ""
|
override fun appendPrimaryConstructorSignature(builder: CodeBuilder) { }
|
||||||
|
|
||||||
override fun modifiersToKotlin(): String {
|
override fun appendModifiers(builder: CodeBuilder): CodeBuilder {
|
||||||
val modifierList = ArrayList<Modifier>()
|
val modifierList = ArrayList<Modifier>()
|
||||||
modifiers.accessModifier()?.let { modifierList.add(it) }
|
modifiers.accessModifier()?.let { modifierList.add(it) }
|
||||||
return modifierList.toKotlin()
|
return builder.append(modifierList)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
class TypeElement(val `type`: Type) : Element() {
|
class TypeElement(val `type`: Type) : Element() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = `type`.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(`type`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,45 +17,37 @@
|
|||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import com.intellij.psi.PsiTypeParameter
|
import com.intellij.psi.PsiTypeParameter
|
||||||
import org.jetbrains.jet.j2k.Converter
|
import org.jetbrains.jet.j2k.*
|
||||||
import com.intellij.psi.PsiTypeParameterList
|
import com.intellij.psi.PsiTypeParameterList
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
|
||||||
|
|
||||||
class TypeParameter(val name: Identifier, val extendsTypes: List<Type>) : Element() {
|
class TypeParameter(val name: Identifier, val extendsTypes: List<Type>) : Element() {
|
||||||
fun hasWhere(): Boolean = extendsTypes.size() > 1
|
fun hasWhere(): Boolean = extendsTypes.size() > 1
|
||||||
|
|
||||||
fun whereToKotlin(commentsAndSpaces: CommentsAndSpaces): String {
|
fun whereToKotlin(builder: CodeBuilder) {
|
||||||
if (hasWhere()) {
|
if (hasWhere()) {
|
||||||
return name.toKotlin(commentsAndSpaces) + " : " + extendsTypes[1].toKotlin(commentsAndSpaces)
|
builder append name append " : " append extendsTypes[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
if (extendsTypes.size() > 0) {
|
builder append name
|
||||||
return name.toKotlin(commentsAndSpaces) + " : " + extendsTypes[0].toKotlin(commentsAndSpaces)
|
if (extendsTypes.isNotEmpty()) {
|
||||||
|
builder append " : " append extendsTypes[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
return name.toKotlin(commentsAndSpaces)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeParameterList(val parameters: List<TypeParameter>) : Element() {
|
class TypeParameterList(val parameters: List<TypeParameter>) : Element() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
return if (parameters.isNotEmpty())
|
if (parameters.isNotEmpty()) builder.append(parameters, ", ", "<", ">")
|
||||||
parameters.map { it.toKotlin(commentsAndSpaces) }.makeString(", ", "<", ">")
|
|
||||||
else
|
|
||||||
""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun whereToKotlin(commentsAndSpaces: CommentsAndSpaces): String {
|
fun appendWhere(builder: CodeBuilder): CodeBuilder {
|
||||||
if (hasWhere()) {
|
if (hasWhere()) {
|
||||||
val wheres = parameters.map { it.whereToKotlin(commentsAndSpaces) }
|
builder.append( parameters.map { { it.whereToKotlin(builder) } }, ", ", " where ", "")
|
||||||
return "where " + wheres.makeString(", ")
|
|
||||||
}
|
}
|
||||||
return ""
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.ConverterSettings
|
import org.jetbrains.jet.j2k.*
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
|
||||||
|
|
||||||
fun Type.isUnit(): Boolean = this == Type.Unit
|
fun Type.isUnit(): Boolean = this == Type.Unit
|
||||||
|
|
||||||
@@ -59,42 +58,45 @@ abstract class Type() : Element() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object Empty : NotNullType() {
|
object Empty : NotNullType() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = "UNRESOLVED_TYPE"
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("UNRESOLVED_TYPE")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object Unit: NotNullType() {
|
object Unit: NotNullType() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces) = "Unit"
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("Unit")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean = other is Type && other.toKotlin(CommentsAndSpaces.None) == this.toKotlin(CommentsAndSpaces.None)
|
override fun equals(other: Any?): Boolean = other is Type && other.canonicalCode() == this.canonicalCode()
|
||||||
|
|
||||||
override fun hashCode(): Int = toKotlin(CommentsAndSpaces.None).hashCode()
|
override fun hashCode(): Int = canonicalCode().hashCode()
|
||||||
|
|
||||||
override fun toString(): String = toKotlin(CommentsAndSpaces.None)
|
override fun toString(): String = canonicalCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClassType(val `type`: Identifier, val typeArgs: List<Element>, nullability: Nullability, settings: ConverterSettings)
|
class ClassType(val name: Identifier, val typeArgs: List<Element>, nullability: Nullability, settings: ConverterSettings)
|
||||||
: MayBeNullableType(nullability, settings) {
|
: MayBeNullableType(nullability, settings) {
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
var params = if (typeArgs.isEmpty()) "" else typeArgs.map { it.toKotlin(commentsAndSpaces) }.makeString(", ", "<", ">")
|
builder.append(name).append(typeArgs, ", ", "<", ">").append(isNullableStr)
|
||||||
return `type`.toKotlin(commentsAndSpaces) + params + isNullableStr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toNotNullType(): Type = ClassType(name, typeArgs, Nullability.NotNull, settings)
|
||||||
override fun toNotNullType(): Type = ClassType(`type`, typeArgs, Nullability.NotNull, settings)
|
override fun toNullableType(): Type = ClassType(name, typeArgs, Nullability.Nullable, settings)
|
||||||
override fun toNullableType(): Type = ClassType(`type`, typeArgs, Nullability.Nullable, settings)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArrayType(val elementType: Type, nullability: Nullability, settings: ConverterSettings)
|
class ArrayType(val elementType: Type, nullability: Nullability, settings: ConverterSettings)
|
||||||
: MayBeNullableType(nullability, settings) {
|
: MayBeNullableType(nullability, settings) {
|
||||||
|
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
if (elementType is PrimitiveType) {
|
if (elementType is PrimitiveType) {
|
||||||
return elementType.toKotlin(commentsAndSpaces) + "Array" + isNullableStr
|
builder append elementType append "Array" append isNullableStr
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder append "Array<" append elementType append ">" append isNullableStr
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Array<" + elementType.toKotlin(commentsAndSpaces) + ">" + isNullableStr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toNotNullType(): Type = ArrayType(elementType, Nullability.NotNull, settings)
|
override fun toNotNullType(): Type = ArrayType(elementType, Nullability.NotNull, settings)
|
||||||
@@ -102,21 +104,31 @@ class ArrayType(val elementType: Type, nullability: Nullability, settings: Conve
|
|||||||
}
|
}
|
||||||
|
|
||||||
class InProjectionType(val bound: Type) : NotNullType() {
|
class InProjectionType(val bound: Type) : NotNullType() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = "in " + bound.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "in " append bound
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OutProjectionType(val bound: Type) : NotNullType() {
|
class OutProjectionType(val bound: Type) : NotNullType() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = "out " + bound.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder append "out " append bound
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StarProjectionType() : NotNullType() {
|
class StarProjectionType() : NotNullType() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = "*"
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append("*")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrimitiveType(val `type`: Identifier) : NotNullType() {
|
class PrimitiveType(val name: Identifier) : NotNullType() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = `type`.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class VarArgType(val `type`: Type) : NotNullType() {
|
class VarArgType(val `type`: Type) : NotNullType() {
|
||||||
override fun toKotlinImpl(commentsAndSpaces: CommentsAndSpaces): String = `type`.toKotlin(commentsAndSpaces)
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
|
builder.append(`type`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,23 +16,23 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k.ast
|
package org.jetbrains.jet.j2k.ast
|
||||||
|
|
||||||
import org.jetbrains.jet.j2k.CommentsAndSpaces
|
import org.jetbrains.jet.j2k.*
|
||||||
|
|
||||||
fun List<Element>.toKotlin(commentsAndSpaces: CommentsAndSpaces, separator: String, prefix: String = "", postfix: String = ""): String {
|
|
||||||
val texts = map { it.toKotlin(commentsAndSpaces) }.filter { it.isNotEmpty() }
|
|
||||||
return if (texts.isNotEmpty()) texts.makeString(separator, prefix, postfix) else ""
|
|
||||||
}
|
|
||||||
|
|
||||||
fun String.withSuffix(suffix: String): String = if (isEmpty()) "" else this + suffix
|
fun String.withSuffix(suffix: String): String = if (isEmpty()) "" else this + suffix
|
||||||
fun String.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + this
|
fun String.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + this
|
||||||
fun Expression.withPrefix(prefix: String, commentsAndSpaces: CommentsAndSpaces): String = if (isEmpty) "" else prefix + toKotlin(commentsAndSpaces)
|
|
||||||
|
|
||||||
fun Expression.operandToKotlin(operand: Expression, commentsAndSpaces: CommentsAndSpaces, parenthesisForSamePrecedence: Boolean = false): String {
|
fun CodeBuilder.appendWithPrefix(element: Element, prefix: String): CodeBuilder = if (!element.isEmpty) this append prefix append element else this
|
||||||
val parentPrecedence = precedence() ?: throw IllegalArgumentException("Unknown precendence for $this")
|
fun CodeBuilder.appendWithSuffix(element: Element, suffix: String): CodeBuilder = if (!element.isEmpty) this append element append suffix else this
|
||||||
val kotlinCode = operand.toKotlin(commentsAndSpaces)
|
|
||||||
val operandPrecedence = operand.precedence() ?: return kotlinCode
|
fun CodeBuilder.appendOperand(expression: Expression, operand: Expression, parenthesisForSamePrecedence: Boolean = false): CodeBuilder {
|
||||||
val needParenthesis = parentPrecedence < operandPrecedence || parentPrecedence == operandPrecedence && parenthesisForSamePrecedence
|
val parentPrecedence = expression.precedence() ?: throw IllegalArgumentException("Unknown precendence for $this")
|
||||||
return if (needParenthesis) "($kotlinCode)" else kotlinCode
|
val operandPrecedence = operand.precedence()
|
||||||
|
val needParenthesis = operandPrecedence != null &&
|
||||||
|
(parentPrecedence < operandPrecedence || parentPrecedence == operandPrecedence && parenthesisForSamePrecedence)
|
||||||
|
if (needParenthesis) append("(")
|
||||||
|
append(operand)
|
||||||
|
if (needParenthesis) append(")")
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Expression.precedence(): Int? {
|
private fun Expression.precedence(): Int? {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class TypeVisitor(private val converter: TypeConverter, private val classesToImp
|
|||||||
if (classType.getParameterCount() == 0 && resolvedClassTypeParams.size() > 0) {
|
if (classType.getParameterCount() == 0 && resolvedClassTypeParams.size() > 0) {
|
||||||
val starParamList = ArrayList<Type>()
|
val starParamList = ArrayList<Type>()
|
||||||
if (resolvedClassTypeParams.size() == 1) {
|
if (resolvedClassTypeParams.size() == 1) {
|
||||||
if ((resolvedClassTypeParams.single() as ClassType).`type`.name == "Any") {
|
if ((resolvedClassTypeParams.single() as ClassType).name.name == "Any") {
|
||||||
starParamList.add(StarProjectionType())
|
starParamList.add(StarProjectionType())
|
||||||
return ClassType(identifier, starParamList, Nullability.Default, converter.settings)
|
return ClassType(identifier, starParamList, Nullability.Default, converter.settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ abstract class AbstractJavaToKotlinConverterTest() : LightIdeaTestCase() {
|
|||||||
|
|
||||||
private fun expressionToKotlin(code: String, settings: ConverterSettings, project: Project): String {
|
private fun expressionToKotlin(code: String, settings: ConverterSettings, project: Project): String {
|
||||||
val result = statementToKotlin("final Object o =" + code + "}", settings, project)
|
val result = statementToKotlin("final Object o =" + code + "}", settings, project)
|
||||||
return result.replaceFirst("val o : Any\\? =", "").replaceFirst("val o : Any = ", "").replaceFirst("val o = ", "").trim()
|
return result.replaceFirst("val o:Any\\?=", "").replaceFirst("val o:Any=", "").replaceFirst("val o=", "").trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getProjectJDK(): Sdk? {
|
override fun getProjectJDK(): Sdk? {
|
||||||
|
|||||||
@@ -737,9 +737,19 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("j2k/tests/testData/ast/comments"), Pattern.compile("^(.+)\\.java$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("j2k/tests/testData/ast/comments"), Pattern.compile("^(.+)\\.java$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("Comments.java")
|
@TestMetadata("comments.java")
|
||||||
public void testComments() throws Exception {
|
public void testComments() throws Exception {
|
||||||
doTest("j2k/tests/testData/ast/comments/Comments.java");
|
doTest("j2k/tests/testData/ast/comments/comments.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("fieldWithEndOfLineComment.java")
|
||||||
|
public void testFieldWithEndOfLineComment() throws Exception {
|
||||||
|
doTest("j2k/tests/testData/ast/comments/fieldWithEndOfLineComment.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("fieldsInitializedFromParams.java")
|
||||||
|
public void testFieldsInitializedFromParams() throws Exception {
|
||||||
|
doTest("j2k/tests/testData/ast/comments/fieldsInitializedFromParams.java");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
//file
|
||||||
|
class A {
|
||||||
|
private boolean isOpen = true; // ideally should be atomic boolean
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class A() {
|
||||||
|
private var isOpen: Boolean = true // ideally should be atomic boolean
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//file
|
||||||
|
class C {
|
||||||
|
private final int p1; // field p1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field myP2
|
||||||
|
*/
|
||||||
|
private final int myP2;
|
||||||
|
|
||||||
|
/* Field p3 */ public int p3;
|
||||||
|
|
||||||
|
public C(int p1 /* parameter p1 */, int p2, int p3) {
|
||||||
|
this.p1 = p1;
|
||||||
|
myP2 = p2;
|
||||||
|
this.p3 = p3;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class C(private val p1: Int /* parameter p1 */ // field p1
|
||||||
|
,
|
||||||
|
/**
|
||||||
|
* Field myP2
|
||||||
|
*/
|
||||||
|
private val myP2: Int, /* Field p3 */ public var p3: Int)
|
||||||
Reference in New Issue
Block a user