J2K: replace overloads with optional parameters not only for constructors but for methods too
This commit is contained in:
@@ -49,8 +49,12 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
||||
public fun convertBody(): ClassBody {
|
||||
processAccessorsToDrop()
|
||||
|
||||
val overloadReducer = OverloadReducer(psiClass.getMethods().filter { it !in membersToRemove } /* do not allow OverloadReducer to use accessors converted to properties */,
|
||||
isOpenClass,
|
||||
converter.referenceSearcher)
|
||||
|
||||
val constructorConverter = if (psiClass.getName() != null && !isObject)
|
||||
ConstructorConverter(psiClass, converter, fieldCorrections)
|
||||
ConstructorConverter(psiClass, converter, fieldCorrections, overloadReducer)
|
||||
else
|
||||
null
|
||||
|
||||
@@ -59,8 +63,9 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
||||
if (element is PsiMember) {
|
||||
if (element is PsiAnnotationMethod) continue // converted in convertAnnotationType()
|
||||
if (isObject && element.isConstructor()) continue // no constructor in object
|
||||
if (element is PsiMethod && overloadReducer.shouldDropMethod(element)) continue
|
||||
|
||||
val converted = converter.convertMember(element, membersToRemove, constructorConverter)
|
||||
val converted = converter.convertMember(element, membersToRemove, constructorConverter, overloadReducer)
|
||||
if (converted != null) {
|
||||
convertedMembers.put(element, converted)
|
||||
}
|
||||
@@ -88,7 +93,7 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
||||
}
|
||||
}
|
||||
|
||||
return ClassBody(null, null, convertedMembers.values().toList(), emptyList(), lBrace, rBrace)
|
||||
return ClassBody(null, null, convertedMembers.values().toList(), emptyList(), lBrace, rBrace, overloadReducer)
|
||||
}
|
||||
|
||||
val useCompanionObject = shouldGenerateCompanionObject(convertedMembers)
|
||||
@@ -123,14 +128,15 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
||||
primaryConstructorSignature = null // no "()" after class name is needed in this case
|
||||
}
|
||||
|
||||
return ClassBody(primaryConstructorSignature, constructorConverter?.baseClassParams, members, companionObjectMembers, lBrace, rBrace)
|
||||
return ClassBody(primaryConstructorSignature, constructorConverter?.baseClassParams, members, companionObjectMembers, lBrace, rBrace, overloadReducer)
|
||||
}
|
||||
|
||||
private fun Converter.convertMember(member: PsiMember,
|
||||
membersToRemove: MutableSet<PsiMember>,
|
||||
constructorConverter: ConstructorConverter?): Member? {
|
||||
constructorConverter: ConstructorConverter?,
|
||||
overloadReducer: OverloadReducer): Member? {
|
||||
return when (member) {
|
||||
is PsiMethod -> convertMethod(member, membersToRemove, constructorConverter, isOpenClass)
|
||||
is PsiMethod -> convertMethod(member, membersToRemove, constructorConverter, overloadReducer, isOpenClass)
|
||||
is PsiField -> convertField(member, fieldCorrections[member])
|
||||
is PsiClass -> convertClass(member)
|
||||
is PsiClassInitializer -> convertInitializer(member)
|
||||
|
||||
@@ -27,9 +27,10 @@ import java.util.HashSet
|
||||
class ConstructorConverter(
|
||||
private val psiClass: PsiClass,
|
||||
private val converter: Converter,
|
||||
private val fieldCorrections: Map<PsiField, FieldCorrectionInfo>
|
||||
private val fieldCorrections: Map<PsiField, FieldCorrectionInfo>,
|
||||
private val overloadReducer: OverloadReducer
|
||||
) {
|
||||
private val constructors = psiClass.getConstructors()
|
||||
private val constructors = psiClass.getConstructors().asList()
|
||||
|
||||
private val toTargetConstructorMap = buildToTargetConstructorMap()
|
||||
|
||||
@@ -43,29 +44,12 @@ class ConstructorConverter(
|
||||
val candidates = constructors.filter { it !in toTargetConstructorMap }
|
||||
if (candidates.size() != 1) return null // there should be only one constructor which does not call other constructor
|
||||
val primary = candidates.single()
|
||||
if (toTargetConstructorMap.values().any() { it.constructor != primary }) return null // all other constructors call our candidate (directly or indirectly)
|
||||
if (toTargetConstructorMap.values().any() { it != primary }) return null // all other constructors call our candidate (directly or indirectly)
|
||||
return primary
|
||||
}
|
||||
|
||||
private class TargetConstructorInfo(
|
||||
/**
|
||||
* Target constructor (one which is finally invoked by this one)
|
||||
*/
|
||||
val constructor: PsiMethod,
|
||||
/**
|
||||
* Is not null if this constructor is equivalent to the target constructor with a few last parameters having default values
|
||||
*/
|
||||
val parameterDefaults: List<PsiExpression>?)
|
||||
|
||||
private val constructorsToDrop = HashSet<PsiMethod>()
|
||||
private val lastParamDefaults = HashMap<PsiMethod, ArrayList<PsiExpression>>() // defaults for a few last parameters in reverse order
|
||||
|
||||
init {
|
||||
dropConstructorsForDefaultValues()
|
||||
}
|
||||
|
||||
private fun buildToTargetConstructorMap(): Map<PsiMethod, TargetConstructorInfo> {
|
||||
val toTargetConstructorMap = HashMap<PsiMethod, TargetConstructorInfo>()
|
||||
private fun buildToTargetConstructorMap(): Map<PsiMethod, PsiMethod> {
|
||||
val toTargetConstructorMap = HashMap<PsiMethod, PsiMethod>()
|
||||
for (constructor in constructors) {
|
||||
val firstStatement = constructor.getBody()?.getStatements()?.firstOrNull()
|
||||
val methodCall = (firstStatement as? PsiExpressionStatement)?.getExpression() as? PsiMethodCallExpression
|
||||
@@ -74,25 +58,11 @@ class ConstructorConverter(
|
||||
if (refExpr.getCanonicalText() == "this") {
|
||||
val target = refExpr.resolve() as? PsiMethod
|
||||
if (target != null && target.isConstructor()) {
|
||||
var parameterDefaults = calcTargetParameterDefaults(constructor, target, methodCall)
|
||||
|
||||
val finalTargetInfo = toTargetConstructorMap[target]
|
||||
if (finalTargetInfo != null && parameterDefaults != null) {
|
||||
parameterDefaults = if (finalTargetInfo.parameterDefaults != null)
|
||||
parameterDefaults!! + finalTargetInfo.parameterDefaults
|
||||
else
|
||||
null
|
||||
}
|
||||
val finalTarget = finalTargetInfo?.constructor ?: target
|
||||
|
||||
toTargetConstructorMap[constructor] = TargetConstructorInfo(finalTarget, parameterDefaults)
|
||||
val finalTarget = toTargetConstructorMap[target] ?: target
|
||||
toTargetConstructorMap[constructor] = finalTarget
|
||||
for (entry in toTargetConstructorMap.entrySet()) {
|
||||
if (entry.value.constructor == constructor) {
|
||||
val newParameterDefaults = if (parameterDefaults != null)
|
||||
entry.value.parameterDefaults?.plus(parameterDefaults!!)
|
||||
else
|
||||
null
|
||||
entry.setValue(TargetConstructorInfo(finalTarget, newParameterDefaults))
|
||||
if (entry.value == constructor) {
|
||||
entry.setValue(finalTarget)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,61 +72,6 @@ class ConstructorConverter(
|
||||
return toTargetConstructorMap
|
||||
}
|
||||
|
||||
private fun calcTargetParameterDefaults(constructor: PsiMethod, target: PsiMethod, targetCall: PsiMethodCallExpression): List<PsiExpression>? {
|
||||
if (constructor.getBody()!!.getStatements().size() != 1) return null // constructor's body should consist of only "this(...)"
|
||||
val parameters = constructor.getParameterList().getParameters()
|
||||
val targetParameters = target.getParameterList().getParameters()
|
||||
if (parameters.size() >= targetParameters.size()) return null
|
||||
val args = targetCall.getArgumentList().getExpressions()
|
||||
if (args.size() != targetParameters.size()) return null // incorrect code
|
||||
|
||||
for (i in parameters.indices) {
|
||||
val parameter = parameters[i]
|
||||
val targetParameter = targetParameters[i]
|
||||
if (parameter.getName() != targetParameter.getName() || parameter.getType() != targetParameter.getType()) return null
|
||||
val arg = args[i]
|
||||
if (arg !is PsiReferenceExpression || arg.resolve() != parameter) return null
|
||||
}
|
||||
|
||||
return args.drop(parameters.size())
|
||||
}
|
||||
|
||||
private fun dropConstructorsForDefaultValues() {
|
||||
val dropCandidates = toTargetConstructorMap
|
||||
.filter {
|
||||
it.value.parameterDefaults != null
|
||||
&& it.key.accessModifier() == it.value.constructor.accessModifier()
|
||||
&& it.key.getModifierList().getAnnotations().isEmpty() /* do not drop constructors with annotations */
|
||||
}
|
||||
.map { it.key }
|
||||
.sortBy { -it.getParameterList().getParametersCount() } // we will try to drop them starting from ones with more parameters
|
||||
|
||||
@DropCandidatesLoop
|
||||
for (constructor in dropCandidates) {
|
||||
val paramCount = constructor.getParameterList().getParametersCount()
|
||||
val targetInfo = toTargetConstructorMap[constructor]!!
|
||||
val targetConstructor = targetInfo.constructor
|
||||
val targetParamCount = targetConstructor.getParameterList().getParametersCount()
|
||||
assert(paramCount < targetParamCount)
|
||||
val defaults = targetInfo.parameterDefaults!!
|
||||
assert(defaults.size() == targetParamCount - paramCount)
|
||||
|
||||
val targetDefaults = lastParamDefaults.getOrPut(targetConstructor, { ArrayList() })
|
||||
|
||||
for (i in defaults.indices) {
|
||||
val default = defaults[defaults.size() - i - 1]
|
||||
if (i < targetDefaults.size()) { // default for this parameter has already been assigned
|
||||
if (targetDefaults[i].getText() != default.getText()) continue@DropCandidatesLoop
|
||||
}
|
||||
else {
|
||||
targetDefaults.add(default)
|
||||
}
|
||||
}
|
||||
|
||||
constructorsToDrop.add(constructor)
|
||||
}
|
||||
}
|
||||
|
||||
public var baseClassParams: List<DeferredElement<Expression>>? = if (constructors.isEmpty()) emptyList() else null
|
||||
private set
|
||||
|
||||
@@ -169,10 +84,9 @@ class ConstructorConverter(
|
||||
convertPrimaryConstructor(annotations, modifiers, membersToRemove, postProcessBody)
|
||||
}
|
||||
else {
|
||||
if (constructor in constructorsToDrop) return null
|
||||
if (overloadReducer.shouldDropMethod(constructor)) return null
|
||||
|
||||
val params = convertParameterList(constructor, converter,
|
||||
{ parameter, default -> converter.convertParameter(parameter, defaultValue = default) })
|
||||
val params = converter.convertParameterList(constructor, overloadReducer)
|
||||
|
||||
val thisOrSuper = findThisOrSuperCall(constructor)
|
||||
val thisOrSuperDeferred = if (thisOrSuper != null)
|
||||
@@ -193,14 +107,6 @@ class ConstructorConverter(
|
||||
|
||||
SecondaryConstructor(annotations, modifiers, params, converter.deferredElement(::convertBody), thisOrSuperDeferred)
|
||||
}
|
||||
|
||||
if (result.parameterList.parameters.any { it.defaultValue != null }) {
|
||||
result.annotations += Annotations(listOf(Annotation(Identifier("overloads").assignNoPrototype(),
|
||||
listOf(),
|
||||
brackets = result is PrimaryConstructor,
|
||||
newLineAfter = false).assignNoPrototype())).assignNoPrototype()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -288,53 +194,34 @@ class ConstructorConverter(
|
||||
baseClassParams = emptyList()
|
||||
}
|
||||
|
||||
val parameterList = convertParameterList(primaryConstructor,
|
||||
correctedConverter,
|
||||
{ parameter, default ->
|
||||
if (!parameterToField.containsKey(parameter)) {
|
||||
correctedConverter.convertParameter(parameter, defaultValue = default)
|
||||
}
|
||||
else {
|
||||
val (field, type) = parameterToField[parameter]!!
|
||||
val fieldCorrection = fieldCorrections[field]
|
||||
val name = fieldCorrection?.identifier ?: field.declarationIdentifier()
|
||||
val accessModifiers = if (fieldCorrection != null)
|
||||
Modifiers(listOf()).with(fieldCorrection.access).assignNoPrototype()
|
||||
else
|
||||
converter.convertModifiers(field).filter { it in ACCESS_MODIFIERS }
|
||||
Parameter(name,
|
||||
type,
|
||||
if (isVal(converter.referenceSearcher, field)) Parameter.VarValModifier.Val else Parameter.VarValModifier.Var,
|
||||
converter.convertAnnotations(parameter) + converter.convertAnnotations(field),
|
||||
accessModifiers,
|
||||
default).assignPrototypes(listOf(parameter, field), CommentsAndSpacesInheritance(blankLinesBefore = false))
|
||||
}
|
||||
},
|
||||
correctCodeConverter = { correct() })
|
||||
val parameterList = correctedConverter.convertParameterList(
|
||||
primaryConstructor,
|
||||
overloadReducer,
|
||||
{ parameter, default ->
|
||||
if (!parameterToField.containsKey(parameter)) {
|
||||
correctedConverter.convertParameter(parameter, defaultValue = default)
|
||||
}
|
||||
else {
|
||||
val (field, type) = parameterToField[parameter]!!
|
||||
val fieldCorrection = fieldCorrections[field]
|
||||
val name = fieldCorrection?.identifier ?: field.declarationIdentifier()
|
||||
val accessModifiers = if (fieldCorrection != null)
|
||||
Modifiers(listOf()).with(fieldCorrection.access).assignNoPrototype()
|
||||
else
|
||||
converter.convertModifiers(field).filter { it in ACCESS_MODIFIERS }
|
||||
Parameter(name,
|
||||
type,
|
||||
if (isVal(converter.referenceSearcher, field)) Parameter.VarValModifier.Val else Parameter.VarValModifier.Var,
|
||||
converter.convertAnnotations(parameter) + converter.convertAnnotations(field),
|
||||
accessModifiers,
|
||||
default).assignPrototypes(listOf(parameter, field), CommentsAndSpacesInheritance(blankLinesBefore = false))
|
||||
}
|
||||
},
|
||||
correctCodeConverter = { correct() })
|
||||
|
||||
return PrimaryConstructor(annotations, modifiers, parameterList, converter.deferredElement(bodyGenerator)).assignPrototype(primaryConstructor)
|
||||
}
|
||||
|
||||
private fun convertParameterList(
|
||||
constructor: PsiMethod,
|
||||
converter: Converter,
|
||||
convertParameter: (parameter: PsiParameter, default: DeferredElement<Expression>?) -> Parameter,
|
||||
correctCodeConverter: CodeConverter.() -> CodeConverter = { this }
|
||||
): ParameterList {
|
||||
val parameterList = constructor.getParameterList()
|
||||
val params = parameterList.getParameters()
|
||||
val defaults = lastParamDefaults[constructor] ?: emptyList<PsiExpression>()
|
||||
return ParameterList(params.indices.map { i ->
|
||||
val parameter = params[i]
|
||||
val indexFromEnd = params.size() - i - 1
|
||||
val defaultValue = if (indexFromEnd < defaults.size())
|
||||
converter.deferredElement { codeConverter -> codeConverter.correctCodeConverter().convertExpression(defaults[indexFromEnd], parameter.getType()) }
|
||||
else
|
||||
null
|
||||
convertParameter(parameter, defaultValue)
|
||||
}).assignPrototype(parameterList)
|
||||
}
|
||||
|
||||
private fun findBackingFieldForConstructorParameter(parameter: PsiParameter, constructor: PsiMethod): Pair<PsiField, PsiStatement>? {
|
||||
val body = constructor.getBody() ?: return null
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k
|
||||
|
||||
import com.google.common.collect.Multimap
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.CommonClassNames.*
|
||||
@@ -32,6 +31,7 @@ import org.jetbrains.kotlin.j2k.usageProcessing.UsageProcessing
|
||||
import org.jetbrains.kotlin.j2k.usageProcessing.UsageProcessingExpressionConverter
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions.*
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
|
||||
class Converter private(
|
||||
private val elementToConvert: PsiElement,
|
||||
@@ -62,7 +62,9 @@ class Converter private(
|
||||
public fun create(elementToConvert: PsiElement, settings: ConverterSettings, inConversionScope: (PsiElement) -> Boolean,
|
||||
referenceSearcher: ReferenceSearcher, resolverForConverter: ResolverForConverter,
|
||||
usageProcessingsCollector: (UsageProcessing) -> Unit): Converter {
|
||||
return Converter(elementToConvert, settings, inConversionScope, referenceSearcher, resolverForConverter, CommonState(usageProcessingsCollector), PersonalState(null))
|
||||
return Converter(elementToConvert, settings, inConversionScope,
|
||||
CachingReferenceSearcher(referenceSearcher),
|
||||
resolverForConverter, CommonState(usageProcessingsCollector), PersonalState(null))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +100,7 @@ class Converter private(
|
||||
private fun convertTopElement(element: PsiElement): Element? = when (element) {
|
||||
is PsiJavaFile -> convertFile(element)
|
||||
is PsiClass -> convertClass(element)
|
||||
is PsiMethod -> convertMethod(element, null, null, false)
|
||||
is PsiMethod -> convertMethod(element, null, null, null, false)
|
||||
is PsiField -> convertField(element, null)
|
||||
is PsiStatement -> createDefaultCodeConverter().convertStatement(element)
|
||||
is PsiExpression -> createDefaultCodeConverter().convertExpression(element)
|
||||
@@ -274,7 +276,8 @@ class Converter private(
|
||||
|
||||
// to convert fields and nested types - they are not allowed in Kotlin but we convert them and let user refactor code
|
||||
var classBody = ClassBodyConverter(psiClass, this, isOpenClass = false, isObject = false).convertBody()
|
||||
classBody = ClassBody(constructorSignature, classBody.baseClassParams, classBody.members, classBody.companionObjectMembers, classBody.lBrace, classBody.rBrace)
|
||||
classBody = ClassBody(constructorSignature, classBody.baseClassParams, classBody.members,
|
||||
classBody.companionObjectMembers, classBody.lBrace, classBody.rBrace, classBody.overloadReducer)
|
||||
|
||||
val annotationAnnotation = Annotation(Identifier("annotation").assignNoPrototype(), listOf(), false, false).assignNoPrototype()
|
||||
return Class(psiClass.declarationIdentifier(),
|
||||
@@ -348,10 +351,13 @@ class Converter private(
|
||||
return if (convertedType == initializerType) null else convertedType
|
||||
}
|
||||
|
||||
public fun convertMethod(method: PsiMethod,
|
||||
membersToRemove: MutableSet<PsiMember>?,
|
||||
constructorConverter: ConstructorConverter?,
|
||||
isInOpenClass: Boolean): Member? {
|
||||
public fun convertMethod(
|
||||
method: PsiMethod,
|
||||
membersToRemove: MutableSet<PsiMember>?,
|
||||
constructorConverter: ConstructorConverter?,
|
||||
overloadReducer: OverloadReducer?,
|
||||
isInOpenClass: Boolean
|
||||
): FunctionLike? {
|
||||
val returnType = typeConverter.convertMethodReturnType(method)
|
||||
|
||||
val annotations = convertAnnotations(method) + convertThrows(method)
|
||||
@@ -401,7 +407,8 @@ class Converter private(
|
||||
}
|
||||
}
|
||||
|
||||
var params = convertParameterList(method.getParameterList())
|
||||
var params = convertParameterList(method, overloadReducer)
|
||||
|
||||
val typeParameterList = convertTypeParameterList(method.getTypeParameterList())
|
||||
var body = deferredElement { codeConverter: CodeConverter ->
|
||||
val body = codeConverter.withMethodReturnType(method.getReturnType()).convertBlock(method.getBody())
|
||||
@@ -410,7 +417,17 @@ class Converter private(
|
||||
Function(method.declarationIdentifier(), annotations, modifiers, returnType, typeParameterList, params, body, containingClass?.isInterface() ?: false)
|
||||
}
|
||||
|
||||
return function?.assignPrototype(method)
|
||||
if (function == null) return null
|
||||
|
||||
if (function.parameterList.parameters.any { it.defaultValue != null }) {
|
||||
function.annotations += Annotations(
|
||||
listOf(Annotation(Identifier("overloads").assignNoPrototype(),
|
||||
listOf(),
|
||||
brackets = function is PrimaryConstructor,
|
||||
newLineAfter = false).assignNoPrototype())).assignNoPrototype()
|
||||
}
|
||||
|
||||
return function.assignPrototype(method)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -507,14 +524,13 @@ class Converter private(
|
||||
private fun convertToNotNullableTypes(types: Array<out PsiType?>): List<Type>
|
||||
= types.map { typeConverter.convertType(it, Nullability.NotNull) }
|
||||
|
||||
private fun convertParameterList(parameterList: PsiParameterList): ParameterList
|
||||
= ParameterList(parameterList.getParameters().map { convertParameter(it) }).assignPrototype(parameterList)
|
||||
|
||||
public fun convertParameter(parameter: PsiParameter,
|
||||
nullability: Nullability = Nullability.Default,
|
||||
varValModifier: Parameter.VarValModifier = Parameter.VarValModifier.None,
|
||||
modifiers: Modifiers = Modifiers.Empty,
|
||||
defaultValue: DeferredElement<Expression>? = null): Parameter {
|
||||
public fun convertParameter(
|
||||
parameter: PsiParameter,
|
||||
nullability: Nullability = Nullability.Default,
|
||||
varValModifier: Parameter.VarValModifier = Parameter.VarValModifier.None,
|
||||
modifiers: Modifiers = Modifiers.Empty,
|
||||
defaultValue: DeferredElement<Expression>? = null
|
||||
): Parameter {
|
||||
var type = typeConverter.convertVariableType(parameter)
|
||||
when (nullability) {
|
||||
Nullability.NotNull -> type = type.toNotNullType()
|
||||
@@ -555,6 +571,27 @@ class Converter private(
|
||||
val annotation = Annotation(Identifier("throws").assignNoPrototype(), arguments, false, true)
|
||||
return Annotations(listOf(annotation.assignPrototype(throwsList))).assignPrototype(throwsList)
|
||||
}
|
||||
|
||||
private class CachingReferenceSearcher(private val searcher: ReferenceSearcher) : ReferenceSearcher by searcher {
|
||||
private val hasInheritorsCached = HashMap<PsiClass, Boolean>()
|
||||
private val hasOverridesCached = HashMap<PsiMethod, Boolean>()
|
||||
|
||||
override fun hasInheritors(`class`: PsiClass): Boolean {
|
||||
val cached = hasInheritorsCached[`class`]
|
||||
if (cached != null) return cached
|
||||
val result = searcher.hasInheritors(`class`)
|
||||
hasInheritorsCached[`class`] = result
|
||||
return result
|
||||
}
|
||||
|
||||
override fun hasOverrides(method: PsiMethod): Boolean {
|
||||
val cached = hasOverridesCached[method]
|
||||
if (cached != null) return cached
|
||||
val result = searcher.hasOverrides(method)
|
||||
hasOverridesCached[method] = result
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val PRIMITIVE_TYPE_CONVERSIONS: Map<String, String> = mapOf(
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.j2k
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.j2k.ast.*
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
import java.util.HashSet
|
||||
|
||||
class OverloadReducer(
|
||||
private val methods: Collection<PsiMethod>,
|
||||
private val isOpenClass: Boolean,
|
||||
private val referenceSearcher: ReferenceSearcher
|
||||
) {
|
||||
private val methodToLastParameterDefaults = HashMap<PsiMethod, ArrayList<PsiExpression>>()
|
||||
private val methodsToDrop = HashSet<PsiMethod>()
|
||||
|
||||
init {
|
||||
val map = buildOverloadEquivalenceMap()
|
||||
dropOverloadsForDefaultValues(map)
|
||||
}
|
||||
|
||||
public fun shouldDropMethod(method: PsiMethod): Boolean = method in methodsToDrop
|
||||
|
||||
public fun parameterDefault(method: PsiMethod, parameterIndex: Int): PsiExpression? {
|
||||
val defaults = methodToLastParameterDefaults[method] ?: return null
|
||||
val index = method.getParameterList().getParametersCount() - parameterIndex - 1
|
||||
return if (index < defaults.size()) defaults[index] else null
|
||||
}
|
||||
|
||||
private class EquivalentOverloadInfo(
|
||||
/**
|
||||
* Target method (one which is finally invoked by this one)
|
||||
*/
|
||||
val method: PsiMethod,
|
||||
/**
|
||||
* This method is equivalent to the target method with a few last parameters having default values
|
||||
*/
|
||||
val parameterDefaults: List<PsiExpression>)
|
||||
|
||||
private fun buildOverloadEquivalenceMap(): Map<PsiMethod, EquivalentOverloadInfo> {
|
||||
val overloadGroups = methods
|
||||
.groupBy { listOf(if (it.isConstructor()) null else it.getName(),
|
||||
it.accessModifier(),
|
||||
it.getReturnType(),
|
||||
it.hasModifierProperty(PsiModifier.STATIC),
|
||||
getAnnotationsFingerprint(it)) }
|
||||
.values()
|
||||
.filter { it.size() > 1 }
|
||||
.map { it.filterNot { shouldSkipOverload(it) } }
|
||||
.filter { it.size() > 1 }
|
||||
|
||||
val map = HashMap<PsiMethod, EquivalentOverloadInfo>()
|
||||
for (group in overloadGroups) {
|
||||
for (method in group) {
|
||||
val overloadInfo = findEquivalentOverload(method, group) ?: continue
|
||||
|
||||
val furtherOverloadInfo = map[overloadInfo.method]
|
||||
val resultOverloadInfo = if (furtherOverloadInfo != null) {
|
||||
EquivalentOverloadInfo(furtherOverloadInfo.method, overloadInfo.parameterDefaults + furtherOverloadInfo.parameterDefaults)
|
||||
}
|
||||
else {
|
||||
overloadInfo
|
||||
}
|
||||
|
||||
map[method] = resultOverloadInfo
|
||||
for (entry in map.entrySet()) {
|
||||
if (entry.value.method == method) {
|
||||
val newParameterDefaults = entry.value.parameterDefaults + resultOverloadInfo.parameterDefaults
|
||||
entry.setValue(EquivalentOverloadInfo(resultOverloadInfo.method, newParameterDefaults))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
private fun shouldSkipOverload(method: PsiMethod): Boolean {
|
||||
if (method.isConstructor()) return false
|
||||
if (method.hasModifierProperty(PsiModifier.ABSTRACT)) return true
|
||||
if (method.hasModifierProperty(PsiModifier.NATIVE)) return true
|
||||
if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) return true
|
||||
if (method.getHierarchicalMethodSignature().getSuperSignatures().isNotEmpty()) return true
|
||||
if (isOpenClass && referenceSearcher.hasOverrides(method)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
private fun findEquivalentOverload(method: PsiMethod, overloads: Collection<PsiMethod>): EquivalentOverloadInfo? {
|
||||
val statement = method.getBody()?.getStatements()?.singleOrNull() ?: return null
|
||||
|
||||
val methodCall = when (statement) {
|
||||
is PsiExpressionStatement -> statement.getExpression()
|
||||
is PsiReturnStatement -> statement.getReturnValue()
|
||||
else -> null
|
||||
} as? PsiMethodCallExpression ?: return null
|
||||
|
||||
val expectedMethodName = if (method.isConstructor()) "this" else method.getName()
|
||||
val refExpr = methodCall.getMethodExpression()
|
||||
if (refExpr.isQualified() || refExpr.getReferenceName() != expectedMethodName) return null
|
||||
|
||||
val target = refExpr.resolve() as? PsiMethod ?: return null
|
||||
if (target !in overloads) return null
|
||||
|
||||
val parameterDefaults = calcTargetParameterDefaults(method, target, methodCall) ?: return null
|
||||
return EquivalentOverloadInfo(target, parameterDefaults)
|
||||
}
|
||||
|
||||
private fun calcTargetParameterDefaults(method: PsiMethod, target: PsiMethod, targetCall: PsiMethodCallExpression): List<PsiExpression>? {
|
||||
val parameters = method.getParameterList().getParameters()
|
||||
val targetParameters = target.getParameterList().getParameters()
|
||||
if (parameters.size() >= targetParameters.size()) return null
|
||||
val args = targetCall.getArgumentList().getExpressions()
|
||||
if (args.size() != targetParameters.size()) return null // incorrect code
|
||||
|
||||
for (i in parameters.indices) {
|
||||
val parameter = parameters[i]
|
||||
val targetParameter = targetParameters[i]
|
||||
if (parameter.getName() != targetParameter.getName() || parameter.getType() != targetParameter.getType()) return null
|
||||
val arg = args[i]
|
||||
if (arg !is PsiReferenceExpression || arg.resolve() != parameter) return null
|
||||
}
|
||||
|
||||
return args.drop(parameters.size())
|
||||
}
|
||||
|
||||
private fun dropOverloadsForDefaultValues(equivalenceMap: Map<PsiMethod, EquivalentOverloadInfo>) {
|
||||
val dropCandidates = equivalenceMap
|
||||
.map { it.key }
|
||||
.sortBy { -it.getParameterList().getParametersCount() } // we will try to drop them starting from ones with more parameters
|
||||
|
||||
@DropCandidatesLoop
|
||||
for (method in dropCandidates) {
|
||||
val paramCount = method.getParameterList().getParametersCount()
|
||||
val targetInfo = equivalenceMap[method]!!
|
||||
val targetParamCount = targetInfo.method.getParameterList().getParametersCount()
|
||||
assert(paramCount < targetParamCount)
|
||||
val defaults = targetInfo.parameterDefaults
|
||||
assert(defaults.size() == targetParamCount - paramCount)
|
||||
|
||||
val targetDefaults = methodToLastParameterDefaults.getOrPut(targetInfo.method, { ArrayList() })
|
||||
|
||||
for (i in defaults.indices) {
|
||||
val default = defaults[defaults.size() - i - 1]
|
||||
if (i < targetDefaults.size()) { // default for this parameter has already been assigned
|
||||
if (targetDefaults[i].getText() != default.getText()) continue@DropCandidatesLoop
|
||||
}
|
||||
else {
|
||||
targetDefaults.add(default)
|
||||
}
|
||||
}
|
||||
|
||||
methodsToDrop.add(method)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAnnotationsFingerprint(method: PsiMethod): Any {
|
||||
return method.getModifierList().getAnnotations().map { it.getText() }
|
||||
}
|
||||
}
|
||||
|
||||
public fun Converter.convertParameterList(
|
||||
method: PsiMethod,
|
||||
overloadReducer: OverloadReducer?,
|
||||
convertParameter: (parameter: PsiParameter, default: DeferredElement<Expression>?) -> Parameter = { parameter, default -> convertParameter(parameter, defaultValue = default) },
|
||||
correctCodeConverter: CodeConverter.() -> CodeConverter = { this }
|
||||
): ParameterList {
|
||||
val parameterList = method.getParameterList()
|
||||
val params = parameterList.getParameters()
|
||||
return ParameterList(params.indices.map { i ->
|
||||
val parameter = params[i]
|
||||
val defaultValue = overloadReducer?.parameterDefault(method, i)
|
||||
val defaultValueConverted = if (defaultValue != null)
|
||||
deferredElement { codeConverter -> codeConverter.correctCodeConverter().convertExpression(defaultValue, parameter.getType()) }
|
||||
else
|
||||
null
|
||||
convertParameter(parameter, defaultValueConverted)
|
||||
}).assignPrototype(parameterList)
|
||||
}
|
||||
@@ -16,7 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import com.intellij.psi.PsiExpression
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.OverloadReducer
|
||||
import org.jetbrains.kotlin.j2k.append
|
||||
|
||||
abstract class Member(var annotations: Annotations, val modifiers: Modifiers) : Element()
|
||||
|
||||
@@ -26,7 +30,8 @@ class ClassBody (
|
||||
val members: List<Member>,
|
||||
val companionObjectMembers: List<Member>,
|
||||
val lBrace: LBrace,
|
||||
val rBrace: RBrace) {
|
||||
val rBrace: RBrace,
|
||||
val overloadReducer: OverloadReducer) {
|
||||
|
||||
fun append(builder: CodeBuilder) {
|
||||
val membersFiltered = members.filter { !it.isEmpty }
|
||||
|
||||
@@ -22,9 +22,9 @@ import com.intellij.util.IncorrectOperationException
|
||||
abstract class Constructor(
|
||||
annotations: Annotations,
|
||||
modifiers: Modifiers,
|
||||
public val parameterList: ParameterList,
|
||||
protected val body: DeferredElement<Block>
|
||||
) : Member(annotations, modifiers)
|
||||
parameterList: ParameterList,
|
||||
body: DeferredElement<Block>
|
||||
) : FunctionLike(annotations, modifiers, parameterList, body)
|
||||
|
||||
class PrimaryConstructor(
|
||||
annotations: Annotations,
|
||||
@@ -36,14 +36,14 @@ class PrimaryConstructor(
|
||||
override fun generateCode(builder: CodeBuilder) { throw IncorrectOperationException() }
|
||||
|
||||
public fun initializer(): Initializer
|
||||
= Initializer(body, Modifiers.Empty).assignPrototypesFrom(this, CommentsAndSpacesInheritance(commentsBefore = false))
|
||||
= Initializer(body!!, Modifiers.Empty).assignPrototypesFrom(this, CommentsAndSpacesInheritance(commentsBefore = false))
|
||||
|
||||
public fun createSignature(converter: Converter): PrimaryConstructorSignature {
|
||||
val signature = PrimaryConstructorSignature(annotations, modifiers, parameterList)
|
||||
|
||||
// assign prototypes later because we don't know yet whether the body is empty or not
|
||||
converter.addPostUnfoldDeferredElementsAction {
|
||||
val inheritance = CommentsAndSpacesInheritance(blankLinesBefore = false, commentsAfter = body.isEmpty, commentsInside = body.isEmpty)
|
||||
val inheritance = CommentsAndSpacesInheritance(blankLinesBefore = false, commentsAfter = body!!.isEmpty, commentsInside = body.isEmpty)
|
||||
signature.assignPrototypesFrom(this, inheritance)
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ class SecondaryConstructor(
|
||||
builder append " : " append thisOrSuperCall
|
||||
}
|
||||
|
||||
builder append " " append body
|
||||
builder append " " append body!!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,16 +18,23 @@ package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
|
||||
abstract class FunctionLike(
|
||||
annotations: Annotations,
|
||||
modifiers: Modifiers,
|
||||
val parameterList: ParameterList,
|
||||
val body: DeferredElement<Block>?
|
||||
) : Member(annotations, modifiers)
|
||||
|
||||
class Function(
|
||||
val name: Identifier,
|
||||
annotations: Annotations,
|
||||
modifiers: Modifiers,
|
||||
val returnType: Type,
|
||||
val typeParameterList: TypeParameterList,
|
||||
val parameterList: ParameterList,
|
||||
val body: DeferredElement<Block>?,
|
||||
parameterList: ParameterList,
|
||||
body: DeferredElement<Block>?,
|
||||
val isInTrait: Boolean
|
||||
) : Member(annotations, modifiers) {
|
||||
) : FunctionLike(annotations, modifiers, parameterList, body) {
|
||||
|
||||
private fun presentationModifiers(): Modifiers {
|
||||
var modifiers = this.modifiers
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
class A {
|
||||
private String s = "";
|
||||
private int x = 0;
|
||||
|
||||
public A() {
|
||||
}
|
||||
|
||||
public A(int p, String s){
|
||||
this(p, s, 1);
|
||||
}
|
||||
|
||||
public A(int p, String s, int x) {
|
||||
this();
|
||||
this.s = s;
|
||||
this.x = x;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// ERROR: Val cannot be reassigned
|
||||
// ERROR: Val cannot be reassigned
|
||||
class A() {
|
||||
private val s = ""
|
||||
private val x = 0
|
||||
|
||||
overloads public constructor(p: Int, s: String, x: Int = 1) : this() {
|
||||
this.s = s
|
||||
this.x = x
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
abstract class A {
|
||||
public abstract void foo(int p);
|
||||
|
||||
public void foo(){
|
||||
foo(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
abstract class A {
|
||||
public abstract fun foo(p: Int)
|
||||
|
||||
public fun foo() {
|
||||
foo(1)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
class A {
|
||||
private int field = 0;
|
||||
|
||||
public int getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public void setField(int field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public void setField() {
|
||||
setField(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
public var field: Int = 0
|
||||
|
||||
public fun setField() {
|
||||
field = 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class A {
|
||||
@NotNull
|
||||
Object foo(String s) {
|
||||
System.out.println("s = " + s);
|
||||
return "";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
Object foo() {
|
||||
return foo(null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Object bar(String s) {
|
||||
System.out.println("s = " + s);
|
||||
return s == null ? "" : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
Object bar() {
|
||||
return bar(null);
|
||||
}
|
||||
|
||||
public @Nullable Object bar1(String s) {
|
||||
System.out.println("s = " + s);
|
||||
return s == null ? "" : null;
|
||||
}
|
||||
|
||||
public @NotNull Object bar1() {
|
||||
return bar1(null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void f() {
|
||||
f(1);
|
||||
}
|
||||
|
||||
public void f(int p) {
|
||||
System.out.println("p = " + p);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// ERROR: Type mismatch: inferred type is kotlin.Any? but kotlin.Any was expected
|
||||
// ERROR: Type mismatch: inferred type is kotlin.Any? but kotlin.Any was expected
|
||||
class A {
|
||||
overloads fun foo(s: String? = null): Any {
|
||||
println("s = " + s!!)
|
||||
return ""
|
||||
}
|
||||
|
||||
fun bar(s: String?): Any? {
|
||||
println("s = " + s!!)
|
||||
return if (s == null) "" else null
|
||||
}
|
||||
|
||||
fun bar(): Any {
|
||||
return bar(null)
|
||||
}
|
||||
|
||||
public fun bar1(s: String?): Any? {
|
||||
println("s = " + s!!)
|
||||
return if (s == null) "" else null
|
||||
}
|
||||
|
||||
public fun bar1(): Any {
|
||||
return bar1(null)
|
||||
}
|
||||
|
||||
deprecated("")
|
||||
public fun f() {
|
||||
f(1)
|
||||
}
|
||||
|
||||
public fun f(p: Int) {
|
||||
println("p = " + p)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
interface I {
|
||||
void foo(int i, char c, String s);
|
||||
void bar();
|
||||
}
|
||||
|
||||
class A implements I{
|
||||
public void foo(int i, char c, String s) {
|
||||
System.out.println("foo" + i + c + s);
|
||||
}
|
||||
|
||||
public void foo(int i, char c) {
|
||||
foo(i, c, "");
|
||||
}
|
||||
|
||||
public void foo(int i) {
|
||||
foo(i, 'a', "");
|
||||
}
|
||||
|
||||
public void bar() {
|
||||
bar(1);
|
||||
}
|
||||
|
||||
public void bar(int i) {}
|
||||
|
||||
public void x() {
|
||||
x(1);
|
||||
}
|
||||
|
||||
public void x(int i) {}
|
||||
|
||||
public void y() {
|
||||
y(1);
|
||||
}
|
||||
|
||||
public void y(int i) {}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public void x() {
|
||||
super.x();
|
||||
}
|
||||
|
||||
public void y(int i) {
|
||||
super.y(i);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
trait I {
|
||||
public fun foo(i: Int, c: Char, s: String)
|
||||
public fun bar()
|
||||
}
|
||||
|
||||
open class A : I {
|
||||
override fun foo(i: Int, c: Char, s: String) {
|
||||
println("foo" + i + c + s)
|
||||
}
|
||||
|
||||
public fun foo(i: Int, c: Char) {
|
||||
foo(i, c, "")
|
||||
}
|
||||
|
||||
public fun foo(i: Int) {
|
||||
foo(i, 'a', "")
|
||||
}
|
||||
|
||||
override fun bar() {
|
||||
bar(1)
|
||||
}
|
||||
|
||||
public fun bar(i: Int) {
|
||||
}
|
||||
|
||||
public open fun x() {
|
||||
x(1)
|
||||
}
|
||||
|
||||
public fun x(i: Int) {
|
||||
}
|
||||
|
||||
public fun y() {
|
||||
y(1)
|
||||
}
|
||||
|
||||
public open fun y(i: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
class B : A() {
|
||||
override fun x() {
|
||||
super.x()
|
||||
}
|
||||
|
||||
override fun y(i: Int) {
|
||||
super.y(i)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
class A {
|
||||
void foo(int i, char c, String s) {
|
||||
System.out.println("foo" + i + c + s);
|
||||
}
|
||||
|
||||
void foo(int i, char c) {
|
||||
foo(i, c, "");
|
||||
}
|
||||
|
||||
void foo(int i) {
|
||||
foo(i, 'a', "");
|
||||
}
|
||||
|
||||
int bar(String s) {
|
||||
System.out.println("s = " + s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bar() {
|
||||
return bar(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class A {
|
||||
overloads fun foo(i: Int, c: Char = 'a', s: String = "") {
|
||||
println("foo" + i + c + s)
|
||||
}
|
||||
|
||||
overloads fun bar(s: String? = null): Int {
|
||||
println("s = " + s!!)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class A {
|
||||
public void foo(int p) {
|
||||
System.out.println("p = [" + p + "]");
|
||||
}
|
||||
|
||||
public synchronized void foo(){
|
||||
foo(calcSomething());
|
||||
}
|
||||
|
||||
// this method should be invoked under synchronized block!
|
||||
private int calcSomething() { return 0; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
class A {
|
||||
public fun foo(p: Int) {
|
||||
println("p = [" + p + "]")
|
||||
}
|
||||
|
||||
synchronized public fun foo() {
|
||||
foo(calcSomething())
|
||||
}
|
||||
|
||||
// this method should be invoked under synchronized block!
|
||||
private fun calcSomething(): Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@@ -78,6 +78,7 @@ import java.util.regex.Pattern;
|
||||
JavaToKotlinConverterForWebDemoTestGenerated.NewClassExpression.class,
|
||||
JavaToKotlinConverterForWebDemoTestGenerated.Nullability.class,
|
||||
JavaToKotlinConverterForWebDemoTestGenerated.ObjectLiteral.class,
|
||||
JavaToKotlinConverterForWebDemoTestGenerated.Overloads.class,
|
||||
JavaToKotlinConverterForWebDemoTestGenerated.PackageStatement.class,
|
||||
JavaToKotlinConverterForWebDemoTestGenerated.ParenthesizedExpression.class,
|
||||
JavaToKotlinConverterForWebDemoTestGenerated.PolyadicExpression.class,
|
||||
@@ -1313,6 +1314,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithDefaultValues2.java")
|
||||
public void testSecondaryConstructorWithDefaultValues2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/constructors/secondaryConstructorWithDefaultValues2.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorsInInnerClass.java")
|
||||
public void testSecondaryConstructorsInInnerClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/constructors/secondaryConstructorsInInnerClass.java");
|
||||
@@ -3489,6 +3496,51 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("j2k/testData/fileOrElement/overloads")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Overloads extends AbstractJavaToKotlinConverterForWebDemoTest {
|
||||
@TestMetadata("Abstract.java")
|
||||
public void testAbstract() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/Abstract.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("AccessorToDrop.java")
|
||||
public void testAccessorToDrop() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/AccessorToDrop.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInOverloads() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/overloads"), Pattern.compile("^(.+)\\.java$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("Annotations.java")
|
||||
public void testAnnotations() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/Annotations.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Override.java")
|
||||
public void testOverride() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/Override.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Simple.java")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/Simple.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Synchronized.java")
|
||||
public void testSynchronized() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/Synchronized.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("j2k/testData/fileOrElement/packageStatement")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -78,6 +78,7 @@ import java.util.regex.Pattern;
|
||||
JavaToKotlinConverterSingleFileTestGenerated.NewClassExpression.class,
|
||||
JavaToKotlinConverterSingleFileTestGenerated.Nullability.class,
|
||||
JavaToKotlinConverterSingleFileTestGenerated.ObjectLiteral.class,
|
||||
JavaToKotlinConverterSingleFileTestGenerated.Overloads.class,
|
||||
JavaToKotlinConverterSingleFileTestGenerated.PackageStatement.class,
|
||||
JavaToKotlinConverterSingleFileTestGenerated.ParenthesizedExpression.class,
|
||||
JavaToKotlinConverterSingleFileTestGenerated.PolyadicExpression.class,
|
||||
@@ -1313,6 +1314,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithDefaultValues2.java")
|
||||
public void testSecondaryConstructorWithDefaultValues2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/constructors/secondaryConstructorWithDefaultValues2.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorsInInnerClass.java")
|
||||
public void testSecondaryConstructorsInInnerClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/constructors/secondaryConstructorsInInnerClass.java");
|
||||
@@ -3489,6 +3496,51 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("j2k/testData/fileOrElement/overloads")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Overloads extends AbstractJavaToKotlinConverterSingleFileTest {
|
||||
@TestMetadata("Abstract.java")
|
||||
public void testAbstract() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/Abstract.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("AccessorToDrop.java")
|
||||
public void testAccessorToDrop() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/AccessorToDrop.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInOverloads() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/overloads"), Pattern.compile("^(.+)\\.java$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("Annotations.java")
|
||||
public void testAnnotations() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/Annotations.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Override.java")
|
||||
public void testOverride() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/Override.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Simple.java")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/Simple.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Synchronized.java")
|
||||
public void testSynchronized() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/overloads/Synchronized.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("j2k/testData/fileOrElement/packageStatement")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user