Converter:

Replace hack used to configure Converter by ConverterSettings class
Minor: remove redundant open modifiers, add override annotations
This commit is contained in:
Pavel Talanov
2013-11-05 18:07:47 +04:00
committed by Pavel V. Talanov
parent 3edefcf598
commit cba8d3b6db
11 changed files with 89 additions and 72 deletions
@@ -27,6 +27,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import org.jetbrains.jet.j2k.Converter;
import org.jetbrains.jet.j2k.J2kPackage;
import java.util.List;
@@ -39,7 +40,7 @@ public class JavaToKotlinAction extends AnAction {
assert virtualFiles != null;
final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
assert project != null;
final Converter converter = new Converter(project);
final Converter converter = new Converter(project, J2kPackage.getPluginSettings());
int result = Messages.showYesNoCancelDialog(project,
"Would you like to backup Java files?",
"Backup",
@@ -28,6 +28,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.j2k.Converter;
import org.jetbrains.jet.j2k.J2kPackage;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.plugin.editor.JetEditorOptions;
@@ -116,7 +117,7 @@ public class JavaCopyPastePostProcessor implements CopyPastePostProcessor<TextBl
Project project = file.getProject();
StringBuilder result = new StringBuilder();
for (PsiElement e : buffer) {
String converted = new Converter(project).elementToKotlin(e);
String converted = new Converter(project, J2kPackage.getPluginSettings()).elementToKotlin(e);
if (!converted.isEmpty()) {
result.append(converted).append(EOL);
}
+29 -29
View File
@@ -37,7 +37,7 @@ import org.jetbrains.jet.util.QualifiedNamesUtil
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap
import com.intellij.openapi.project.Project
public open class Converter(val project: Project) {
public class Converter(val project: Project, val settings: ConverterSettings) {
private var classIdentifiersSet: MutableSet<String> = Sets.newHashSet()!!
@@ -47,35 +47,35 @@ public open class Converter(val project: Project) {
private val javaToKotlinClassMap: JavaToKotlinClassMap = JavaToKotlinClassMap.getInstance()
public open var methodReturnType: PsiType? = null
public var methodReturnType: PsiType? = null
private set
public open fun addFlag(flag: J2KConverterFlags): Boolean {
public fun addFlag(flag: J2KConverterFlags): Boolean {
return flags?.add(flag)!!
}
public open fun hasFlag(flag: J2KConverterFlags): Boolean {
public fun hasFlag(flag: J2KConverterFlags): Boolean {
return flags?.contains(flag)!!
}
public open fun setClassIdentifiers(identifiers: MutableSet<String>) {
public fun setClassIdentifiers(identifiers: MutableSet<String>) {
classIdentifiersSet = identifiers
}
public open fun getClassIdentifiers(): Set<String> {
public fun getClassIdentifiers(): Set<String> {
return Collections.unmodifiableSet(classIdentifiersSet)
}
public open fun clearClassIdentifiers() {
public fun clearClassIdentifiers() {
classIdentifiersSet.clear()
}
public open fun elementToKotlin(element: PsiElement): String {
public fun elementToKotlin(element: PsiElement): String {
val kElement = topElementToElement(element)
return kElement?.toKotlin() ?: ""
}
public open fun topElementToElement(element: PsiElement?): Node? = when(element) {
public fun topElementToElement(element: PsiElement?): Node? = when(element) {
is PsiJavaFile -> fileToFile(element)
is PsiClass -> classToClass(element)
is PsiMethod -> methodToFunction(element)
@@ -86,11 +86,11 @@ public open class Converter(val project: Project) {
else -> null
}
public open fun fileToFile(javaFile: PsiJavaFile): File {
public fun fileToFile(javaFile: PsiJavaFile): File {
return fileToFile(javaFile, Collections.emptyList<String>())
}
public open fun fileToFileWithCompatibilityImport(javaFile: PsiJavaFile): File {
public fun fileToFileWithCompatibilityImport(javaFile: PsiJavaFile): File {
return fileToFile(javaFile, Collections.singletonList("kotlin.compatibility.*"))
}
@@ -124,7 +124,7 @@ public open class Converter(val project: Project) {
return File(quoteKeywords(javaFile.getPackageName()), imports, body, createMainFunction(javaFile))
}
public open fun anonymousClassToAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass {
public fun anonymousClassToAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass {
return AnonymousClass(this, getMembers(anonymousClass))
}
@@ -352,26 +352,26 @@ public open class Converter(val project: Project) {
return false
}
public open fun blockToBlock(block: PsiCodeBlock?, notEmpty: Boolean): Block {
public fun blockToBlock(block: PsiCodeBlock?, notEmpty: Boolean): Block {
if (block == null)
return Block.EMPTY_BLOCK
return Block(removeEmpty(statementsToStatementList(block.getChildren())), notEmpty)
}
public open fun blockToBlock(block: PsiCodeBlock?): Block {
public fun blockToBlock(block: PsiCodeBlock?): Block {
return blockToBlock(block, true)
}
public open fun statementsToStatementList(statements: Array<PsiElement>): List<Element> {
public fun statementsToStatementList(statements: Array<PsiElement>): List<Element> {
return statements.filterNot { it is PsiWhiteSpace }.map { statementToStatement(it) }
}
public open fun statementsToStatementList(statements: List<PsiElement>): List<Element> {
public fun statementsToStatementList(statements: List<PsiElement>): List<Element> {
return statements.filterNot { it is PsiWhiteSpace }.map { statementToStatement(it) }
}
public open fun statementToStatement(s: PsiElement?): Element {
public fun statementToStatement(s: PsiElement?): Element {
if (s == null)
return Statement.EMPTY_STATEMENT
@@ -380,14 +380,14 @@ public open class Converter(val project: Project) {
return statementVisitor.getResult()
}
public open fun expressionsToExpressionList(expressions: Array<PsiExpression>): List<Expression> {
public fun expressionsToExpressionList(expressions: Array<PsiExpression>): List<Expression> {
val result = ArrayList<Expression>()
for (e : PsiExpression? in expressions)
result.add(expressionToExpression(e))
return result
}
public open fun expressionToExpression(e: PsiExpression?): Expression {
public fun expressionToExpression(e: PsiExpression?): Expression {
if (e == null)
return Expression.EMPTY_EXPRESSION
@@ -396,7 +396,7 @@ public open class Converter(val project: Project) {
return expressionVisitor.getResult()
}
public open fun elementToElement(e: PsiElement?): Element {
public fun elementToElement(e: PsiElement?): Element {
if (e == null)
return Element.EMPTY_ELEMENT
@@ -405,7 +405,7 @@ public open class Converter(val project: Project) {
return elementVisitor.getResult()
}
public open fun elementsToElementList(elements: Array<out PsiElement?>): List<Element> {
public fun elementsToElementList(elements: Array<out PsiElement?>): List<Element> {
val result = ArrayList<Element>()
for (element in elements) {
result.add(elementToElement(element))
@@ -413,14 +413,14 @@ public open class Converter(val project: Project) {
return result
}
public open fun typeElementToTypeElement(element: PsiTypeElement?): TypeElement {
public fun typeElementToTypeElement(element: PsiTypeElement?): TypeElement {
return TypeElement(if (element == null)
EmptyType()
else
typeToType(element.getType()))
}
public open fun typeToType(`type`: PsiType?): Type {
public fun typeToType(`type`: PsiType?): Type {
if (`type` == null)
return EmptyType()
@@ -429,11 +429,11 @@ public open class Converter(val project: Project) {
return typeVisitor.getResult()
}
public open fun typesToTypeList(types: Array<PsiType>): List<Type> {
public fun typesToTypeList(types: Array<PsiType>): List<Type> {
return types.map { typeToType(it) }
}
public open fun typeToType(`type`: PsiType?, notNull: Boolean): Type {
public fun typeToType(`type`: PsiType?, notNull: Boolean): Type {
val result: Type = typeToType(`type`)
if (notNull) {
return result.convertedToNotNull()
@@ -450,17 +450,17 @@ public open class Converter(val project: Project) {
return result
}
public open fun parametersToParameterList(parameters: Array<PsiParameter>): List<Parameter?> {
public fun parametersToParameterList(parameters: Array<PsiParameter>): List<Parameter?> {
return parameters.map { parameterToParameter(it) }
}
public open fun parameterToParameter(parameter: PsiParameter, forceNotNull: Boolean = false): Parameter {
public fun parameterToParameter(parameter: PsiParameter, forceNotNull: Boolean = false): Parameter {
return Parameter(Identifier(parameter.getName()!!),
typeToType(parameter.getType(),
forceNotNull || isAnnotatedAsNotNull(parameter.getModifierList())), true)
}
public open fun argumentsToExpressionList(expression: PsiCallExpression): List<Expression> {
public fun argumentsToExpressionList(expression: PsiCallExpression): List<Expression> {
val argumentList: PsiExpressionList? = expression.getArgumentList()
val arguments: Array<PsiExpression> = (if (argumentList != null)
argumentList.getExpressions()
@@ -485,7 +485,7 @@ public open class Converter(val project: Project) {
return result
}
public open fun expressionToExpression(argument: PsiExpression?, expectedType: PsiType?): Expression {
public fun expressionToExpression(argument: PsiExpression?, expectedType: PsiType?): Expression {
if (argument == null)
return Identifier.EMPTY_IDENTIFIER
@@ -0,0 +1,35 @@
/*
* 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
public class ConverterSettings(
val forceNotNullTypes: Boolean,
val forceLocalVariableImmutability: Boolean,
val specifyLocalVariableTypeByDefault: Boolean
) {}
public val PluginSettings: ConverterSettings = ConverterSettings(
forceNotNullTypes = true,
forceLocalVariableImmutability = true,
specifyLocalVariableTypeByDefault = false
)
public val TestSettings: ConverterSettings = ConverterSettings(
forceNotNullTypes = false,
forceLocalVariableImmutability = false,
specifyLocalVariableTypeByDefault = true
)
@@ -96,7 +96,7 @@ object JavaToKotlinTranslator {
fun generateKotlinCode(javaCode: String): String {
val file = createFile(javaCode)
if (file is PsiJavaFile) {
val converter = Converter(file.getProject())
val converter = Converter(file.getProject(), TestSettings)
setClassIdentifiers(converter, file)
return prettify(converter.fileToFile(file).toKotlin())
}
@@ -106,7 +106,7 @@ object JavaToKotlinTranslator {
fun generateKotlinCodeWithCompatibilityImport(javaCode: String): String {
val file = createFile(javaCode)
if (file is PsiJavaFile) {
val converter = Converter(file.getProject())
val converter = Converter(file.getProject(), TestSettings)
setClassIdentifiers(converter, file)
return prettify(converter.fileToFileWithCompatibilityImport(file).toKotlin())
}
@@ -24,13 +24,9 @@ public class CallChainExpression(val expression: Expression, val identifier: Exp
public override fun toKotlin(): String {
if (!expression.isEmpty()) {
return expression.toKotlin() + (if (expression.isNullable() && !forceDotCall) "?." else ".") + identifier.toKotlin()
return expression.toKotlin() + (if (expression.isNullable()) "?." else ".") + identifier.toKotlin()
}
return identifier.toKotlin()
}
class object {
public var forceDotCall: Boolean = true
}
}
@@ -25,18 +25,15 @@ public class LocalVariable(val identifier: Identifier,
val initializer: Expression,
val converter: Converter) : Expression() {
public fun isImmutable(): Boolean = forceImmutable || modifiersSet.contains(Modifier.FINAL)
public fun isImmutable(): Boolean =
converter.settings.forceLocalVariableImmutability || modifiersSet.contains(Modifier.FINAL)
override fun toKotlin(): String {
if (initializer.isEmpty()) {
return "${identifier.toKotlin()} : ${javaType.toKotlin()}"
}
return "${identifier.toKotlin()} ${if (specifyTypeExplicitly) ": ${javaType.toKotlin()} " else ""}= ${initializer.toKotlin()}"
}
class object {
public var specifyTypeExplicitly: Boolean = false
public var forceImmutable: Boolean = true
val shouldSpecifyType = converter.settings.specifyLocalVariableTypeByDefault
return "${identifier.toKotlin()} ${if (shouldSpecifyType) ": ${javaType.toKotlin()} " else ""}= ${initializer.toKotlin()}"
}
}
@@ -21,7 +21,8 @@ import org.jetbrains.jet.j2k.Converter
public fun Type.isPrimitive(): Boolean = this is PrimitiveType
public abstract class MayBeNullableType(override public val nullable: Boolean, val converter: Converter): Type {
public abstract class MayBeNullableType(nullable: Boolean, val converter: Converter): Type {
override public val nullable: Boolean = !converter.settings.forceNotNullTypes && nullable
}
public trait NotNullType : Type {
@@ -39,13 +40,6 @@ public trait Type : Element {
}
protected fun isNullableStr(): String? {
return (if (nullable && !forceNotNullTypes)
"?"
else
"")
}
class object {
public var forceNotNullTypes: Boolean = true
return if (nullable) "?" else ""
}
}
@@ -18,9 +18,7 @@ package org.jetbrains.jet.j2k.test;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.jetbrains.jet.j2k.ast.CallChainExpression;
import org.jetbrains.jet.j2k.ast.LocalVariable;
import org.jetbrains.jet.j2k.ast.types.Type;
import org.jetbrains.jet.j2k.J2kPackage;
import static org.jetbrains.jet.j2k.test.TestPackage.suiteForDirectory;
@@ -32,15 +30,12 @@ public class BasicConverterTestSuite {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(suiteForDirectory("j2k/tests/testData", "/ast", new NamedTestFactory() {
@Override
public Test createTest(String dataPath, String name) {
//noinspection JUnitTestCaseWithNoTests
return new StandaloneJavaToKotlinConverterTest(dataPath, name) {
return new StandaloneJavaToKotlinConverterTest(dataPath, name, J2kPackage.getTestSettings()) {
@Override
protected void runTest() {
CallChainExpression.forceDotCall = false;
LocalVariable.specifyTypeExplicitly = true;
LocalVariable.forceImmutable = false;
Type.forceNotNullTypes = false;
super.runTest();
}
};
@@ -18,9 +18,7 @@ package org.jetbrains.jet.j2k.test;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.jetbrains.jet.j2k.ast.CallChainExpression;
import org.jetbrains.jet.j2k.ast.LocalVariable;
import org.jetbrains.jet.j2k.ast.types.Type;
import org.jetbrains.jet.j2k.J2kPackage;
import static org.jetbrains.jet.j2k.test.TestPackage.suiteForDirectory;
@@ -32,15 +30,12 @@ public class ConverterTestSuiteForPlugin {
TestSuite suite = new TestSuite();
suite.addTest(suiteForDirectory("j2k/tests/testData", "/plugin", new NamedTestFactory() {
@Override
public Test createTest(String dataPath, String name) {
//noinspection JUnitTestCaseWithNoTests
return new StandaloneJavaToKotlinConverterTest(dataPath, name) {
return new StandaloneJavaToKotlinConverterTest(dataPath, name, J2kPackage.getPluginSettings()) {
@Override
protected void runTest() {
CallChainExpression.forceDotCall = true;
LocalVariable.specifyTypeExplicitly = false;
LocalVariable.forceImmutable = true;
Type.forceNotNullTypes = true;
super.runTest();
}
};
@@ -31,12 +31,15 @@ import org.jetbrains.jet.j2k.JavaToKotlinTranslator
import org.jetbrains.jet.ConfigurationKind
import org.jetbrains.jet.JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations
import com.intellij.testFramework.UsefulTestCase
import org.jetbrains.jet.j2k.ConverterSettings
public abstract class StandaloneJavaToKotlinConverterTest(val dataPath: String, val name: String) : UsefulTestCase() {
public abstract class StandaloneJavaToKotlinConverterTest(val dataPath: String,
val name: String,
val settings: ConverterSettings) : UsefulTestCase() {
protected override fun runTest(): Unit {
val jetCoreEnvironment = createEnvironmentWithMockJdkAndIdeaAnnotations(getTestRootDisposable(), ConfigurationKind.JDK_ONLY)
val converter = Converter(jetCoreEnvironment.getProject())
val converter = Converter(jetCoreEnvironment.getProject(), settings)
val javaPath = "j2k/tests/testData/" + getTestFilePath()
val kotlinPath = javaPath.replace(".jav", ".kt")
val kotlinFile = File(kotlinPath)