Fixed KT-5383 J2K: preserve annotations from primary constructor + never drop constructors with annotations
#KT-5383 Fixed
This commit is contained in:
@@ -121,12 +121,10 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun dropConstructorsForDefaultValues(primary: PsiMethod, toTargetConstructorMap: Map<PsiMethod, TargetConstructorInfo>) {
|
private fun dropConstructorsForDefaultValues(primary: PsiMethod, toTargetConstructorMap: Map<PsiMethod, TargetConstructorInfo>) {
|
||||||
//TODO: should we drop when annotations exist?
|
|
||||||
|
|
||||||
val dropCandidates = toTargetConstructorMap
|
val dropCandidates = toTargetConstructorMap
|
||||||
.filter { it.value.parameterDefaults != null }
|
.filter { it.value.parameterDefaults != null }
|
||||||
.map { it.key }
|
.map { it.key }
|
||||||
.filter { it.accessModifier() == primary.accessModifier() }
|
.filter { it.accessModifier() == primary.accessModifier() && it.getModifierList().getAnnotations().isEmpty() /* do not drop constructors with annotations */ }
|
||||||
.sortBy { -it.getParameterList().getParametersCount() } // we will try to drop them starting from ones with more parameters
|
.sortBy { -it.getParameterList().getParametersCount() } // we will try to drop them starting from ones with more parameters
|
||||||
val primaryParamCount = primary.getParameterList().getParametersCount()
|
val primaryParamCount = primary.getParameterList().getParametersCount()
|
||||||
@DropCandidatesLoop
|
@DropCandidatesLoop
|
||||||
@@ -340,7 +338,7 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter
|
|||||||
//TODO: we can generate it private when secondary constructors are supported by Kotlin
|
//TODO: we can generate it private when secondary constructors are supported by Kotlin
|
||||||
//val modifiers = Modifiers(listOf(Modifier.PRIVATE)).assignNoPrototype()
|
//val modifiers = Modifiers(listOf(Modifier.PRIVATE)).assignNoPrototype()
|
||||||
val parameterList = ParameterList(parameters).assignNoPrototype()
|
val parameterList = ParameterList(parameters).assignNoPrototype()
|
||||||
val constructorSignature = PrimaryConstructorSignature(modifiers, parameterList).assignNoPrototype()
|
val constructorSignature = PrimaryConstructorSignature(Annotations.Empty, modifiers, parameterList).assignNoPrototype()
|
||||||
val updatedMembers = classBody.members.filter { !fieldsToInitialize.contains(it) }
|
val updatedMembers = classBody.members.filter { !fieldsToInitialize.contains(it) }
|
||||||
return ClassBody(constructorSignature, updatedMembers, classBody.classObjectMembers, updatedFactoryFunctions, classBody.lBrace, classBody.rBrace)
|
return ClassBody(constructorSignature, updatedMembers, classBody.classObjectMembers, updatedFactoryFunctions, classBody.lBrace, classBody.rBrace)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,3 +66,6 @@ class Annotations(val annotations: List<Annotation>, val newLines: Boolean) : El
|
|||||||
val Empty = Annotations(listOf(), false)
|
val Empty = Annotations(listOf(), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Annotations.withBrackets(): Annotations
|
||||||
|
= Annotations(annotations.map { Annotation(it.name, it.arguments, true).assignPrototypesFrom(it) }, newLines).assignPrototypesFrom(this)
|
||||||
|
|||||||
@@ -37,17 +37,23 @@ class PrimaryConstructor(annotations: Annotations,
|
|||||||
public fun signature(): PrimaryConstructorSignature {
|
public fun signature(): PrimaryConstructorSignature {
|
||||||
val noBody = block.isEmpty
|
val noBody = block.isEmpty
|
||||||
val inheritance = CommentsAndSpacesInheritance(blankLinesBefore = false, commentsAfter = noBody, commentsInside = noBody)
|
val inheritance = CommentsAndSpacesInheritance(blankLinesBefore = false, commentsAfter = noBody, commentsInside = noBody)
|
||||||
return PrimaryConstructorSignature(modifiers, parameterList).assignPrototypesFrom(this, inheritance)
|
return PrimaryConstructorSignature(annotations, modifiers, parameterList).assignPrototypesFrom(this, inheritance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrimaryConstructorSignature(val modifiers: Modifiers, val parameterList: ParameterList) : Element() {
|
class PrimaryConstructorSignature(val annotations: Annotations, val modifiers: Modifiers, val parameterList: ParameterList) : Element() {
|
||||||
override fun generateCode(builder: CodeBuilder) {
|
override fun generateCode(builder: CodeBuilder) {
|
||||||
val accessModifier = modifiers.filter { it in ACCESS_MODIFIERS && it != Modifier.PUBLIC }
|
val accessModifier = modifiers.filter { it in ACCESS_MODIFIERS && it != Modifier.PUBLIC }
|
||||||
if (accessModifier.isEmpty && parameterList.parameters.isEmpty()) return
|
if (accessModifier.isEmpty && annotations.isEmpty && parameterList.parameters.isEmpty()) return
|
||||||
|
|
||||||
|
if (!annotations.isEmpty) {
|
||||||
|
builder append " " append annotations.withBrackets()
|
||||||
|
}
|
||||||
|
|
||||||
if (!accessModifier.isEmpty) {
|
if (!accessModifier.isEmpty) {
|
||||||
builder append " " append accessModifier
|
builder append " " append accessModifier
|
||||||
}
|
}
|
||||||
|
|
||||||
builder append "(" append parameterList append ")"
|
builder append "(" append parameterList append ")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -821,6 +821,11 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv
|
|||||||
doTest("j2k/tests/testData/ast/constructors/chain.java");
|
doTest("j2k/tests/testData/ast/constructors/chain.java");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructorAnnotations.java")
|
||||||
|
public void testConstructorAnnotations() throws Exception {
|
||||||
|
doTest("j2k/tests/testData/ast/constructors/constructorAnnotations.java");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("customerBuilder.java")
|
@TestMetadata("customerBuilder.java")
|
||||||
public void testCustomerBuilder() throws Exception {
|
public void testCustomerBuilder() throws Exception {
|
||||||
doTest("j2k/tests/testData/ast/constructors/customerBuilder.java");
|
doTest("j2k/tests/testData/ast/constructors/customerBuilder.java");
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import javaApi.Anon5;
|
||||||
|
|
||||||
|
class A {
|
||||||
|
private final int a;
|
||||||
|
private final int b;
|
||||||
|
|
||||||
|
@Anon5(10)
|
||||||
|
public A(int a, int b) {
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated // this constructor will not be replaced by default parameter value in primary because of this annotation
|
||||||
|
public A(int a) {
|
||||||
|
this(a, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
@Anon5(11)
|
||||||
|
public B() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
@Anon5(12)
|
||||||
|
private C() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import javaApi.Anon5
|
||||||
|
|
||||||
|
|
||||||
|
deprecated("") // this constructor will not be replaced by default parameter value in primary because of this annotation
|
||||||
|
fun A(a: Int): A {
|
||||||
|
return A(a, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
class A
|
||||||
|
[Anon5(10)]
|
||||||
|
(private val a: Int, private val b: Int)
|
||||||
|
|
||||||
|
class B [Anon5(11)]
|
||||||
|
()
|
||||||
|
|
||||||
|
class C [Anon5(12)]
|
||||||
|
private()
|
||||||
Reference in New Issue
Block a user