Fix for KT-12892 J2K: Wrong placing of comments when constructor converted to primary constructor & init
This commit is contained in:
@@ -106,7 +106,7 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ClassBody(null, null, convertedMembers.values.toList(), emptyList(), lBrace, rBrace, classKind)
|
return ClassBody(null, null, null, convertedMembers.values.toList(), emptyList(), lBrace, rBrace, classKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
val useCompanionObject = shouldGenerateCompanionObject(convertedMembers)
|
val useCompanionObject = shouldGenerateCompanionObject(convertedMembers)
|
||||||
@@ -114,11 +114,13 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
|||||||
val members = ArrayList<Member>()
|
val members = ArrayList<Member>()
|
||||||
val companionObjectMembers = ArrayList<Member>()
|
val companionObjectMembers = ArrayList<Member>()
|
||||||
var primaryConstructorSignature: PrimaryConstructorSignature? = null
|
var primaryConstructorSignature: PrimaryConstructorSignature? = null
|
||||||
|
var primaryConstructor: PrimaryConstructor? = null
|
||||||
for ((psiMember, member) in convertedMembers) {
|
for ((psiMember, member) in convertedMembers) {
|
||||||
if (member is PrimaryConstructor) {
|
if (member is PrimaryConstructor) {
|
||||||
|
primaryConstructor = member
|
||||||
assert(primaryConstructorSignature == null)
|
assert(primaryConstructorSignature == null)
|
||||||
primaryConstructorSignature = member.createSignature(converter)
|
primaryConstructorSignature = primaryConstructor.createSignature(converter)
|
||||||
members.add(member.initializer())
|
members.add(primaryConstructor.initializer)
|
||||||
}
|
}
|
||||||
else if (useCompanionObject && member !is Class && psiMember !is PsiEnumConstant && psiMember.hasModifierProperty(PsiModifier.STATIC)) {
|
else if (useCompanionObject && member !is Class && psiMember !is PsiEnumConstant && psiMember.hasModifierProperty(PsiModifier.STATIC)) {
|
||||||
companionObjectMembers.add(member)
|
companionObjectMembers.add(member)
|
||||||
@@ -131,7 +133,8 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primaryConstructorSignature != null
|
if (primaryConstructor != null
|
||||||
|
&& primaryConstructorSignature != null
|
||||||
&& classKind != ClassKind.ANONYMOUS_OBJECT
|
&& classKind != ClassKind.ANONYMOUS_OBJECT
|
||||||
&& primaryConstructorSignature.annotations.isEmpty
|
&& primaryConstructorSignature.annotations.isEmpty
|
||||||
&& primaryConstructorSignature.accessModifier == null
|
&& primaryConstructorSignature.accessModifier == null
|
||||||
@@ -141,7 +144,7 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
|||||||
primaryConstructorSignature = null // no "()" after class name is needed in this case
|
primaryConstructorSignature = null // no "()" after class name is needed in this case
|
||||||
}
|
}
|
||||||
|
|
||||||
return ClassBody(primaryConstructorSignature, constructorConverter?.baseClassParams, members, companionObjectMembers, lBrace, rBrace, classKind)
|
return ClassBody(primaryConstructor, primaryConstructorSignature, constructorConverter?.baseClassParams, members, companionObjectMembers, lBrace, rBrace, classKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertMember(
|
private fun convertMember(
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ class Converter private constructor(
|
|||||||
val implementsTypes = convertToNotNullableTypes(psiClass.implementsListTypes)
|
val implementsTypes = convertToNotNullableTypes(psiClass.implementsListTypes)
|
||||||
val name = psiClass.declarationIdentifier()
|
val name = psiClass.declarationIdentifier()
|
||||||
|
|
||||||
return when {
|
val converted = when {
|
||||||
psiClass.isInterface -> {
|
psiClass.isInterface -> {
|
||||||
val classBody = ClassBodyConverter(psiClass, ClassKind.INTERFACE, this).convertBody()
|
val classBody = ClassBodyConverter(psiClass, ClassKind.INTERFACE, this).convertBody()
|
||||||
Interface(name, annotations, modifiers, typeParameters, extendsTypes, implementsTypes, classBody)
|
Interface(name, annotations, modifiers, typeParameters, extendsTypes, implementsTypes, classBody)
|
||||||
@@ -208,6 +208,18 @@ class Converter private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.assignPrototype(psiClass)
|
}.assignPrototype(psiClass)
|
||||||
|
|
||||||
|
if (converted.body.primaryConstructorSignature == null)
|
||||||
|
addPostUnfoldDeferredElementsAction {
|
||||||
|
val primaryConstructor = converted.body.primaryConstructor
|
||||||
|
if (primaryConstructor != null) {
|
||||||
|
if (primaryConstructor.initializer.isEmpty)
|
||||||
|
converted.prototypes = converted.prototypes!! + primaryConstructor.prototypes!!
|
||||||
|
else
|
||||||
|
primaryConstructor.initializer.assignPrototypesFrom(primaryConstructor, CommentsAndSpacesInheritance.NO_SPACES)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return converted
|
||||||
}
|
}
|
||||||
|
|
||||||
fun needOpenModifier(psiClass: PsiClass): Boolean {
|
fun needOpenModifier(psiClass: PsiClass): Boolean {
|
||||||
@@ -285,7 +297,7 @@ class Converter private constructor(
|
|||||||
|
|
||||||
// to convert fields and nested types - they are not allowed in Kotlin but we convert them and let user refactor code
|
// 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, ClassKind.ANNOTATION_CLASS, this).convertBody()
|
var classBody = ClassBodyConverter(psiClass, ClassKind.ANNOTATION_CLASS, this).convertBody()
|
||||||
classBody = ClassBody(constructorSignature, classBody.baseClassParams, classBody.members,
|
classBody = ClassBody(null, constructorSignature, classBody.baseClassParams, classBody.members,
|
||||||
classBody.companionObjectMembers, classBody.lBrace, classBody.rBrace, classBody.classKind)
|
classBody.companionObjectMembers, classBody.lBrace, classBody.rBrace, classBody.classKind)
|
||||||
|
|
||||||
return Class(psiClass.declarationIdentifier(),
|
return Class(psiClass.declarationIdentifier(),
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.j2k.append
|
|||||||
abstract class Member(var annotations: Annotations, val modifiers: Modifiers) : Element()
|
abstract class Member(var annotations: Annotations, val modifiers: Modifiers) : Element()
|
||||||
|
|
||||||
class ClassBody (
|
class ClassBody (
|
||||||
|
val primaryConstructor: PrimaryConstructor?,
|
||||||
val primaryConstructorSignature: PrimaryConstructorSignature?,
|
val primaryConstructorSignature: PrimaryConstructorSignature?,
|
||||||
val baseClassParams: List<DeferredElement<Expression>>?,
|
val baseClassParams: List<DeferredElement<Expression>>?,
|
||||||
val members: List<Member>,
|
val members: List<Member>,
|
||||||
|
|||||||
@@ -39,10 +39,12 @@ class PrimaryConstructor(
|
|||||||
|
|
||||||
override fun generateCode(builder: CodeBuilder) { throw IncorrectOperationException() }
|
override fun generateCode(builder: CodeBuilder) { throw IncorrectOperationException() }
|
||||||
|
|
||||||
fun initializer(): Initializer
|
// Should be lazy, to defer `assignPrototypesFrom(this,...)` a bit,
|
||||||
= Initializer(body!!, Modifiers.Empty).assignPrototypesFrom(this, CommentsAndSpacesInheritance(commentsBefore = false))
|
// cause when `PrimaryConstructor` created prototypes not yet assigned
|
||||||
|
val initializer: Initializer by
|
||||||
|
lazy { Initializer(body, Modifiers.Empty).assignPrototypesFrom(this, CommentsAndSpacesInheritance(commentsBefore = false)) }
|
||||||
|
|
||||||
fun createSignature(converter: Converter): PrimaryConstructorSignature {
|
fun createSignature(converter: Converter): PrimaryConstructorSignature? {
|
||||||
val signature = PrimaryConstructorSignature(annotations, modifiers, parameterList)
|
val signature = PrimaryConstructorSignature(annotations, modifiers, parameterList)
|
||||||
|
|
||||||
// assign prototypes later because we don't know yet whether the body is empty or not
|
// assign prototypes later because we don't know yet whether the body is empty or not
|
||||||
|
|||||||
@@ -26,4 +26,24 @@ class B {
|
|||||||
} // end of constructor body
|
} // end of constructor body
|
||||||
|
|
||||||
void foo(){}
|
void foo(){}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CtorComment {
|
||||||
|
public String myA;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The magic of comments
|
||||||
|
*/
|
||||||
|
// single line magic comments
|
||||||
|
public CtorComment() {
|
||||||
|
myA = "a";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CtorComment2 {
|
||||||
|
/*
|
||||||
|
* The magic of comments
|
||||||
|
*/
|
||||||
|
// single line magic comments
|
||||||
|
public CtorComment() {}
|
||||||
}
|
}
|
||||||
@@ -18,4 +18,22 @@ internal class B// this constructor will disappear
|
|||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class CtorComment {
|
||||||
|
var myA: String
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The magic of comments
|
||||||
|
*/
|
||||||
|
// single line magic comments
|
||||||
|
init {
|
||||||
|
myA = "a"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The magic of comments
|
||||||
|
*/
|
||||||
|
// single line magic comments
|
||||||
|
internal class CtorComment2
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
class CtorComment {
|
||||||
|
public String myA;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor is especially useful
|
||||||
|
*/
|
||||||
|
public CtorComment() {
|
||||||
|
myA = "str";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CtorComment2 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor is especially useful
|
||||||
|
*/
|
||||||
|
public CtorComment() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
internal class CtorComment {
|
||||||
|
var myA: String
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor is especially useful
|
||||||
|
*/
|
||||||
|
init {
|
||||||
|
myA = "str"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor is especially useful
|
||||||
|
*/
|
||||||
|
internal class CtorComment2
|
||||||
@@ -1807,6 +1807,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("primaryConstructorDoc.java")
|
||||||
|
public void testPrimaryConstructorDoc() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/docComments/primaryConstructorDoc.java");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("quoted.java")
|
@TestMetadata("quoted.java")
|
||||||
public void testQuoted() throws Exception {
|
public void testQuoted() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/docComments/quoted.java");
|
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/docComments/quoted.java");
|
||||||
|
|||||||
@@ -1807,6 +1807,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("primaryConstructorDoc.java")
|
||||||
|
public void testPrimaryConstructorDoc() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/docComments/primaryConstructorDoc.java");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("quoted.java")
|
@TestMetadata("quoted.java")
|
||||||
public void testQuoted() throws Exception {
|
public void testQuoted() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/docComments/quoted.java");
|
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/docComments/quoted.java");
|
||||||
|
|||||||
Reference in New Issue
Block a user