Java to Kotlin converter: no more setting 'class identifiers', use ConversionScope

This commit is contained in:
Valentin Kipyatkov
2014-06-10 15:42:51 +04:00
parent 324040a02f
commit 6fd8ac5236
7 changed files with 18 additions and 103 deletions
@@ -16,7 +16,6 @@
package org.jetbrains.jet.plugin.actions;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -25,7 +24,6 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.j2k.Converter;
@@ -54,7 +52,7 @@ public class JavaToKotlinAction extends AnAction {
return;
}
final Converter converter = prepareConverter(project, selectedJavaFiles);
final Converter converter = new Converter(project, ConverterSettings.defaultSettings, new FilesConversionScope(selectedJavaFiles));
CommandProcessor.getInstance().executeCommand(
project,
new Runnable() {
@@ -78,18 +76,6 @@ public class JavaToKotlinAction extends AnAction {
);
}
@NotNull
private static Converter prepareConverter(@NotNull Project project, @NotNull List<PsiJavaFile> selectedJavaFiles) {
Converter converter = new Converter(project, ConverterSettings.defaultSettings, new FilesConversionScope(selectedJavaFiles));
converter.clearClassIdentifiers();
for (PsiFile f : selectedJavaFiles) {
if (f.getFileType() instanceof JavaFileType) {
setClassIdentifiers(converter, f);
}
}
return converter;
}
private static enum DialogResult {
BACKUP_FILES,
DELETE_FILES,
@@ -28,19 +28,11 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.j2k.Converter;
import org.jetbrains.jet.j2k.visitors.ClassVisitor;
import java.io.IOException;
import java.util.*;
public class JavaToKotlinActionUtil {
static void setClassIdentifiers(@NotNull Converter converter, @NotNull PsiFile psiFile) {
ClassVisitor c = new ClassVisitor();
psiFile.accept(c);
converter.setClassIdentifiers(new HashSet<String>(c.getClassIdentifiers()));
}
@NotNull
private static List<VirtualFile> getChildrenRecursive(@Nullable VirtualFile baseDir) {
List<VirtualFile> result = new LinkedList<VirtualFile>();
+2 -16
View File
@@ -37,25 +37,11 @@ public class Converter(val project: Project, val settings: ConverterSettings, va
private val typeConverter = TypeConverter(settings, conversionScope)
private var classIdentifiersSet: MutableSet<String> = HashSet()
private val dispatcher: Dispatcher = Dispatcher(this, typeConverter)
public var methodReturnType: PsiType? = null
private set
public fun setClassIdentifiers(identifiers: MutableSet<String>) {
classIdentifiersSet = identifiers
}
public fun getClassIdentifiers(): Set<String> {
return Collections.unmodifiableSet(classIdentifiersSet)
}
public fun clearClassIdentifiers() {
classIdentifiersSet.clear()
}
public fun elementToKotlin(element: PsiElement): String
= convertTopElement(element)?.toKotlin() ?: ""
@@ -307,9 +293,9 @@ public class Converter(val project: Project, val settings: ConverterSettings, va
val containing = method.getContainingClass()
if (containing != null) {
val hasOtherJavaSuperclasses = containing.getSuperTypes().any {
val canonicalText = it.getCanonicalText()
//TODO: correctly check for kotlin class
canonicalText != JAVA_LANG_OBJECT && !getClassIdentifiers().contains(canonicalText)
val `class` = it.resolve()
`class` != null && `class`.getQualifiedName() != JAVA_LANG_OBJECT && !conversionScope.contains(`class`)
}
if (hasOtherJavaSuperclasses) return true
}
@@ -25,7 +25,6 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiFileFactory
import com.intellij.psi.PsiJavaFile
import org.jetbrains.jet.j2k.visitors.ClassVisitor
import org.jetbrains.jet.utils.PathUtil
import java.io.File
import java.net.URLClassLoader
@@ -87,18 +86,10 @@ public object JavaToKotlinTranslator {
return null
}
fun setClassIdentifiers(converter: Converter, psiFile: PsiElement) {
val c = ClassVisitor()
psiFile.accept(c)
converter.clearClassIdentifiers()
converter.setClassIdentifiers(HashSet(c.classIdentifiers))
}
fun generateKotlinCode(javaCode: String): String {
val file = createFile(javaCode)
if (file is PsiJavaFile) {
val converter = Converter(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)))
setClassIdentifiers(converter, file)
return prettify(converter.convertFile(file).toKotlin())
}
return ""
@@ -1,36 +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 com.intellij.psi.JavaRecursiveElementVisitor
import com.intellij.psi.PsiClass
import java.util.HashSet
public open class ClassVisitor() : JavaRecursiveElementVisitor() {
private val _classIdentifiers = HashSet<String>()
public val classIdentifiers: Set<String>
get() = _classIdentifiers
override fun visitClass(aClass: PsiClass) {
val qName = aClass.getQualifiedName()
if (qName != null) {
_classIdentifiers.add(qName)
}
super.visitClass(aClass)
}
}
@@ -243,22 +243,23 @@ class ExpressionVisitor(private val converter: Converter,
private fun createNewClassExpression(expression: PsiNewExpression): Expression {
val anonymousClass = expression.getAnonymousClass()
val constructor = expression.resolveMethod()
val classReference = expression.getClassOrAnonymousClassReference()
val isNotConvertedClass = classReference != null && !converter.getClassIdentifiers().contains(classReference.getQualifiedName())
val argumentList = expression.getArgumentList()
var arguments = argumentList?.getExpressions() ?: array()
if (constructor == null || constructor.isPrimaryConstructor() || isNotConvertedClass) {
return NewClassExpression(converter.convertElement(classReference),
convertArguments(expression),
converter.convertExpression(expression.getQualifier()),
if (anonymousClass != null) converter.convertAnonymousClass(anonymousClass) else null)
var arguments = expression.getArgumentList()?.getExpressions() ?: array()
val constructor = expression.resolveMethod()
if (constructor != null && !constructor.isPrimaryConstructor() && converter.conversionScope.contains(constructor)) {
//TODO: handle anonymous class!
// non-primary constructor converted to factory method in class object
val reference = expression.getClassReference()
val typeParameters = if (reference != null) typeConverter.convertTypes(reference.getTypeParameters()) else listOf()
return QualifiedExpression(Identifier(constructor.getName(), false),
MethodCallExpression(Identifier("init"), converter.convertExpressions(arguments), typeParameters, false))
}
val reference = expression.getClassReference()
val typeParameters = if (reference != null) typeConverter.convertTypes(reference.getTypeParameters()) else listOf()
return QualifiedExpression(Identifier(constructor.getName(), false),
MethodCallExpression(Identifier("init"), converter.convertExpressions(arguments), typeParameters, false))
return NewClassExpression(converter.convertElement(classReference),
convertArguments(expression),
converter.convertExpression(expression.getQualifier()),
if (anonymousClass != null) converter.convertAnonymousClass(anonymousClass) else null)
}
private fun createNewEmptyArrayWithoutInitialization(expression: PsiNewExpression): Expression {
@@ -124,7 +124,7 @@ abstract class AbstractJavaToKotlinConverterTest() : LightIdeaTestCase() {
private fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val file = JavaToKotlinTranslator.createFile(project, text)
val converter = Converter(project, settings, FilesConversionScope(listOf(file)))
return generateKotlinCode(converter, file)
return converter.elementToKotlin(file)
}
private fun methodToKotlin(text: String, settings: ConverterSettings, project: Project): String {
@@ -142,11 +142,6 @@ abstract class AbstractJavaToKotlinConverterTest() : LightIdeaTestCase() {
return result.replaceFirst("val o : Any\\? =", "").replaceFirst("val o : Any = ", "").replaceFirst("val o = ", "").trim()
}
private fun generateKotlinCode(converter: Converter, file: PsiJavaFile): String {
JavaToKotlinTranslator.setClassIdentifiers(converter, file)
return converter.elementToKotlin(file)
}
override fun getProjectJDK(): Sdk? {
return PluginTestCaseBase.jdkFromIdeaHome()
}