Java to Kotlin converter: supported try-with-resource construct, fixed anonymous class generation + fixed a bug with method return type

#KT-4488 Fixed
This commit is contained in:
Valentin Kipyatkov
2014-06-11 13:07:13 +04:00
parent 1b948ef8f1
commit 149ea16f5c
46 changed files with 724 additions and 107 deletions
@@ -52,7 +52,7 @@ public class JavaToKotlinAction extends AnAction {
return;
}
final Converter converter = new Converter(project, ConverterSettings.defaultSettings, new FilesConversionScope(selectedJavaFiles));
final Converter converter = Converter.object$.create(project, ConverterSettings.defaultSettings, new FilesConversionScope(selectedJavaFiles));
CommandProcessor.getInstance().executeCommand(
project,
new Runnable() {
@@ -79,7 +79,7 @@ public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBl
}
private fun convertCopiedCodeToKotlin(code: CopiedCode, file: PsiJavaFile): String {
val converter = Converter(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)))
val converter = Converter.create(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)))
val startOffsets = code.getStartOffsets()
val endOffsets = code.getEndOffsets()
assert(startOffsets.size == endOffsets.size) { "Must have the same size" }
+30 -26
View File
@@ -33,14 +33,28 @@ public class FilesConversionScope(val files: Collection<PsiJavaFile>) : Conversi
override fun contains(element: PsiElement) = files.any { element.getContainingFile() == it }
}
public class Converter(val project: Project, val settings: ConverterSettings, val conversionScope: ConversionScope) {
public class Converter private(val project: Project, val settings: ConverterSettings, val conversionScope: ConversionScope, val state: Converter.State) {
private class State(val typeConverter: TypeConverter,
val methodReturnType: PsiType?,
val expressionVisitorFactory: (Converter) -> ExpressionVisitor,
val statementVisitorFactory: (Converter) -> StatementVisitor)
private val typeConverter = TypeConverter(settings, conversionScope)
val typeConverter: TypeConverter get() = state.typeConverter
val methodReturnType: PsiType? get() = state.methodReturnType
private val dispatcher: Dispatcher = Dispatcher(this, typeConverter)
class object {
public fun create(project: Project, settings: ConverterSettings, conversionScope: ConversionScope): Converter
= Converter(project, settings, conversionScope, State(TypeConverter(settings, conversionScope), null, { ExpressionVisitor(it) }, { StatementVisitor(it) }))
}
public var methodReturnType: PsiType? = null
private set
fun withMethodReturnType(methodReturnType: PsiType?): Converter
= Converter(project, settings, conversionScope, State(typeConverter, methodReturnType, state.expressionVisitorFactory, state.statementVisitorFactory))
fun withExpressionVisitor(factory: (Converter) -> ExpressionVisitor): Converter
= Converter(project, settings, conversionScope, State(typeConverter, state.methodReturnType, factory, state.statementVisitorFactory))
fun withStatementVisitor(factory: (Converter) -> StatementVisitor): Converter
= Converter(project, settings, conversionScope, State(typeConverter, state.methodReturnType, state.expressionVisitorFactory, factory))
public fun elementToKotlin(element: PsiElement): String
= convertTopElement(element)?.toKotlin() ?: ""
@@ -65,8 +79,8 @@ public class Converter(val project: Project, val settings: ConverterSettings, va
return File(fileMembers, createMainFunction(javaFile))
}
public fun convertAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass {
return AnonymousClass(this, convertClassBody(anonymousClass))
public fun convertAnonymousClassBody(anonymousClass: PsiAnonymousClass): AnonymousClassBody {
return AnonymousClassBody(this, convertClassBody(anonymousClass), anonymousClass.getBaseClassType().resolve()?.isInterface() ?: false)
}
private fun convertClassBody(psiClass: PsiClass): List<Element> {
@@ -216,7 +230,10 @@ public class Converter(val project: Project, val settings: ConverterSettings, va
}
private fun convertMethod(method: PsiMethod, membersToRemove: MutableSet<PsiMember>): Function {
methodReturnType = method.getReturnType()
return withMethodReturnType(method.getReturnType()).doConvertMethod(method, membersToRemove)
}
private fun doConvertMethod(method: PsiMethod, membersToRemove: MutableSet<PsiMember>): Function {
val returnType = typeConverter.convertMethodReturnType(method)
val modifiers = convertModifiers(method)
@@ -340,13 +357,8 @@ public class Converter(val project: Project, val settings: ConverterSettings, va
usageReplacementMap.put(parameter, field.getName()!!)
}
}
dispatcher.expressionVisitor = ExpressionVisitor(this, typeConverter, usageReplacementMap)
try {
convertBlock(body, false, { !statementsToRemove.contains(it) })
}
finally {
dispatcher.expressionVisitor = ExpressionVisitor(this, typeConverter, mapOf())
}
withExpressionVisitor { ExpressionVisitor(it, usageReplacementMap) }.convertBlock(body, false, { !statementsToRemove.contains(it) })
}
else {
Block.Empty
@@ -409,7 +421,7 @@ public class Converter(val project: Project, val settings: ConverterSettings, va
public fun convertStatement(statement: PsiStatement?): Statement {
if (statement == null) return Statement.Empty
val statementVisitor: StatementVisitor = StatementVisitor(this)
val statementVisitor = state.statementVisitorFactory(this)
statement.accept(statementVisitor)
return statementVisitor.result
}
@@ -420,7 +432,7 @@ public class Converter(val project: Project, val settings: ConverterSettings, va
public fun convertExpression(expression: PsiExpression?): Expression {
if (expression == null) return Expression.Empty
val expressionVisitor = dispatcher.expressionVisitor
val expressionVisitor = state.expressionVisitorFactory(this)
expression.accept(expressionVisitor)
return expressionVisitor.result
}
@@ -428,19 +440,11 @@ public class Converter(val project: Project, val settings: ConverterSettings, va
public fun convertElement(element: PsiElement?): Element {
if (element == null) return Element.Empty
val elementVisitor = ElementVisitor(this, typeConverter)
val elementVisitor = ElementVisitor(this)
element.accept(elementVisitor)
return elementVisitor.result
}
fun convertElements(elements: Array<out PsiElement?>): List<Element> {
val result = ArrayList<Element>()
for (element in elements) {
result.add(convertElement(element))
}
return result
}
public fun convertTypeElement(element: PsiTypeElement?): TypeElement
= TypeElement(if (element == null) Type.Empty else typeConverter.convertType(element.getType()))
@@ -89,7 +89,7 @@ public object JavaToKotlinTranslator {
fun generateKotlinCode(javaCode: String): String {
val file = createFile(javaCode)
if (file is PsiJavaFile) {
val converter = Converter(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)))
val converter = Converter.create(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)))
return prettify(converter.convertFile(file).toKotlin())
}
return ""
@@ -19,11 +19,11 @@ package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.Converter
import java.util.Collections
class AnonymousClass(converter: Converter, bodyElements: List<Element>)
class AnonymousClassBody(converter: Converter, bodyElements: List<Element>, val extendsTrait: Boolean)
: Class(converter,
Identifier("anonClass"),
Identifier(""),
MemberComments.Empty,
Collections.emptySet<Modifier>(),
setOf(),
TypeParameterList.Empty,
listOf(),
listOf(),
@@ -91,6 +91,19 @@ class PolyadicExpression(val expressions: List<Expression>, val token: String) :
}
}
class LambdaExpression(val arguments: String?, val statementList: StatementList) : Expression() {
override fun toKotlin(): String {
val statementsText = statementList.toKotlin().trim()
if (arguments != null) {
val br = if (statementsText.indexOf('\n') < 0 && statementsText.indexOf('\r') < 0) " " else "\n"
return "{ $arguments ->$br$statementsText }"
}
else {
return "{ $statementsText }"
}
}
}
fun createArrayInitializerExpression(arrayType: ArrayType, initializers: List<Expression>) : MethodCallExpression {
val elementType = arrayType.elementType
val createArrayFunction = if (elementType.isPrimitive()) {
@@ -16,46 +16,54 @@
package org.jetbrains.jet.j2k.ast
import java.util.ArrayList
class MethodCallExpression(
val methodExpression: Expression,
val arguments: List<Expression>,
val typeArguments: List<Type>,
override val isNullable: Boolean
override val isNullable: Boolean,
val lambdaArgument: LambdaExpression? = null
) : Expression() {
override fun toKotlin(): String {
return operandToKotlin(methodExpression) +
typeArguments.toKotlin(", ", "<", ">") +
"(" +
arguments.map { it.toKotlin() }.makeString(", ") +
")"
val builder = StringBuilder()
builder.append(operandToKotlin(methodExpression))
builder.append(typeArguments.toKotlin(", ", "<", ">"))
if (arguments.isNotEmpty() || lambdaArgument == null) {
builder.append("(").append(arguments.map { it.toKotlin() }.makeString(", ")).append(")")
}
if (lambdaArgument != null) {
builder.append(lambdaArgument.toKotlin())
}
return builder.toString()
}
class object {
public fun buildNotNull(receiver: Expression?,
methodName: String,
arguments: List<Expression> = listOf(),
typeArguments: List<Type> = listOf()): MethodCallExpression
= build(receiver, methodName, arguments, typeArguments, false)
methodName: String,
arguments: List<Expression> = listOf(),
typeArguments: List<Type> = listOf(),
lambdaArgument: LambdaExpression? = null): MethodCallExpression
= build(receiver, methodName, arguments, typeArguments, false, lambdaArgument)
public fun buildNullable(receiver: Expression?,
methodName: String,
arguments: List<Expression> = listOf(),
typeArguments: List<Type> = listOf()): MethodCallExpression
= build(receiver, methodName, arguments, typeArguments, true)
methodName: String,
arguments: List<Expression> = listOf(),
typeArguments: List<Type> = listOf(),
lambdaArgument: LambdaExpression? = null): MethodCallExpression
= build(receiver, methodName, arguments, typeArguments, true, lambdaArgument)
public fun build(receiver: Expression?,
methodName: String,
arguments: List<Expression>,
typeArguments: List<Type>,
isNullable: Boolean): MethodCallExpression {
isNullable: Boolean,
lambdaArgument: LambdaExpression? = null): MethodCallExpression {
val identifier = Identifier(methodName, false)
return MethodCallExpression(if (receiver != null) QualifiedExpression(receiver, identifier) else identifier,
arguments,
typeArguments,
isNullable)
isNullable,
lambdaArgument)
}
}
}
@@ -16,20 +16,25 @@
package org.jetbrains.jet.j2k.ast
open class NewClassExpression(
class NewClassExpression(
val name: Element,
val arguments: List<Expression>,
val qualifier: Expression = Expression.Empty,
val anonymousClass: AnonymousClass? = null
val anonymousClass: AnonymousClassBody? = null
) : Expression() {
override fun toKotlin(): String {
val callOperator = if (qualifier.isNullable) "?." else "."
val callOperator = if (qualifier.isNullable) "!!." else "."
val qualifier = if (qualifier.isEmpty) "" else qualifier.toKotlin() + callOperator
val appliedArguments = arguments.toKotlin(", ")
return if (anonymousClass != null)
"object : " + qualifier + name.toKotlin() + "(" + appliedArguments + ")" + anonymousClass.toKotlin()
else
return if (anonymousClass != null) {
if (anonymousClass.extendsTrait)
"object : " + qualifier + name.toKotlin() + anonymousClass.toKotlin()
else
"object : " + qualifier + name.toKotlin() + "(" + appliedArguments + ")" + anonymousClass.toKotlin()
}
else{
qualifier + name.toKotlin() + "(" + appliedArguments + ")"
}
}
}
@@ -1,24 +0,0 @@
/*
* Copyright 2010-2013 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.visitors
import org.jetbrains.jet.j2k.Converter
import org.jetbrains.jet.j2k.TypeConverter
class Dispatcher(converter: Converter, typeConverter: TypeConverter) {
var expressionVisitor: ExpressionVisitor = ExpressionVisitor(converter, typeConverter)
}
@@ -20,7 +20,9 @@ import com.intellij.psi.*
import org.jetbrains.jet.j2k.*
import org.jetbrains.jet.j2k.ast.*
class ElementVisitor(private val converter: Converter, private val typeConverter: TypeConverter) : JavaElementVisitor() {
class ElementVisitor(private val converter: Converter) : JavaElementVisitor() {
private val typeConverter = converter.typeConverter
public var result: Element = Element.Empty
protected set
@@ -36,8 +36,9 @@ import com.intellij.psi.impl.light.LightField
import org.jetbrains.jet.lang.resolve.java.JvmAbi
class ExpressionVisitor(private val converter: Converter,
private val typeConverter: TypeConverter,
private val usageReplacementMap: Map<PsiVariable, String> = mapOf()) : JavaElementVisitor() {
private val typeConverter = converter.typeConverter
public var result: Expression = Expression.Empty
protected set
@@ -263,7 +264,7 @@ class ExpressionVisitor(private val converter: Converter,
return NewClassExpression(converter.convertElement(classReference),
convertArguments(expression),
converter.convertExpression(expression.getQualifier()),
if (anonymousClass != null) converter.convertAnonymousClass(anonymousClass) else null)
if (anonymousClass != null) converter.convertAnonymousClassBody(anonymousClass) else null)
}
override fun visitParenthesizedExpression(expression: PsiParenthesizedExpression) {
@@ -23,10 +23,11 @@ import org.jetbrains.jet.j2k.countWriteAccesses
import java.util.ArrayList
import org.jetbrains.jet.j2k.hasWriteAccesses
import org.jetbrains.jet.j2k.isInSingleLine
import org.jetbrains.jet.j2k.getContainingMethod
class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
open class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
public var result: Statement = Statement.Empty
private set
protected set
override fun visitAssertStatement(statement: PsiAssertStatement) {
result = AssertStatement(converter.convertExpression(statement.getAssertCondition()),
@@ -56,7 +57,7 @@ class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
}
override fun visitDeclarationStatement(statement: PsiDeclarationStatement) {
result = DeclarationStatement(converter.convertElements(statement.getDeclaredElements()))
result = DeclarationStatement(statement.getDeclaredElements().map { converter.convertElement(it) })
}
override fun visitDoWhileStatement(statement: PsiDoWhileStatement) {
@@ -217,16 +218,76 @@ class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
result = ThrowStatement(converter.convertExpression(statement.getException()))
}
override fun visitTryStatement(statement: PsiTryStatement) {
val catches = ArrayList<CatchStatement>()
val catchBlocks = statement.getCatchBlocks()
val catchBlockParameters = statement.getCatchBlockParameters()
for (i in 0..catchBlocks.size - 1) {
catches.add(CatchStatement(converter.convertParameter(catchBlockParameters[i], Nullability.NotNull),
converter.convertBlock(catchBlocks[i])))
override fun visitTryStatement(tryStatement: PsiTryStatement) {
val tryBlock = tryStatement.getTryBlock()
val catchesConverted = run {
val catchBlocks = tryStatement.getCatchBlocks()
val catchBlockParameters = tryStatement.getCatchBlockParameters()
catchBlocks.indices.map {
CatchStatement(converter.convertParameter(catchBlockParameters[it], Nullability.NotNull),
converter.convertBlock(catchBlocks[it]))
}
}
result = TryStatement(converter.convertBlock(statement.getTryBlock()),
catches, converter.convertBlock(statement.getFinallyBlock()))
val finallyConverted = converter.convertBlock(tryStatement.getFinallyBlock())
val resourceList = tryStatement.getResourceList()
if (resourceList != null) {
val variables = resourceList.getResourceVariables()
if (variables.isNotEmpty()) {
var wrapResultStatement: (Expression) -> Statement = { it }
var converterForBody = converter
val returns = collectReturns(tryBlock)
//TODO: support other returns when non-local returns supported by Kotlin
if (returns.size == 1 && returns.single() == tryBlock!!.getStatements().last()) {
wrapResultStatement = { ReturnStatement(it) }
converterForBody = converter.withStatementVisitor { object : StatementVisitor(it) {
override fun visitReturnStatement(statement: PsiReturnStatement) {
if (statement == returns.single()) {
result = converter.convertExpression(statement.getReturnValue(), tryStatement.getContainingMethod()?.getReturnType())
}
else {
super.visitReturnStatement(statement)
}
}
}}
}
var bodyConverted = converterForBody.convertBlock(tryBlock)
var statementList = bodyConverted.statementList
var expression: Expression = Expression.Empty
for (variable in variables.reverse()) {
val lambda = LambdaExpression(Identifier(variable.getName()!!).toKotlin(), statementList)
expression = MethodCallExpression.build(converter.convertExpression(variable.getInitializer()), "use", listOf(), listOf(), false, lambda)
statementList = StatementList(listOf(expression))
}
if (catchesConverted.isEmpty() && finallyConverted.isEmpty) {
result = wrapResultStatement(expression)
return
}
bodyConverted = Block(StatementList(listOf(wrapResultStatement(expression))), true)
result = TryStatement(bodyConverted, catchesConverted, finallyConverted)
return
}
}
result = TryStatement(converter.convertBlock(tryBlock), catchesConverted, finallyConverted)
}
private fun collectReturns(block: PsiCodeBlock?): Collection<PsiReturnStatement> {
val returns = ArrayList<PsiReturnStatement>()
block?.accept(object: JavaRecursiveElementVisitor() {
override fun visitReturnStatement(statement: PsiReturnStatement) {
returns.add(statement)
}
override fun visitMethod(method: PsiMethod) {
// do not go inside any other method (e.g. in anonymous class)
}
})
return returns
}
override fun visitWhileStatement(statement: PsiWhileStatement) {
@@ -241,10 +302,10 @@ class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
override fun visitReturnStatement(statement: PsiReturnStatement) {
val returnValue = statement.getReturnValue()
val methodReturnType = converter.methodReturnType
val expression = (if (returnValue != null && methodReturnType != null)
val expression = if (returnValue != null && methodReturnType != null)
converter.convertExpression(returnValue, methodReturnType)
else
converter.convertExpression(returnValue))
converter.convertExpression(returnValue)
result = ReturnStatement(expression)
}
@@ -116,14 +116,14 @@ abstract class AbstractJavaToKotlinConverterTest() : LightIdeaTestCase() {
private fun elementToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val fileWithText = JavaToKotlinTranslator.createFile(project, text)
val converter = Converter(project, settings, FilesConversionScope(listOf(fileWithText)))
val converter = Converter.create(project, settings, FilesConversionScope(listOf(fileWithText)))
val element = fileWithText.getFirstChild()!!
return converter.elementToKotlin(element)
}
private fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val file = JavaToKotlinTranslator.createFile(project, text)
val converter = Converter(project, settings, FilesConversionScope(listOf(file)))
val converter = Converter.create(project, settings, FilesConversionScope(listOf(file)))
return converter.elementToKotlin(file)
}
@@ -31,7 +31,7 @@ import org.jetbrains.jet.j2k.test.AbstractJavaToKotlinConverterTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("j2k/tests/testData/ast")
@InnerTestClasses({JavaToKotlinConverterTestGenerated.Annotations.class, JavaToKotlinConverterTestGenerated.AnonymousBlock.class, JavaToKotlinConverterTestGenerated.ArrayAccessExpression.class, JavaToKotlinConverterTestGenerated.ArrayInitializerExpression.class, JavaToKotlinConverterTestGenerated.ArrayType.class, JavaToKotlinConverterTestGenerated.AssertStatement.class, JavaToKotlinConverterTestGenerated.AssignmentExpression.class, JavaToKotlinConverterTestGenerated.BinaryExpression.class, JavaToKotlinConverterTestGenerated.BoxedType.class, JavaToKotlinConverterTestGenerated.BreakStatement.class, JavaToKotlinConverterTestGenerated.CallChainExpression.class, JavaToKotlinConverterTestGenerated.Class.class, JavaToKotlinConverterTestGenerated.ClassExpression.class, JavaToKotlinConverterTestGenerated.ConditionalExpression.class, JavaToKotlinConverterTestGenerated.Constructors.class, JavaToKotlinConverterTestGenerated.ContinueStatement.class, JavaToKotlinConverterTestGenerated.DeclarationStatement.class, JavaToKotlinConverterTestGenerated.DoWhileStatement.class, JavaToKotlinConverterTestGenerated.Enum.class, JavaToKotlinConverterTestGenerated.Equals.class, JavaToKotlinConverterTestGenerated.Field.class, JavaToKotlinConverterTestGenerated.For.class, JavaToKotlinConverterTestGenerated.ForeachStatement.class, JavaToKotlinConverterTestGenerated.Formatting.class, JavaToKotlinConverterTestGenerated.Function.class, JavaToKotlinConverterTestGenerated.Identifier.class, JavaToKotlinConverterTestGenerated.IfStatement.class, JavaToKotlinConverterTestGenerated.ImportStatement.class, JavaToKotlinConverterTestGenerated.InProjectionType.class, JavaToKotlinConverterTestGenerated.Inheritance.class, JavaToKotlinConverterTestGenerated.IsOperator.class, JavaToKotlinConverterTestGenerated.Issues.class, JavaToKotlinConverterTestGenerated.KotlinApiAccess.class, JavaToKotlinConverterTestGenerated.KotlinExclusion.class, JavaToKotlinConverterTestGenerated.LabelStatement.class, JavaToKotlinConverterTestGenerated.List.class, JavaToKotlinConverterTestGenerated.LiteralExpression.class, JavaToKotlinConverterTestGenerated.LocalVariable.class, JavaToKotlinConverterTestGenerated.MethodCallExpression.class, JavaToKotlinConverterTestGenerated.Misc.class, JavaToKotlinConverterTestGenerated.NewClassExpression.class, JavaToKotlinConverterTestGenerated.Nullability.class, JavaToKotlinConverterTestGenerated.ObjectLiteral.class, JavaToKotlinConverterTestGenerated.OutProjectionType.class, JavaToKotlinConverterTestGenerated.PackageStatement.class, JavaToKotlinConverterTestGenerated.ParenthesizedExpression.class, JavaToKotlinConverterTestGenerated.PolyadicExpression.class, JavaToKotlinConverterTestGenerated.PostfixOperator.class, JavaToKotlinConverterTestGenerated.PrefixOperator.class, JavaToKotlinConverterTestGenerated.RawGenerics.class, JavaToKotlinConverterTestGenerated.ReturnStatement.class, JavaToKotlinConverterTestGenerated.Settings.class, JavaToKotlinConverterTestGenerated.StarProjectionType.class, JavaToKotlinConverterTestGenerated.SuperExpression.class, JavaToKotlinConverterTestGenerated.Switch.class, JavaToKotlinConverterTestGenerated.SynchronizedStatement.class, JavaToKotlinConverterTestGenerated.ThisExpression.class, JavaToKotlinConverterTestGenerated.ThrowStatement.class, JavaToKotlinConverterTestGenerated.Trait.class, JavaToKotlinConverterTestGenerated.TryStatement.class, JavaToKotlinConverterTestGenerated.TypeCastExpression.class, JavaToKotlinConverterTestGenerated.TypeParameters.class, JavaToKotlinConverterTestGenerated.VarArg.class, JavaToKotlinConverterTestGenerated.WhileStatement.class})
@InnerTestClasses({JavaToKotlinConverterTestGenerated.Annotations.class, JavaToKotlinConverterTestGenerated.AnonymousBlock.class, JavaToKotlinConverterTestGenerated.ArrayAccessExpression.class, JavaToKotlinConverterTestGenerated.ArrayInitializerExpression.class, JavaToKotlinConverterTestGenerated.ArrayType.class, JavaToKotlinConverterTestGenerated.AssertStatement.class, JavaToKotlinConverterTestGenerated.AssignmentExpression.class, JavaToKotlinConverterTestGenerated.BinaryExpression.class, JavaToKotlinConverterTestGenerated.BoxedType.class, JavaToKotlinConverterTestGenerated.BreakStatement.class, JavaToKotlinConverterTestGenerated.CallChainExpression.class, JavaToKotlinConverterTestGenerated.Class.class, JavaToKotlinConverterTestGenerated.ClassExpression.class, JavaToKotlinConverterTestGenerated.ConditionalExpression.class, JavaToKotlinConverterTestGenerated.Constructors.class, JavaToKotlinConverterTestGenerated.ContinueStatement.class, JavaToKotlinConverterTestGenerated.DeclarationStatement.class, JavaToKotlinConverterTestGenerated.DoWhileStatement.class, JavaToKotlinConverterTestGenerated.Enum.class, JavaToKotlinConverterTestGenerated.Equals.class, JavaToKotlinConverterTestGenerated.Field.class, JavaToKotlinConverterTestGenerated.For.class, JavaToKotlinConverterTestGenerated.ForeachStatement.class, JavaToKotlinConverterTestGenerated.Formatting.class, JavaToKotlinConverterTestGenerated.Function.class, JavaToKotlinConverterTestGenerated.Identifier.class, JavaToKotlinConverterTestGenerated.IfStatement.class, JavaToKotlinConverterTestGenerated.ImportStatement.class, JavaToKotlinConverterTestGenerated.InProjectionType.class, JavaToKotlinConverterTestGenerated.Inheritance.class, JavaToKotlinConverterTestGenerated.IsOperator.class, JavaToKotlinConverterTestGenerated.Issues.class, JavaToKotlinConverterTestGenerated.KotlinApiAccess.class, JavaToKotlinConverterTestGenerated.KotlinExclusion.class, JavaToKotlinConverterTestGenerated.LabelStatement.class, JavaToKotlinConverterTestGenerated.List.class, JavaToKotlinConverterTestGenerated.LiteralExpression.class, JavaToKotlinConverterTestGenerated.LocalVariable.class, JavaToKotlinConverterTestGenerated.MethodCallExpression.class, JavaToKotlinConverterTestGenerated.Misc.class, JavaToKotlinConverterTestGenerated.NewClassExpression.class, JavaToKotlinConverterTestGenerated.Nullability.class, JavaToKotlinConverterTestGenerated.ObjectLiteral.class, JavaToKotlinConverterTestGenerated.OutProjectionType.class, JavaToKotlinConverterTestGenerated.PackageStatement.class, JavaToKotlinConverterTestGenerated.ParenthesizedExpression.class, JavaToKotlinConverterTestGenerated.PolyadicExpression.class, JavaToKotlinConverterTestGenerated.PostfixOperator.class, JavaToKotlinConverterTestGenerated.PrefixOperator.class, JavaToKotlinConverterTestGenerated.RawGenerics.class, JavaToKotlinConverterTestGenerated.ReturnStatement.class, JavaToKotlinConverterTestGenerated.Settings.class, JavaToKotlinConverterTestGenerated.StarProjectionType.class, JavaToKotlinConverterTestGenerated.SuperExpression.class, JavaToKotlinConverterTestGenerated.Switch.class, JavaToKotlinConverterTestGenerated.SynchronizedStatement.class, JavaToKotlinConverterTestGenerated.ThisExpression.class, JavaToKotlinConverterTestGenerated.ThrowStatement.class, JavaToKotlinConverterTestGenerated.Trait.class, JavaToKotlinConverterTestGenerated.TryStatement.class, JavaToKotlinConverterTestGenerated.TryWithResource.class, JavaToKotlinConverterTestGenerated.TypeCastExpression.class, JavaToKotlinConverterTestGenerated.TypeParameters.class, JavaToKotlinConverterTestGenerated.VarArg.class, JavaToKotlinConverterTestGenerated.WhileStatement.class})
public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConverterTest {
public void testAllFilesPresentInAst() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("j2k/tests/testData/ast"), Pattern.compile("^(.+)\\.java$"), true);
@@ -1863,16 +1863,26 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv
doTest("j2k/tests/testData/ast/newClassExpression/genericClassInvocation.java");
}
@TestMetadata("newAnonymousClass.java")
public void testNewAnonymousClass() throws Exception {
doTest("j2k/tests/testData/ast/newClassExpression/newAnonymousClass.java");
}
@TestMetadata("newAnonymousClass2.java")
public void testNewAnonymousClass2() throws Exception {
doTest("j2k/tests/testData/ast/newClassExpression/newAnonymousClass2.java");
}
@TestMetadata("newAnonymousClass3.java")
public void testNewAnonymousClass3() throws Exception {
doTest("j2k/tests/testData/ast/newClassExpression/newAnonymousClass3.java");
}
@TestMetadata("newClassByFullName.java")
public void testNewClassByFullName() throws Exception {
doTest("j2k/tests/testData/ast/newClassExpression/newClassByFullName.java");
}
@TestMetadata("newClassWithAnonymousScope.java")
public void testNewClassWithAnonymousScope() throws Exception {
doTest("j2k/tests/testData/ast/newClassExpression/newClassWithAnonymousScope.java");
}
@TestMetadata("newInnerClass.java")
public void testNewInnerClass() throws Exception {
doTest("j2k/tests/testData/ast/newClassExpression/newInnerClass.java");
@@ -2203,6 +2213,11 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("j2k/tests/testData/ast/returnStatement"), Pattern.compile("^(.+)\\.java$"), true);
}
@TestMetadata("currentMethodBug.java")
public void testCurrentMethodBug() throws Exception {
doTest("j2k/tests/testData/ast/returnStatement/currentMethodBug.java");
}
@TestMetadata("returnChar.java")
public void testReturnChar() throws Exception {
doTest("j2k/tests/testData/ast/returnStatement/returnChar.java");
@@ -2452,6 +2467,64 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv
}
@TestMetadata("j2k/tests/testData/ast/tryWithResource")
public static class TryWithResource extends AbstractJavaToKotlinConverterTest {
public void testAllFilesPresentInTryWithResource() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("j2k/tests/testData/ast/tryWithResource"), Pattern.compile("^(.+)\\.java$"), true);
}
@TestMetadata("Multiline.java")
public void testMultiline() throws Exception {
doTest("j2k/tests/testData/ast/tryWithResource/Multiline.java");
}
@TestMetadata("MultipleResources.java")
public void testMultipleResources() throws Exception {
doTest("j2k/tests/testData/ast/tryWithResource/MultipleResources.java");
}
@TestMetadata("Simple.java")
public void testSimple() throws Exception {
doTest("j2k/tests/testData/ast/tryWithResource/Simple.java");
}
@TestMetadata("WithCatch.java")
public void testWithCatch() throws Exception {
doTest("j2k/tests/testData/ast/tryWithResource/WithCatch.java");
}
@TestMetadata("WithCatchAndFinally.java")
public void testWithCatchAndFinally() throws Exception {
doTest("j2k/tests/testData/ast/tryWithResource/WithCatchAndFinally.java");
}
@TestMetadata("WithCatches.java")
public void testWithCatches() throws Exception {
doTest("j2k/tests/testData/ast/tryWithResource/WithCatches.java");
}
@TestMetadata("WithFinally.java")
public void testWithFinally() throws Exception {
doTest("j2k/tests/testData/ast/tryWithResource/WithFinally.java");
}
@TestMetadata("WithReturnAtEnd.java")
public void testWithReturnAtEnd() throws Exception {
doTest("j2k/tests/testData/ast/tryWithResource/WithReturnAtEnd.java");
}
@TestMetadata("WithReturnInAnonymousClass.java")
public void testWithReturnInAnonymousClass() throws Exception {
doTest("j2k/tests/testData/ast/tryWithResource/WithReturnInAnonymousClass.java");
}
@TestMetadata("WithReturnInAnonymousClass2.java")
public void testWithReturnInAnonymousClass2() throws Exception {
doTest("j2k/tests/testData/ast/tryWithResource/WithReturnInAnonymousClass2.java");
}
}
@TestMetadata("j2k/tests/testData/ast/typeCastExpression")
public static class TypeCastExpression extends AbstractJavaToKotlinConverterTest {
public void testAllFilesPresentInTypeCastExpression() throws Exception {
@@ -2677,6 +2750,7 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv
suite.addTestSuite(ThrowStatement.class);
suite.addTestSuite(Trait.class);
suite.addTestSuite(TryStatement.class);
suite.addTestSuite(TryWithResource.class);
suite.addTestSuite(TypeCastExpression.class);
suite.addTestSuite(TypeParameters.class);
suite.addTestSuite(VarArg.class);
+2
View File
@@ -19,6 +19,8 @@ public open class KotlinClass {
public trait KotlinTrait {
public fun nullableFun(): String?
public fun notNullableFun(): String
public fun nonAbstractFun(): Int = 1
}
public fun globalFunction(s: String): String = s
@@ -1,4 +1,4 @@
object : Runnable() {
object : Runnable {
override fun run() {
System.out.println("Run")
}
@@ -0,0 +1,13 @@
//file
abstract class A {}
class C {
void foo() {
A a = new A() {
@Override
public String toString() {
return "a";
}
};
}
}
@@ -0,0 +1,11 @@
abstract class A()
class C() {
fun foo() {
val a = object : A() {
override fun toString(): String {
return "a"
}
}
}
}
@@ -0,0 +1,27 @@
//file
import kotlinApi.KotlinTrait;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
class C {
void foo() {
KotlinTrait t = new KotlinTrait() {
@Nullable
@Override
public String nullableFun() {
return null;
}
@NotNull
@Override
public String notNullableFun() {
return "";
}
@Override
public int nonAbstractFun() {
return 0;
}
};
}
}
@@ -0,0 +1,19 @@
import kotlinApi.KotlinTrait
class C() {
fun foo() {
val t = object : KotlinTrait {
override fun nullableFun(): String? {
return null
}
override fun notNullableFun(): String {
return ""
}
override fun nonAbstractFun(): Int {
return 0
}
}
}
}
@@ -4,7 +4,7 @@ trait Getter {
class C() {
fun foo(b: Boolean): String {
val getter = object : Getter() {
val getter = object : Getter {
override fun get(): String? {
return null
}
@@ -0,0 +1,22 @@
//file
import org.jetbrains.annotations.Nullable;
interface I {
int getInt();
}
class C {
@Nullable Object getObject() {
foo(new I() {
@Override
public int getInt() {
return 0;
}
});
return string;
}
void foo(I i) {}
@Nullable String string;
}
@@ -0,0 +1,19 @@
trait I {
public fun getInt(): Int
}
class C() {
fun getObject(): Any? {
foo(object : I {
override fun getInt(): Int {
return 0
}
})
return string
}
fun foo(i: I) {
}
var string: String? = null
}
@@ -0,0 +1,12 @@
//file
import java.io.*;
public class C {
void foo() throws IOException {
try(InputStream stream = new FileInputStream("foo")) {
// reading something
int c = stream.read();
System.out.println(c);
}
}
}
@@ -0,0 +1,11 @@
import java.io.*
public class C() {
fun foo() {
FileInputStream("foo").use { stream ->
// reading something
val c = stream.read()
System.out.println(c)
}
}
}
@@ -0,0 +1,12 @@
//file
import java.io.*;
public class C {
void foo() throws IOException {
try(InputStream input = new FileInputStream("foo");
OutputStream output = new FileOutputStream("bar")) {
output.write(input.read());
output.write(0);
}
}
}
@@ -0,0 +1,12 @@
import java.io.*
public class C() {
fun foo() {
FileInputStream("foo").use { input ->
FileOutputStream("bar").use { output ->
output.write(input.read())
output.write(0)
}
}
}
}
@@ -0,0 +1,10 @@
//file
import java.io.*;
public class C {
void foo() throws IOException {
try(InputStream stream = new FileInputStream("foo")) {
System.out.println(stream.read());
}
}
}
@@ -0,0 +1,7 @@
import java.io.*
public class C() {
fun foo() {
FileInputStream("foo").use { stream -> System.out.println(stream.read()) }
}
}
@@ -0,0 +1,15 @@
//file
import java.io.*;
public class C {
void foo() {
try(InputStream stream = new FileInputStream("foo")) {
// reading something
int c = stream.read();
System.out.println(c);
}
catch (IOException e) {
System.out.println(e);
}
}
}
@@ -0,0 +1,16 @@
import java.io.*
public class C() {
fun foo() {
try {
FileInputStream("foo").use { stream ->
// reading something
val c = stream.read()
System.out.println(c)
}
} catch (e: IOException) {
System.out.println(e)
}
}
}
@@ -0,0 +1,18 @@
//file
import java.io.*;
public class C {
void foo() {
try(InputStream stream = new FileInputStream("foo")) {
// reading something
int c = stream.read();
System.out.println(c);
}
catch (IOException e) {
System.out.println(e);
}
finally {
System.out.println("Finally!");
}
}
}
@@ -0,0 +1,17 @@
import java.io.*
public class C() {
fun foo() {
try {
FileInputStream("foo").use { stream ->
// reading something
val c = stream.read()
System.out.println(c)
}
} catch (e: IOException) {
System.out.println(e)
} finally {
System.out.println("Finally!")
}
}
}
@@ -0,0 +1,18 @@
//file
import java.io.*;
public class C {
void foo() {
try(InputStream stream = new FileInputStream("foo")) {
// reading something
int c = stream.read();
System.out.println(c);
}
catch (IOException e) {
System.out.println(e);
}
catch (Exception e) {
System.err.println(e);
}
}
}
@@ -0,0 +1,18 @@
import java.io.*
public class C() {
fun foo() {
try {
FileInputStream("foo").use { stream ->
// reading something
val c = stream.read()
System.out.println(c)
}
} catch (e: IOException) {
System.out.println(e)
} catch (e: Exception) {
System.err.println(e)
}
}
}
@@ -0,0 +1,15 @@
//file
import java.io.*;
public class C {
void foo() throws IOException {
try(InputStream stream = new FileInputStream("foo")) {
// reading something
int c = stream.read();
System.out.println(c);
}
finally {
// dispose something else
}
}
}
@@ -0,0 +1,15 @@
import java.io.*
public class C() {
fun foo() {
try {
FileInputStream("foo").use { stream ->
// reading something
val c = stream.read()
System.out.println(c)
}
} finally {
// dispose something else
}
}
}
@@ -0,0 +1,17 @@
//file
import java.io.*;
public class C {
int foo() {
try(InputStream stream = new FileInputStream("foo")) {
while(true) {
int c = stream.read();
if (c < 0 || c > 127) return c;
}
}
catch (IOException e) {
System.out.println(e);
return -1;
}
}
}
@@ -0,0 +1,16 @@
//file
import java.io.*;
public class C {
int foo() {
try(InputStream stream = new FileInputStream("foo")) {
// reading something
int c = stream.read();
return c;
}
catch (IOException e) {
System.out.println(e);
return -1;
}
}
}
@@ -0,0 +1,17 @@
import java.io.*
public class C() {
fun foo(): Int {
try {
return FileInputStream("foo").use { stream ->
// reading something
val c = stream.read()
c
}
} catch (e: IOException) {
System.out.println(e)
return -1
}
}
}
@@ -0,0 +1,23 @@
//file
import java.io.*;
interface I {
int doIt(InputStream stream) throws IOException;
}
public class C {
void foo() throws IOException {
try(InputStream stream = new FileInputStream("foo")) {
bar(new I() {
@Override
public int doIt(InputStream stream) throws IOException {
return stream.available();
}
}, stream);
}
}
int bar(I i, InputStream stream) throws IOException {
return i.doIt(stream);
}
}
@@ -0,0 +1,21 @@
import java.io.*
trait I {
public fun doIt(stream: InputStream): Int
}
public class C() {
fun foo() {
FileInputStream("foo").use { stream ->
bar(object : I {
override fun doIt(stream: InputStream): Int {
return stream.available()
}
}, stream)
}
}
fun bar(i: I, stream: InputStream): Int {
return i.doIt(stream)
}
}
@@ -0,0 +1,23 @@
//file
import java.io.*;
interface I {
int doIt(InputStream stream) throws IOException;
}
public class C {
int foo() throws IOException {
try(InputStream stream = new FileInputStream("foo")) {
return bar(new I() {
@Override
public int doIt(InputStream stream) throws IOException {
return stream.available();
}
}, stream);
}
}
int bar(I i, InputStream stream) throws IOException {
return i.doIt(stream);
}
}
@@ -0,0 +1,21 @@
import java.io.*
trait I {
public fun doIt(stream: InputStream): Int
}
public class C() {
fun foo(): Int {
return FileInputStream("foo").use { stream ->
bar(object : I {
override fun doIt(stream: InputStream): Int {
return stream.available()
}
}, stream)
}
}
fun bar(i: I, stream: InputStream): Int {
return i.doIt(stream)
}
}
@@ -0,0 +1,26 @@
//file
import java.io.*;
interface I {
int doIt(InputStream stream) throws IOException;
}
public class C {
int foo() throws IOException {
try(InputStream stream = new FileInputStream("foo")) {
if (stream.read() >= 0) {
return bar(new I() {
@Override
public int doIt(InputStream stream) throws IOException {
return stream.available();
}
}, stream);
}
}
return -1;
}
int bar(I i, InputStream stream) throws IOException {
return i.doIt(stream);
}
}