J2K: adding type arguments where they are needed and removing them where they are redundant
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import kotlin.jvm.KotlinSignature;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
@@ -41,12 +42,15 @@ public interface Call {
|
||||
@Nullable
|
||||
JetValueArgumentList getValueArgumentList();
|
||||
|
||||
@KotlinSignature("fun getValueArguments(): List<out ValueArgument?>")
|
||||
@NotNull
|
||||
List<? extends ValueArgument> getValueArguments();
|
||||
|
||||
@KotlinSignature("fun getFunctionLiteralArguments(): List<JetExpression>")
|
||||
@NotNull
|
||||
List<JetExpression> getFunctionLiteralArguments();
|
||||
|
||||
@KotlinSignature("fun getTypeArguments(): List<JetTypeProjection>")
|
||||
@NotNull
|
||||
List<JetTypeProjection> getTypeArguments();
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.j2k.Converter;
|
||||
import org.jetbrains.jet.j2k.ConverterSettings;
|
||||
import org.jetbrains.jet.j2k.FilesConversionScope;
|
||||
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -52,7 +53,10 @@ public class JavaToKotlinAction extends AnAction {
|
||||
return;
|
||||
}
|
||||
|
||||
final Converter converter = Converter.object$.create(project, ConverterSettings.defaultSettings, new FilesConversionScope(selectedJavaFiles));
|
||||
final Converter converter = Converter.object$.create(project,
|
||||
ConverterSettings.defaultSettings,
|
||||
new FilesConversionScope(selectedJavaFiles),
|
||||
J2kPostProcessor.instance$);
|
||||
CommandProcessor.getInstance().executeCommand(
|
||||
project,
|
||||
new Runnable() {
|
||||
|
||||
+5
-2
@@ -32,7 +32,7 @@ import org.jetbrains.jet.plugin.editor.JetEditorOptions
|
||||
import java.awt.datatransfer.Transferable
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import com.intellij.codeInsight.editorActions.ReferenceTransferableData
|
||||
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor;
|
||||
|
||||
public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBlockTransferableData>() {
|
||||
|
||||
@@ -85,7 +85,10 @@ public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBl
|
||||
}
|
||||
|
||||
private fun convertCopiedCodeToKotlin(code: CopiedCode, file: PsiJavaFile): String {
|
||||
val converter = Converter.create(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)))
|
||||
val converter = Converter.create(file.getProject(),
|
||||
ConverterSettings.defaultSettings,
|
||||
FilesConversionScope(listOf(file)),
|
||||
J2kPostProcessor)
|
||||
val startOffsets = code.getStartOffsets()
|
||||
val endOffsets = code.getEndOffsets()
|
||||
assert(startOffsets.size == endOffsets.size) { "Must have the same size" }
|
||||
|
||||
@@ -84,14 +84,9 @@ public class RemoveExplicitTypeArguments : JetSelfTargetingIntention<JetTypeArgu
|
||||
return args == newArgs
|
||||
}
|
||||
|
||||
class CallWithoutTypeArgs(call: Call) : DelegatingCall(call) {
|
||||
|
||||
override fun getTypeArguments(): MutableList<JetTypeProjection> {
|
||||
return ArrayList<JetTypeProjection>()
|
||||
}
|
||||
|
||||
private class CallWithoutTypeArgs(call: Call) : DelegatingCall(call) {
|
||||
override fun getTypeArguments(): List<JetTypeProjection> = listOf()
|
||||
override fun getTypeArgumentList() = null
|
||||
|
||||
}
|
||||
|
||||
override fun applyTo(element: JetTypeArgumentList, editor: Editor) {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.plugin.j2k
|
||||
|
||||
import org.jetbrains.jet.j2k.PostProcessor
|
||||
import org.jetbrains.jet.lang.psi.*
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.plugin.intentions.RemoveExplicitTypeArguments
|
||||
import org.jetbrains.jet.plugin.caches.resolve.getAnalysisResults
|
||||
import java.util.ArrayList
|
||||
|
||||
public object J2kPostProcessor : PostProcessor {
|
||||
override fun analyzeFile(file: JetFile): BindingContext {
|
||||
return file.getAnalysisResults().getBindingContext()
|
||||
}
|
||||
|
||||
override fun doAdditionalProcessing(file: JetFile) {
|
||||
val redundantTypeArgs = ArrayList<JetTypeArgumentList>()
|
||||
file.accept(object : JetTreeVisitorVoid(){
|
||||
override fun visitTypeArgumentList(typeArgumentList: JetTypeArgumentList) {
|
||||
if (RemoveExplicitTypeArguments().isApplicableTo(typeArgumentList)) {
|
||||
redundantTypeArgs.add(typeArgumentList)
|
||||
return
|
||||
}
|
||||
|
||||
super.visitTypeArgumentList(typeArgumentList)
|
||||
}
|
||||
})
|
||||
|
||||
for (typeArgs in redundantTypeArgs) {
|
||||
typeArgs.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,44 +17,33 @@
|
||||
package org.jetbrains.jet.j2k
|
||||
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM
|
||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.jet.lang.resolve.name.Name
|
||||
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||
import org.jetbrains.jet.lang.psi.JetUnaryExpression
|
||||
import org.jetbrains.jet.lang.psi.JetProperty
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
|
||||
class AfterConversionPass(val project: Project) {
|
||||
class AfterConversionPass(val project: Project, val postProcessor: PostProcessor) {
|
||||
public fun run(kotlinCode: String): String {
|
||||
val kotlinFile = JetPsiFactory(project).createFile(kotlinCode)
|
||||
val analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
project,
|
||||
listOf(kotlinFile),
|
||||
BindingTraceContext(),
|
||||
{ true },
|
||||
ModuleDescriptorImpl(Name.special("<module>"), AnalyzerFacadeForJVM.DEFAULT_IMPORTS, JavaToKotlinClassMap.getInstance()),
|
||||
null,
|
||||
null
|
||||
)
|
||||
val bindingContext = postProcessor.analyzeFile(kotlinFile)
|
||||
|
||||
val problems = analyzeExhaust.getBindingContext().getDiagnostics()
|
||||
val fixes = problems.map {
|
||||
val fixes = bindingContext.getDiagnostics().map {
|
||||
val fix = fixForProblem(it)
|
||||
if (fix != null) it.getPsiElement() to fix else null
|
||||
}.filterNotNull()
|
||||
|
||||
if (fixes.isEmpty()) return kotlinCode
|
||||
|
||||
for ((psiElement, fix) in fixes) {
|
||||
if (psiElement.isValid()) {
|
||||
fix()
|
||||
}
|
||||
}
|
||||
|
||||
postProcessor.doAdditionalProcessing(kotlinFile)
|
||||
|
||||
return kotlinFile.getText()!!
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.ArrayList
|
||||
import org.jetbrains.jet.j2k.ast.Element
|
||||
import kotlin.platform.platformName
|
||||
import org.jetbrains.jet.j2k.ast.CommentsAndSpacesInheritance
|
||||
import com.intellij.psi.impl.light.LightElement
|
||||
|
||||
fun<T> CodeBuilder.append(generators: Collection<() -> T>, separator: String, prefix: String = "", suffix: String = ""): CodeBuilder {
|
||||
if (generators.isNotEmpty()) {
|
||||
@@ -95,6 +96,7 @@ class CodeBuilder(private val topElement: PsiElement?) {
|
||||
val prefixElements = ArrayList<PsiElement>(1)
|
||||
val postfixElements = ArrayList<PsiElement>(1)
|
||||
for ((prototype, inheritance) in element.prototypes!!) {
|
||||
if (prototype is LightElement) continue
|
||||
assert(prototype !is PsiComment)
|
||||
assert(prototype !is PsiWhiteSpace)
|
||||
assert(topElement.isAncestor(prototype))
|
||||
|
||||
@@ -25,6 +25,8 @@ import org.jetbrains.jet.lang.types.expressions.OperatorConventions.*
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.util.PsiMethodUtil
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.jet.lang.psi.JetFile
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
|
||||
public trait ConversionScope {
|
||||
public fun contains(element: PsiElement): Boolean
|
||||
@@ -34,7 +36,16 @@ public class FilesConversionScope(val files: Collection<PsiJavaFile>) : Conversi
|
||||
override fun contains(element: PsiElement) = files.any { element.getContainingFile() == it }
|
||||
}
|
||||
|
||||
public class Converter private(val project: Project, val settings: ConverterSettings, val conversionScope: ConversionScope, val state: Converter.State) {
|
||||
public trait PostProcessor {
|
||||
public fun analyzeFile(file: JetFile): BindingContext
|
||||
public fun doAdditionalProcessing(file: JetFile)
|
||||
}
|
||||
|
||||
public class Converter private(val project: Project,
|
||||
val settings: ConverterSettings,
|
||||
val conversionScope: ConversionScope,
|
||||
private val postProcessor: PostProcessor?,
|
||||
private val state: Converter.State) {
|
||||
private class State(val methodReturnType: PsiType?,
|
||||
val expressionVisitorFactory: (Converter) -> ExpressionVisitor,
|
||||
val statementVisitorFactory: (Converter) -> StatementVisitor,
|
||||
@@ -55,41 +66,46 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
val annotationConverter = AnnotationConverter(this)
|
||||
|
||||
class object {
|
||||
public fun create(project: Project, settings: ConverterSettings, conversionScope: ConversionScope): Converter {
|
||||
public fun create(project: Project, settings: ConverterSettings, conversionScope: ConversionScope, postProcessor: PostProcessor?): Converter {
|
||||
val state = State(null, { ExpressionVisitor(it) }, { StatementVisitor(it) }, null, null, null)
|
||||
return Converter(project, settings, conversionScope, state)
|
||||
return Converter(project, settings, conversionScope, postProcessor, state)
|
||||
}
|
||||
}
|
||||
|
||||
fun withMethodReturnType(methodReturnType: PsiType?): Converter
|
||||
= Converter(project, settings, conversionScope,
|
||||
= Converter(project, settings, conversionScope, postProcessor,
|
||||
State(methodReturnType, state.expressionVisitorFactory, state.statementVisitorFactory, state.specialContext, state.importList, state.importsToAdd))
|
||||
|
||||
fun withExpressionVisitor(factory: (Converter) -> ExpressionVisitor): Converter
|
||||
= Converter(project, settings, conversionScope,
|
||||
= Converter(project, settings, conversionScope, postProcessor,
|
||||
State(state.methodReturnType, factory, state.statementVisitorFactory, state.specialContext, state.importList, state.importsToAdd))
|
||||
|
||||
fun withStatementVisitor(factory: (Converter) -> StatementVisitor): Converter
|
||||
= Converter(project, settings, conversionScope,
|
||||
= Converter(project, settings, conversionScope, postProcessor,
|
||||
State(state.methodReturnType, state.expressionVisitorFactory, factory, state.specialContext, state.importList, state.importsToAdd))
|
||||
|
||||
fun withSpecialContext(context: PsiElement): Converter
|
||||
= Converter(project, settings, conversionScope,
|
||||
= Converter(project, settings, conversionScope, postProcessor,
|
||||
State(state.methodReturnType, state.expressionVisitorFactory, state.statementVisitorFactory, context, state.importList, state.importsToAdd))
|
||||
|
||||
private fun withImportList(importList: ImportList): Converter
|
||||
= Converter(project, settings, conversionScope,
|
||||
= Converter(project, settings, conversionScope, postProcessor,
|
||||
State(state.methodReturnType, state.expressionVisitorFactory, state.statementVisitorFactory, state.specialContext, importList, state.importsToAdd))
|
||||
|
||||
private fun withImportsToAdd(importsToAdd: MutableCollection<String>): Converter
|
||||
= Converter(project, settings, conversionScope,
|
||||
= Converter(project, settings, conversionScope, postProcessor,
|
||||
State(state.methodReturnType, state.expressionVisitorFactory, state.statementVisitorFactory, state.specialContext, state.importList, importsToAdd))
|
||||
|
||||
public fun elementToKotlin(element: PsiElement): String {
|
||||
val converted = convertTopElement(element) ?: return ""
|
||||
val builder = CodeBuilder(element)
|
||||
builder.append(converted)
|
||||
return AfterConversionPass(project).run(builder.result)
|
||||
if (postProcessor != null) {
|
||||
return AfterConversionPass(project, postProcessor).run(builder.result)
|
||||
}
|
||||
else {
|
||||
return builder.result
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertTopElement(element: PsiElement?): Element? = when (element) {
|
||||
|
||||
@@ -87,7 +87,7 @@ public object JavaToKotlinTranslator {
|
||||
fun generateKotlinCode(javaCode: String): String {
|
||||
val file = createFile(javaCode)
|
||||
if (file is PsiJavaFile) {
|
||||
val converter = Converter.create(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)))
|
||||
val converter = Converter.create(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)), null)
|
||||
return prettify(converter.elementToKotlin(file))
|
||||
}
|
||||
return ""
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.jet.j2k.visitors
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.jet.j2k.ast.*
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
|
||||
@@ -187,7 +186,7 @@ open class ExpressionVisitor(private val converter: Converter) : JavaElementVisi
|
||||
val arguments = expression.getArgumentList().getExpressions()
|
||||
val target = methodExpr.resolve()
|
||||
val isNullable = if (target is PsiMethod) typeConverter.methodNullability(target).isNullable(converter.settings) else false
|
||||
val typeArguments = typeConverter.convertTypes(expression.getTypeArguments())
|
||||
val typeArguments = convertTypeArguments(expression)
|
||||
|
||||
if (target is KotlinLightMethod) {
|
||||
val origin = target.origin
|
||||
@@ -250,7 +249,7 @@ open class ExpressionVisitor(private val converter: Converter) : JavaElementVisi
|
||||
if (target is PsiMethod) {
|
||||
val specialMethod = SpecialMethod.values().firstOrNull { it.matches(target) }
|
||||
if (specialMethod != null && arguments.size == specialMethod.parameterCount) {
|
||||
val converted = specialMethod.convertCall(methodExpr.getQualifierExpression(), arguments, converter)
|
||||
val converted = specialMethod.convertCall(methodExpr.getQualifierExpression(), arguments, typeArguments, converter)
|
||||
if (converted != null) {
|
||||
result = converted
|
||||
return
|
||||
@@ -264,6 +263,27 @@ open class ExpressionVisitor(private val converter: Converter) : JavaElementVisi
|
||||
isNullable)
|
||||
}
|
||||
|
||||
private fun convertTypeArguments(call: PsiCallExpression): List<Type> {
|
||||
var typeArgs = call.getTypeArguments().toList()
|
||||
|
||||
// always add explicit type arguments and remove them if they are redundant later
|
||||
if (typeArgs.size == 0) {
|
||||
val resolve = call.resolveMethodGenerics()
|
||||
if (resolve.isValidResult()) {
|
||||
val method = resolve.getElement() as? PsiMethod
|
||||
if (method != null) {
|
||||
val typeParameters = method.getTypeParameters()
|
||||
if (typeParameters.isNotEmpty()) {
|
||||
val map = resolve.getSubstitutor().getSubstitutionMap()
|
||||
typeArgs = typeParameters.map { map[it] ?: return listOf() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return typeArgs.map { typeConverter.convertType(it).assignNoPrototype() }
|
||||
}
|
||||
|
||||
override fun visitNewExpression(expression: PsiNewExpression) {
|
||||
if (expression.getArrayInitializer() != null) {
|
||||
result = converter.convertExpression(expression.getArrayInitializer())
|
||||
|
||||
@@ -27,55 +27,53 @@ import com.intellij.psi.PsiSuperExpression
|
||||
import org.jetbrains.jet.j2k.ast.QualifiedExpression
|
||||
import org.jetbrains.jet.j2k.ast.Identifier
|
||||
import org.jetbrains.jet.j2k.ast.assignNoPrototype
|
||||
import org.jetbrains.jet.j2k.ast.Type
|
||||
|
||||
enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String, val parameterCount: Int) {
|
||||
OBJECT_EQUALS: SpecialMethod(null, "equals", 1) {
|
||||
override fun matches(method: PsiMethod)
|
||||
= super.matches(method) && method.getParameterList().getParameters().single().getType().getCanonicalText() == JAVA_LANG_OBJECT
|
||||
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, converter: Converter): Expression? {
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, converter: Converter): Expression? {
|
||||
if (qualifier == null || qualifier is PsiSuperExpression) return null
|
||||
return BinaryExpression(converter.convertExpression(qualifier), converter.convertExpression(arguments.single()), "==")
|
||||
}
|
||||
}
|
||||
|
||||
OBJECT_GET_CLASS: SpecialMethod("java.lang.Object", "getClass", 0) {
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, converter: Converter): Expression {
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, converter: Converter): Expression {
|
||||
val identifier = Identifier("javaClass", false).assignNoPrototype()
|
||||
return if (qualifier != null) QualifiedExpression(converter.convertExpression(qualifier), identifier) else identifier
|
||||
}
|
||||
}
|
||||
|
||||
OBJECTS_EQUALS: SpecialMethod("java.util.Objects", "equals", 2) {
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, converter: Converter)
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, converter: Converter)
|
||||
= BinaryExpression(converter.convertExpression(arguments[0]), converter.convertExpression(arguments[1]), "==")
|
||||
}
|
||||
|
||||
//TODO: type arguments maybe required if we are in initializer of variable with no explicit type
|
||||
COLLECTIONS_EMPTY_LIST: SpecialMethod("java.util.Collections", "emptyList", 0) {
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, converter: Converter)
|
||||
= MethodCallExpression.build(null, "listOf", listOf(), listOf(), false)
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, converter: Converter)
|
||||
= MethodCallExpression.build(null, "listOf", listOf(), typeArgumentsConverted, false)
|
||||
}
|
||||
|
||||
//TODO: type arguments maybe required if we are in initializer of variable with no explicit type
|
||||
COLLECTIONS_EMPTY_SET: SpecialMethod("java.util.Collections", "emptySet", 0) {
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, converter: Converter)
|
||||
= MethodCallExpression.build(null, "setOf", listOf(), listOf(), false)
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, converter: Converter)
|
||||
= MethodCallExpression.build(null, "setOf", listOf(), typeArgumentsConverted, false)
|
||||
}
|
||||
|
||||
//TODO: type arguments maybe required if we are in initializer of variable with no explicit type
|
||||
COLLECTIONS_EMPTY_MAP: SpecialMethod("java.util.Collections", "emptyMap", 0) {
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, converter: Converter)
|
||||
= MethodCallExpression.build(null, "mapOf", listOf(), listOf(), false)
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, converter: Converter)
|
||||
= MethodCallExpression.build(null, "mapOf", listOf(), typeArgumentsConverted, false)
|
||||
}
|
||||
|
||||
COLLECTIONS_SINGLETON_LIST: SpecialMethod("java.util.Collections", "singletonList", 1) {
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, converter: Converter)
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, converter: Converter)
|
||||
= MethodCallExpression.build(null, "listOf", listOf(converter.convertExpression(arguments.single())), listOf(), false)
|
||||
}
|
||||
|
||||
COLLECTIONS_SINGLETON: SpecialMethod("java.util.Collections", "singleton", 1) {
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, converter: Converter)
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, converter: Converter)
|
||||
= MethodCallExpression.build(null, "setOf", listOf(converter.convertExpression(arguments.single())), listOf(), false)
|
||||
}
|
||||
|
||||
@@ -85,5 +83,5 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String
|
||||
return method.getParameterList().getParametersCount() == parameterCount
|
||||
}
|
||||
|
||||
abstract fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, converter: Converter): Expression?
|
||||
abstract fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, converter: Converter): Expression?
|
||||
}
|
||||
@@ -23,9 +23,6 @@ import org.jetbrains.jet.j2k.JavaToKotlinTranslator
|
||||
import org.jetbrains.jet.j2k.ConverterSettings
|
||||
import java.util.regex.Pattern
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import com.intellij.testFramework.LightIdeaTestCase
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import org.jetbrains.jet.JetTestUtils
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -33,8 +30,12 @@ import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import org.jetbrains.jet.test.util.trimIndent
|
||||
import org.jetbrains.jet.j2k.FilesConversionScope
|
||||
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor
|
||||
|
||||
abstract class AbstractJavaToKotlinConverterTest() : LightIdeaTestCase() {
|
||||
abstract class AbstractJavaToKotlinConverterTest() : LightCodeInsightFixtureTestCase() {
|
||||
val testHeaderPattern = Pattern.compile("//(element|expression|statement|method|class|file|comp)\n")
|
||||
|
||||
override fun setUp() {
|
||||
@@ -122,14 +123,14 @@ abstract class AbstractJavaToKotlinConverterTest() : LightIdeaTestCase() {
|
||||
|
||||
private fun elementToKotlin(text: String, settings: ConverterSettings, project: Project): String {
|
||||
val fileWithText = JavaToKotlinTranslator.createFile(project, text)
|
||||
val converter = Converter.create(project, settings, FilesConversionScope(listOf(fileWithText)))
|
||||
val converter = Converter.create(project, settings, FilesConversionScope(listOf(fileWithText)), J2kPostProcessor)
|
||||
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.create(project, settings, FilesConversionScope(listOf(file)))
|
||||
val converter = Converter.create(project, settings, FilesConversionScope(listOf(file)), J2kPostProcessor)
|
||||
return converter.elementToKotlin(file)
|
||||
}
|
||||
|
||||
@@ -148,9 +149,8 @@ abstract class AbstractJavaToKotlinConverterTest() : LightIdeaTestCase() {
|
||||
return result.replaceFirst("val o:Any\\? = ", "").replaceFirst("val o:Any = ", "").replaceFirst("val o = ", "").trim()
|
||||
}
|
||||
|
||||
override fun getProjectJDK(): Sdk? {
|
||||
return PluginTestCaseBase.jdkFromIdeaHome()
|
||||
}
|
||||
override fun getProjectDescriptor()
|
||||
= JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||
|
||||
private fun String.removeFirstLine(): String {
|
||||
val lastNewLine = indexOf('\n')
|
||||
|
||||
@@ -16,17 +16,14 @@
|
||||
|
||||
package org.jetbrains.jet.j2k.test;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.test.InnerTestClasses;
|
||||
import org.jetbrains.jet.test.TestMetadata;
|
||||
|
||||
import org.jetbrains.jet.j2k.test.AbstractJavaToKotlinConverterTest;
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@@ -3128,6 +3125,11 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv
|
||||
doTest("j2k/tests/testData/ast/typeParameters/methodDoubleParametrizationWithTwoBounds.java");
|
||||
}
|
||||
|
||||
@TestMetadata("needTypeArgs.java")
|
||||
public void testNeedTypeArgs() throws Exception {
|
||||
doTest("j2k/tests/testData/ast/typeParameters/needTypeArgs.java");
|
||||
}
|
||||
|
||||
@TestMetadata("traitDoubleParametrizationWithTwoBoundsWithExtending.java")
|
||||
public void testTraitDoubleParametrizationWithTwoBoundsWithExtending() throws Exception {
|
||||
doTest("j2k/tests/testData/ast/typeParameters/traitDoubleParametrizationWithTwoBoundsWithExtending.java");
|
||||
|
||||
@@ -1 +1 @@
|
||||
val a = array<Double>(1.0, 2.0, 3.0)
|
||||
val a = array(1.0, 2.0, 3.0)
|
||||
@@ -1 +1 @@
|
||||
val a = array<IntArray>(intArray(1, 2, 3), intArray(4, 5, 6), intArray(7, 8, 9))
|
||||
val a = array(intArray(1, 2, 3), intArray(4, 5, 6), intArray(7, 8, 9))
|
||||
+1
-1
@@ -1 +1 @@
|
||||
val d2 = Array<IntArray>(5, { IntArray(5) })
|
||||
val d2 = Array(5, { IntArray(5) })
|
||||
@@ -1 +1 @@
|
||||
val sss = Array<Array<Array<String>>>(5, { Array<Array<String>>(5, { arrayOfNulls<String>(5) }) })
|
||||
val sss = Array(5, { Array<Array<String>>(5, { arrayOfNulls<String>(5) }) })
|
||||
@@ -1 +1 @@
|
||||
val a = array<String>("abc")
|
||||
val a = array("abc")
|
||||
@@ -25,9 +25,9 @@ public class Identifier<T>(private val myName: T, private val myHasDollar: Boole
|
||||
public class User {
|
||||
class object {
|
||||
public fun main() {
|
||||
val i1 = Identifier<String>("name", false, true)
|
||||
val i1 = Identifier("name", false, true)
|
||||
val i2 = Identifier<String>("name", false)
|
||||
val i3 = Identifier<String>("name")
|
||||
val i3 = Identifier("name")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,12 @@ import kotlin.List
|
||||
|
||||
class A {
|
||||
private val field1 = ArrayList<String>()
|
||||
val field2: List<String> = ArrayList<String>()
|
||||
val field2: List<String> = ArrayList()
|
||||
public val field3: Int = 0
|
||||
protected val field4: Int = 0
|
||||
|
||||
private var field5: List<String> = ArrayList<String>()
|
||||
var field6: List<String> = ArrayList<String>()
|
||||
private var field5: List<String> = ArrayList()
|
||||
var field6: List<String> = ArrayList()
|
||||
|
||||
private var field7 = 0
|
||||
var field8 = 0
|
||||
|
||||
@@ -3,6 +3,6 @@ package demo
|
||||
class Test {
|
||||
fun test(vararg args: Any) {
|
||||
var args = args
|
||||
args = array<Int>(1, 2, 3)
|
||||
args = array(1, 2, 3)
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,6 @@ public class Java {
|
||||
fun test2() {
|
||||
val m = HashMap()
|
||||
val g = G("")
|
||||
val g2 = G<String>("")
|
||||
val g2 = G("")
|
||||
}
|
||||
}
|
||||
@@ -25,9 +25,9 @@ public class Identifier<T>(private val myName: T, private val myHasDollar: Boole
|
||||
public class User {
|
||||
class object {
|
||||
public fun main(args: Array<String>) {
|
||||
val i1 = Identifier<String>("name", false, true)
|
||||
val i1 = Identifier("name", false, true)
|
||||
val i2 = Identifier<String>("name", false)
|
||||
val i3 = Identifier<String>("name")
|
||||
val i3 = Identifier("name")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ import java.util.*
|
||||
import kotlin.List
|
||||
|
||||
class A {
|
||||
var list: List<String> = ArrayList<String>()
|
||||
var list: List<String> = ArrayList()
|
||||
}
|
||||
@@ -2,6 +2,6 @@ import kotlinApi.*
|
||||
|
||||
class C {
|
||||
fun foo() {
|
||||
val v = globalGenericFunction<Int>(1)
|
||||
val v = globalGenericFunction(1)
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,9 @@ import kotlin.Map
|
||||
|
||||
class A {
|
||||
fun foo(): Map<String, String> {
|
||||
val list1 = listOf()
|
||||
val list1 = listOf<String>()
|
||||
val list2 = listOf(1)
|
||||
val set1 = setOf()
|
||||
val set1 = setOf<String>()
|
||||
val set2 = setOf("a")
|
||||
return mapOf()
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ class Collection<E>(e: E) {
|
||||
class Test {
|
||||
fun main() {
|
||||
val raw1 = Collection(1)
|
||||
val raw2 = Collection<Int>(1)
|
||||
val raw3 = Collection<String>("1")
|
||||
val raw2 = Collection(1)
|
||||
val raw3 = Collection("1")
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,6 @@ class U {
|
||||
val t = TestT()
|
||||
t.getT<String>()
|
||||
t.getT<Int>()
|
||||
t.getT()
|
||||
t.getT<Any>()
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,8 @@ import java.util.*
|
||||
import kotlin.List
|
||||
|
||||
class A {
|
||||
private val field1: List<String> = ArrayList<String>()
|
||||
val field2: List<String> = ArrayList<String>()
|
||||
private val field1: List<String> = ArrayList()
|
||||
val field2: List<String> = ArrayList()
|
||||
public val field3: Int = 0
|
||||
protected val field4: Int = 0
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class A {
|
||||
void foo() {
|
||||
Map<String, Integer> map1 = getMap1();
|
||||
Map<String, Integer> map2 = getMap2("a", 1);
|
||||
}
|
||||
|
||||
<K, V> Map<K, V> getMap1() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
<K, V> Map<K, V> getMap2(K k, V v) {
|
||||
HashMap<K, V> map = new HashMap<>();
|
||||
map.put(k, v);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import java.util.HashMap
|
||||
|
||||
class A {
|
||||
fun foo() {
|
||||
val map1 = getMap1<String, Int>()
|
||||
val map2 = getMap2("a", 1)
|
||||
}
|
||||
|
||||
fun <K, V> getMap1(): Map<K, V> {
|
||||
return HashMap()
|
||||
}
|
||||
|
||||
fun <K, V> getMap2(k: K, v: V): Map<K, V> {
|
||||
val map = HashMap<K, V>()
|
||||
map.put(k, v)
|
||||
return map
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user