Java to Kotlin converter: no more setting 'class identifiers', use ConversionScope
This commit is contained in:
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.plugin.actions;
|
package org.jetbrains.jet.plugin.actions;
|
||||||
|
|
||||||
import com.intellij.ide.highlighter.JavaFileType;
|
|
||||||
import com.intellij.openapi.actionSystem.AnAction;
|
import com.intellij.openapi.actionSystem.AnAction;
|
||||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
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.project.Project;
|
||||||
import com.intellij.openapi.ui.Messages;
|
import com.intellij.openapi.ui.Messages;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiFile;
|
|
||||||
import com.intellij.psi.PsiJavaFile;
|
import com.intellij.psi.PsiJavaFile;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.j2k.Converter;
|
import org.jetbrains.jet.j2k.Converter;
|
||||||
@@ -54,7 +52,7 @@ public class JavaToKotlinAction extends AnAction {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Converter converter = prepareConverter(project, selectedJavaFiles);
|
final Converter converter = new Converter(project, ConverterSettings.defaultSettings, new FilesConversionScope(selectedJavaFiles));
|
||||||
CommandProcessor.getInstance().executeCommand(
|
CommandProcessor.getInstance().executeCommand(
|
||||||
project,
|
project,
|
||||||
new Runnable() {
|
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 {
|
private static enum DialogResult {
|
||||||
BACKUP_FILES,
|
BACKUP_FILES,
|
||||||
DELETE_FILES,
|
DELETE_FILES,
|
||||||
|
|||||||
@@ -28,19 +28,11 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.j2k.Converter;
|
import org.jetbrains.jet.j2k.Converter;
|
||||||
import org.jetbrains.jet.j2k.visitors.ClassVisitor;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class JavaToKotlinActionUtil {
|
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
|
@NotNull
|
||||||
private static List<VirtualFile> getChildrenRecursive(@Nullable VirtualFile baseDir) {
|
private static List<VirtualFile> getChildrenRecursive(@Nullable VirtualFile baseDir) {
|
||||||
List<VirtualFile> result = new LinkedList<VirtualFile>();
|
List<VirtualFile> result = new LinkedList<VirtualFile>();
|
||||||
|
|||||||
@@ -37,25 +37,11 @@ public class Converter(val project: Project, val settings: ConverterSettings, va
|
|||||||
|
|
||||||
private val typeConverter = TypeConverter(settings, conversionScope)
|
private val typeConverter = TypeConverter(settings, conversionScope)
|
||||||
|
|
||||||
private var classIdentifiersSet: MutableSet<String> = HashSet()
|
|
||||||
|
|
||||||
private val dispatcher: Dispatcher = Dispatcher(this, typeConverter)
|
private val dispatcher: Dispatcher = Dispatcher(this, typeConverter)
|
||||||
|
|
||||||
public var methodReturnType: PsiType? = null
|
public var methodReturnType: PsiType? = null
|
||||||
private set
|
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
|
public fun elementToKotlin(element: PsiElement): String
|
||||||
= convertTopElement(element)?.toKotlin() ?: ""
|
= convertTopElement(element)?.toKotlin() ?: ""
|
||||||
|
|
||||||
@@ -307,9 +293,9 @@ public class Converter(val project: Project, val settings: ConverterSettings, va
|
|||||||
val containing = method.getContainingClass()
|
val containing = method.getContainingClass()
|
||||||
if (containing != null) {
|
if (containing != null) {
|
||||||
val hasOtherJavaSuperclasses = containing.getSuperTypes().any {
|
val hasOtherJavaSuperclasses = containing.getSuperTypes().any {
|
||||||
val canonicalText = it.getCanonicalText()
|
|
||||||
//TODO: correctly check for kotlin class
|
//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
|
if (hasOtherJavaSuperclasses) return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.PsiFileFactory
|
import com.intellij.psi.PsiFileFactory
|
||||||
import com.intellij.psi.PsiJavaFile
|
import com.intellij.psi.PsiJavaFile
|
||||||
import org.jetbrains.jet.j2k.visitors.ClassVisitor
|
|
||||||
import org.jetbrains.jet.utils.PathUtil
|
import org.jetbrains.jet.utils.PathUtil
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
@@ -87,18 +86,10 @@ public object JavaToKotlinTranslator {
|
|||||||
return null
|
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 {
|
fun generateKotlinCode(javaCode: String): String {
|
||||||
val file = createFile(javaCode)
|
val file = createFile(javaCode)
|
||||||
if (file is PsiJavaFile) {
|
if (file is PsiJavaFile) {
|
||||||
val converter = Converter(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)))
|
val converter = Converter(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)))
|
||||||
setClassIdentifiers(converter, file)
|
|
||||||
return prettify(converter.convertFile(file).toKotlin())
|
return prettify(converter.convertFile(file).toKotlin())
|
||||||
}
|
}
|
||||||
return ""
|
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 {
|
private fun createNewClassExpression(expression: PsiNewExpression): Expression {
|
||||||
val anonymousClass = expression.getAnonymousClass()
|
val anonymousClass = expression.getAnonymousClass()
|
||||||
val constructor = expression.resolveMethod()
|
|
||||||
val classReference = expression.getClassOrAnonymousClassReference()
|
val classReference = expression.getClassOrAnonymousClassReference()
|
||||||
val isNotConvertedClass = classReference != null && !converter.getClassIdentifiers().contains(classReference.getQualifiedName())
|
var arguments = expression.getArgumentList()?.getExpressions() ?: array()
|
||||||
val argumentList = expression.getArgumentList()
|
|
||||||
var arguments = argumentList?.getExpressions() ?: array()
|
val constructor = expression.resolveMethod()
|
||||||
if (constructor == null || constructor.isPrimaryConstructor() || isNotConvertedClass) {
|
if (constructor != null && !constructor.isPrimaryConstructor() && converter.conversionScope.contains(constructor)) {
|
||||||
return NewClassExpression(converter.convertElement(classReference),
|
//TODO: handle anonymous class!
|
||||||
convertArguments(expression),
|
// non-primary constructor converted to factory method in class object
|
||||||
converter.convertExpression(expression.getQualifier()),
|
val reference = expression.getClassReference()
|
||||||
if (anonymousClass != null) converter.convertAnonymousClass(anonymousClass) else null)
|
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()
|
return NewClassExpression(converter.convertElement(classReference),
|
||||||
val typeParameters = if (reference != null) typeConverter.convertTypes(reference.getTypeParameters()) else listOf()
|
convertArguments(expression),
|
||||||
return QualifiedExpression(Identifier(constructor.getName(), false),
|
converter.convertExpression(expression.getQualifier()),
|
||||||
MethodCallExpression(Identifier("init"), converter.convertExpressions(arguments), typeParameters, false))
|
if (anonymousClass != null) converter.convertAnonymousClass(anonymousClass) else null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createNewEmptyArrayWithoutInitialization(expression: PsiNewExpression): Expression {
|
private fun createNewEmptyArrayWithoutInitialization(expression: PsiNewExpression): Expression {
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ abstract class AbstractJavaToKotlinConverterTest() : LightIdeaTestCase() {
|
|||||||
private fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String {
|
private fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String {
|
||||||
val file = JavaToKotlinTranslator.createFile(project, text)
|
val file = JavaToKotlinTranslator.createFile(project, text)
|
||||||
val converter = Converter(project, settings, FilesConversionScope(listOf(file)))
|
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 {
|
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()
|
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? {
|
override fun getProjectJDK(): Sdk? {
|
||||||
return PluginTestCaseBase.jdkFromIdeaHome()
|
return PluginTestCaseBase.jdkFromIdeaHome()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user