Java to Kotlin converter: better comments preserving, never lose any comment
#KT-4489 Fixed
This commit is contained in:
@@ -21,6 +21,7 @@ import java.util.HashSet
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.j2k.ast.Element
|
||||
import org.jetbrains.jet.j2k.ast.Modifiers
|
||||
import kotlin.platform.platformName
|
||||
|
||||
fun<T> CodeBuilder.append(generators: Collection<() -> T>, separator: String, prefix: String = "", suffix: String = ""): CodeBuilder {
|
||||
@@ -104,6 +105,17 @@ class CodeBuilder(private val topElement: PsiElement?) {
|
||||
|
||||
element.generateCode(this)
|
||||
|
||||
// scan for all comments inside which are not yet used in the text and put them here to not loose any comment from code
|
||||
for ((prototype, _) in element.prototypes) {
|
||||
prototype.accept(object : JavaRecursiveElementVisitor(){
|
||||
override fun visitComment(comment: PsiComment) {
|
||||
if (commentsAndSpacesUsed.add(comment)) {
|
||||
append(comment.getText()!!, comment.isEndOfLineComment())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
postfixElements.forEach { append(it.getText()!!, it.isEndOfLineComment()) }
|
||||
|
||||
return this
|
||||
|
||||
@@ -168,7 +168,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
|
||||
private fun convertClass(psiClass: PsiClass): Class {
|
||||
val annotations = convertAnnotations(psiClass)
|
||||
val modifiers = convertModifiers(psiClass)
|
||||
var modifiers = convertModifiers(psiClass)
|
||||
val typeParameters = convertTypeParameterList(psiClass.getTypeParameterList())
|
||||
val implementsTypes = convertToNotNullableTypes(psiClass.getImplementsListTypes())
|
||||
val extendsTypes = convertToNotNullableTypes(psiClass.getExtendsListTypes())
|
||||
@@ -198,11 +198,11 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
}
|
||||
|
||||
if (settings.openByDefault && !psiClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
modifiers.add(Modifier.OPEN)
|
||||
modifiers = modifiers.with(Modifier.OPEN)
|
||||
}
|
||||
|
||||
if (psiClass.getContainingClass() != null && !psiClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
modifiers.add(Modifier.INNER)
|
||||
modifiers = modifiers.with(Modifier.INNER)
|
||||
}
|
||||
|
||||
Class(name, annotations, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, classBody)
|
||||
@@ -247,7 +247,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
val initializer = MethodCallExpression.buildNotNull(null, className.name, finalOrWithEmptyInitializerFields.map { initializers[it]!! })
|
||||
val localVar = LocalVariable(SecondaryConstructor.tempValIdentifier,
|
||||
Annotations.Empty,
|
||||
setOf(),
|
||||
Modifiers.Empty,
|
||||
{ ClassType(className, listOf(), Nullability.NotNull, settings) },
|
||||
initializer,
|
||||
true,
|
||||
@@ -259,10 +259,10 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
//TODO: comments?
|
||||
val parameters = finalOrWithEmptyInitializerFields.map { field ->
|
||||
val varValModifier = if (field.isVal) Parameter.VarValModifier.Val else Parameter.VarValModifier.Var
|
||||
Parameter(field.identifier, field.`type`, varValModifier, field.annotations, field.modifiers.filter { ACCESS_MODIFIERS.contains(it) })
|
||||
Parameter(field.identifier, field.`type`, varValModifier, field.annotations, field.modifiers.filter { it in ACCESS_MODIFIERS })
|
||||
}
|
||||
|
||||
val primaryConstructor = PrimaryConstructor(this, Annotations.Empty, setOf(Modifier.PRIVATE), ParameterList(parameters), Block.Empty)
|
||||
val primaryConstructor = PrimaryConstructor(this, Annotations.Empty, Modifiers(listOf(Modifier.PRIVATE)), ParameterList(parameters), Block.Empty)
|
||||
val updatedMembers = classBody.normalMembers.filter { !finalOrWithEmptyInitializerFields.contains(it) }
|
||||
return ClassBody(primaryConstructor, classBody.secondaryConstructors, updatedMembers, classBody.classObjectMembers, classBody.lBrace, classBody.rBrace)
|
||||
}
|
||||
@@ -302,7 +302,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
val returnType = typeConverter.convertMethodReturnType(method)
|
||||
|
||||
val annotations = convertAnnotations(method) + convertThrows(method)
|
||||
val modifiers = convertModifiers(method)
|
||||
var modifiers = convertModifiers(method)
|
||||
|
||||
if (method.isConstructor()) {
|
||||
if (method.isPrimaryConstructor()) {
|
||||
@@ -316,7 +316,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
else {
|
||||
val isOverride = isOverride(method)
|
||||
if (isOverride) {
|
||||
modifiers.add(Modifier.OVERRIDE)
|
||||
modifiers = modifiers.with(Modifier.OVERRIDE)
|
||||
}
|
||||
|
||||
val containingClass = method.getContainingClass()
|
||||
@@ -325,7 +325,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
val isEffectivelyFinal = method.hasModifierProperty(PsiModifier.FINAL) ||
|
||||
containingClass != null && (containingClass.hasModifierProperty(PsiModifier.FINAL) || containingClass.isEnum())
|
||||
if (!isEffectivelyFinal && !modifiers.contains(Modifier.ABSTRACT) && !modifiers.contains(Modifier.PRIVATE)) {
|
||||
modifiers.add(Modifier.OPEN)
|
||||
modifiers = modifiers.with(Modifier.OPEN)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
ClassType(Identifier("Any"), listOf(), Nullability.Nullable, settings),
|
||||
Parameter.VarValModifier.None,
|
||||
params.parameters.single().annotations,
|
||||
listOf())
|
||||
Modifiers.Empty)
|
||||
params = ParameterList(listOf(correctedParameter))
|
||||
}
|
||||
}
|
||||
@@ -390,7 +390,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
|
||||
private fun convertPrimaryConstructor(constructor: PsiMethod,
|
||||
annotations: Annotations,
|
||||
modifiers: Set<Modifier>,
|
||||
modifiers: Modifiers,
|
||||
membersToRemove: MutableSet<PsiMember>): PrimaryConstructor {
|
||||
val params = constructor.getParameterList().getParameters()
|
||||
val parameterToField = HashMap<PsiParameter, Pair<PsiField, Type>>()
|
||||
@@ -439,7 +439,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
`type`,
|
||||
if (field.hasModifierProperty(PsiModifier.FINAL)) Parameter.VarValModifier.Val else Parameter.VarValModifier.Var,
|
||||
convertAnnotations(parameter) + convertAnnotations(field),
|
||||
convertModifiers(field).filter { ACCESS_MODIFIERS.contains(it) }).assignPrototypes(listOf(parameter, field), inheritBlankLinesBefore = false)
|
||||
convertModifiers(field).filter { it in ACCESS_MODIFIERS }).assignPrototypes(listOf(parameter, field), inheritBlankLinesBefore = false)
|
||||
}
|
||||
})
|
||||
return PrimaryConstructor(this, annotations, modifiers, parameterList, block).assignPrototype(constructor)
|
||||
@@ -521,9 +521,9 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
= ParameterList(parameterList.getParameters().map { convertParameter(it) }).assignPrototype(parameterList)
|
||||
|
||||
fun convertParameter(parameter: PsiParameter,
|
||||
nullability: Nullability = Nullability.Default,
|
||||
varValModifier: Parameter.VarValModifier = Parameter.VarValModifier.None,
|
||||
modifiers: List<Modifier> = listOf()): Parameter {
|
||||
nullability: Nullability = Nullability.Default,
|
||||
varValModifier: Parameter.VarValModifier = Parameter.VarValModifier.None,
|
||||
modifiers: Modifiers = Modifiers.Empty): Parameter {
|
||||
var `type` = typeConverter.convertVariableType(parameter)
|
||||
when (nullability) {
|
||||
Nullability.NotNull -> `type` = `type`.toNotNullType()
|
||||
@@ -566,8 +566,8 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
return Identifier(identifier.getText()!!).assignPrototype(identifier)
|
||||
}
|
||||
|
||||
fun convertModifiers(owner: PsiModifierListOwner): MutableSet<Modifier>
|
||||
= HashSet(MODIFIERS_MAP.filter { owner.hasModifierProperty(it.first) }.map { it.second })
|
||||
fun convertModifiers(owner: PsiModifierListOwner): Modifiers
|
||||
= Modifiers(MODIFIERS_MAP.filter { owner.hasModifierProperty(it.first) }.map { it.second }).assignPrototype(owner.getModifierList(), false)
|
||||
|
||||
private val MODIFIERS_MAP = listOf(
|
||||
PsiModifier.ABSTRACT to Modifier.ABSTRACT,
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.HashMap
|
||||
import java.util.HashSet
|
||||
import org.jetbrains.jet.j2k.ast.Import
|
||||
import org.jetbrains.jet.j2k.ast.ImportList
|
||||
import org.jetbrains.jet.j2k.ast.assignPrototype
|
||||
|
||||
class TypeConverter(val settings: ConverterSettings, val conversionScope: ConversionScope) {
|
||||
private val nullabilityCache = HashMap<PsiElement, Nullability>()
|
||||
@@ -56,7 +57,7 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
||||
= types.map { convertType(it) }
|
||||
|
||||
public fun convertVariableType(variable: PsiVariable): Type
|
||||
= convertType(variable.getType(), variableNullability(variable))
|
||||
= convertType(variable.getType(), variableNullability(variable)).assignPrototype(variable.getTypeElement())
|
||||
|
||||
public fun variableNullability(variable: PsiVariable): Nullability {
|
||||
val cached = nullabilityCache[variable]
|
||||
@@ -119,7 +120,7 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
||||
}
|
||||
|
||||
public fun convertMethodReturnType(method: PsiMethod): Type
|
||||
= convertType(method.getReturnType(), methodNullability(method))
|
||||
= convertType(method.getReturnType(), methodNullability(method)).assignPrototype(method.getReturnTypeElement())
|
||||
|
||||
public fun methodNullability(method: PsiMethod): Nullability {
|
||||
val cached = nullabilityCache[method]
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.jet.j2k.ast
|
||||
import org.jetbrains.jet.j2k.CodeBuilder
|
||||
|
||||
class AnonymousClassBody(body: ClassBody, val extendsTrait: Boolean)
|
||||
: Class(Identifier.Empty, Annotations.Empty, setOf(), TypeParameterList.Empty, listOf(), listOf(), listOf(), body) {
|
||||
: Class(Identifier.Empty, Annotations.Empty, Modifiers.Empty, TypeParameterList.Empty, listOf(), listOf(), listOf(), body) {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
body.append(builder, null)
|
||||
}
|
||||
|
||||
@@ -16,13 +16,12 @@
|
||||
|
||||
package org.jetbrains.jet.j2k.ast
|
||||
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.j2k.*
|
||||
|
||||
open class Class(
|
||||
val name: Identifier,
|
||||
annotations: Annotations,
|
||||
modifiers: Set<Modifier>,
|
||||
modifiers: Modifiers,
|
||||
val typeParameterList: TypeParameterList,
|
||||
val extendsTypes: List<Type>,
|
||||
val baseClassParams: List<Expression>,
|
||||
@@ -32,7 +31,11 @@ open class Class(
|
||||
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
builder.append(annotations)
|
||||
appendModifiers(builder).append(keyword).append(" ").append(name).append(typeParameterList)
|
||||
.appendWithSpaceAfter(presentationModifiers())
|
||||
.append(keyword)
|
||||
.append(" ")
|
||||
.append(name)
|
||||
.append(typeParameterList)
|
||||
appendPrimaryConstructorSignature(builder)
|
||||
appendBaseTypes(builder)
|
||||
typeParameterList.appendWhere(builder)
|
||||
@@ -61,22 +64,6 @@ open class Class(
|
||||
return extendsTypes.map { { builder.append(it) } }
|
||||
}
|
||||
|
||||
protected open fun appendModifiers(builder: CodeBuilder): CodeBuilder {
|
||||
val modifierList = ArrayList<Modifier>()
|
||||
|
||||
modifiers.accessModifier()?.let { modifierList.add(it) }
|
||||
|
||||
if (modifiers.contains(Modifier.ABSTRACT)) {
|
||||
modifierList.add(Modifier.ABSTRACT)
|
||||
}
|
||||
else if (modifiers.contains(Modifier.OPEN)) {
|
||||
modifierList.add(Modifier.OPEN)
|
||||
}
|
||||
|
||||
if (modifiers.contains(Modifier.INNER)) {
|
||||
modifierList.add(Modifier.INNER)
|
||||
}
|
||||
|
||||
return builder.append(modifierList)
|
||||
}
|
||||
protected open fun presentationModifiers(): Modifiers
|
||||
= if (modifiers.contains(Modifier.ABSTRACT)) modifiers.without(Modifier.OPEN) else modifiers
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.jet.j2k.ast
|
||||
|
||||
import org.jetbrains.jet.j2k.*
|
||||
|
||||
abstract class Member(val annotations: Annotations, val modifiers: Set<Modifier>) : Element()
|
||||
abstract class Member(val annotations: Annotations, val modifiers: Modifiers) : Element()
|
||||
|
||||
class ClassBody (
|
||||
val primaryConstructor: PrimaryConstructor?,
|
||||
|
||||
@@ -16,29 +16,30 @@
|
||||
|
||||
package org.jetbrains.jet.j2k.ast
|
||||
|
||||
import java.util.HashSet
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.j2k.*
|
||||
|
||||
abstract class Constructor(
|
||||
converter: Converter,
|
||||
annotations: Annotations,
|
||||
modifiers: Set<Modifier>,
|
||||
modifiers: Modifiers,
|
||||
parameterList: ParameterList,
|
||||
block: Block
|
||||
) : Function(converter, Identifier.Empty, annotations, modifiers, Type.Empty, TypeParameterList.Empty, parameterList, block, false)
|
||||
|
||||
class PrimaryConstructor(converter: Converter,
|
||||
annotations: Annotations,
|
||||
modifiers: Set<Modifier>,
|
||||
modifiers: Modifiers,
|
||||
parameterList: ParameterList,
|
||||
block: Block)
|
||||
: Constructor(converter, annotations, modifiers, parameterList, block) {
|
||||
|
||||
public fun appendSignature(builder: CodeBuilder): CodeBuilder {
|
||||
val accessModifier = modifiers.accessModifier()
|
||||
val modifiersString = if (accessModifier != null && accessModifier != Modifier.PUBLIC) " " + accessModifier.toKotlin() else ""
|
||||
return builder.append(modifiersString).append("(").append(parameterList).append(")")
|
||||
val accessModifier = modifiers.filter { it in ACCESS_MODIFIERS && it != Modifier.PUBLIC }
|
||||
if (!accessModifier.isEmpty) {
|
||||
builder append " " append accessModifier
|
||||
}
|
||||
return builder append "(" append parameterList append ")"
|
||||
}
|
||||
|
||||
public fun appendBody(builder: CodeBuilder): CodeBuilder = builder.append(block!!)
|
||||
@@ -46,13 +47,12 @@ class PrimaryConstructor(converter: Converter,
|
||||
|
||||
class SecondaryConstructor(converter: Converter,
|
||||
annotations: Annotations,
|
||||
modifiers: Set<Modifier>,
|
||||
modifiers: Modifiers,
|
||||
parameterList: ParameterList,
|
||||
block: Block)
|
||||
: Constructor(converter, annotations, modifiers, parameterList, block) {
|
||||
|
||||
public fun toFactoryFunction(containingClass: Class?): Function {
|
||||
val modifiers = HashSet(modifiers)
|
||||
val statements = ArrayList(block?.statements ?: listOf())
|
||||
statements.add(ReturnStatement(tempValIdentifier))
|
||||
val block = Block(statements, block?.lBrace ?: LBrace(), block?.rBrace ?: RBrace())
|
||||
|
||||
@@ -19,8 +19,8 @@ package org.jetbrains.jet.j2k.ast
|
||||
import org.jetbrains.jet.j2k.*
|
||||
import com.intellij.psi.PsiElement
|
||||
|
||||
fun <TElement: Element> TElement.assignPrototype(prototype: PsiElement?): TElement {
|
||||
assignPrototypeInfos(if (prototype != null) listOf(PrototypeInfo(prototype, true)) else listOf())
|
||||
fun <TElement: Element> TElement.assignPrototype(prototype: PsiElement?, inheritBlankLinesBefore: Boolean = true): TElement {
|
||||
assignPrototypeInfos(if (prototype != null) listOf(PrototypeInfo(prototype, inheritBlankLinesBefore)) else listOf())
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.jet.j2k.*
|
||||
class Enum(
|
||||
name: Identifier,
|
||||
annotations: Annotations,
|
||||
modifiers: Set<Modifier>,
|
||||
modifiers: Modifiers,
|
||||
typeParameterList: TypeParameterList,
|
||||
extendsTypes: List<Type>,
|
||||
baseClassParams: List<Expression>,
|
||||
@@ -35,8 +35,7 @@ class Enum(
|
||||
}
|
||||
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
builder append annotations
|
||||
appendModifiers(builder) append "enum class " append name
|
||||
builder append annotations appendWithSpaceAfter presentationModifiers() append "enum class " append name
|
||||
appendPrimaryConstructorSignature(builder)
|
||||
builder append typeParameterList
|
||||
appendBaseTypes(builder)
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.jet.j2k.*
|
||||
class EnumConstant(
|
||||
identifier: Identifier,
|
||||
annotations: Annotations,
|
||||
modifiers: Set<Modifier>,
|
||||
modifiers: Modifiers,
|
||||
`type`: Type,
|
||||
params: Element
|
||||
) : Field(identifier, annotations, modifiers, `type`.toNotNullType(), params, true, false) {
|
||||
|
||||
@@ -17,12 +17,11 @@
|
||||
package org.jetbrains.jet.j2k.ast
|
||||
|
||||
import org.jetbrains.jet.j2k.*
|
||||
import java.util.ArrayList
|
||||
|
||||
open class Field(
|
||||
val identifier: Identifier,
|
||||
annotations: Annotations,
|
||||
modifiers: Set<Modifier>,
|
||||
modifiers: Modifiers,
|
||||
val `type`: Type,
|
||||
val initializer: Element,
|
||||
val isVal: Boolean,
|
||||
@@ -31,7 +30,7 @@ open class Field(
|
||||
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
builder.append(annotations)
|
||||
.appendModifiers()
|
||||
.appendWithSpaceAfter(modifiers)
|
||||
.append(if (isVal) "val " else "var ")
|
||||
.append(identifier)
|
||||
.append(" : ")
|
||||
@@ -45,15 +44,4 @@ open class Field(
|
||||
builder append "=" append initializerToUse
|
||||
}
|
||||
}
|
||||
|
||||
private fun CodeBuilder.appendModifiers(): CodeBuilder {
|
||||
val modifierList = ArrayList<Modifier>()
|
||||
if (modifiers.contains(Modifier.ABSTRACT)) {
|
||||
modifierList.add(Modifier.ABSTRACT)
|
||||
}
|
||||
|
||||
modifiers.accessModifier()?.let { modifierList.add(it) }
|
||||
|
||||
return append(modifierList)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
|
||||
package org.jetbrains.jet.j2k.ast
|
||||
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.j2k.*
|
||||
|
||||
open class Function(
|
||||
val converter: Converter,
|
||||
val name: Identifier,
|
||||
annotations: Annotations,
|
||||
modifiers: Set<Modifier>,
|
||||
modifiers: Modifiers,
|
||||
val `type`: Type,
|
||||
val typeParameterList: TypeParameterList,
|
||||
val parameterList: ParameterList,
|
||||
@@ -31,33 +30,23 @@ open class Function(
|
||||
val isInTrait: Boolean
|
||||
) : Member(annotations, modifiers) {
|
||||
|
||||
private fun CodeBuilder.appendModifiers(): CodeBuilder {
|
||||
val resultingModifiers = ArrayList<Modifier>()
|
||||
val isOverride = modifiers.contains(Modifier.OVERRIDE)
|
||||
if (isOverride) {
|
||||
resultingModifiers.add(Modifier.OVERRIDE)
|
||||
private fun presentationModifiers(): Modifiers {
|
||||
var modifiers = this.modifiers
|
||||
if (isInTrait) {
|
||||
modifiers = modifiers.without(Modifier.ABSTRACT)
|
||||
}
|
||||
|
||||
val accessModifier = modifiers.accessModifier()
|
||||
if (accessModifier != null && !isOverride) {
|
||||
resultingModifiers.add(accessModifier)
|
||||
if (modifiers.contains(Modifier.OVERRIDE)) {
|
||||
modifiers = modifiers.filter { it != Modifier.OPEN && it !in ACCESS_MODIFIERS }
|
||||
}
|
||||
|
||||
if (modifiers.contains(Modifier.ABSTRACT) && !isInTrait) {
|
||||
resultingModifiers.add(Modifier.ABSTRACT)
|
||||
}
|
||||
|
||||
if (modifiers.contains(Modifier.OPEN) && !isOverride) {
|
||||
resultingModifiers.add(Modifier.OPEN)
|
||||
}
|
||||
|
||||
return append(resultingModifiers)
|
||||
return modifiers
|
||||
}
|
||||
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
builder.append(annotations)
|
||||
.appendModifiers()
|
||||
.append(" fun ")
|
||||
.appendWithSpaceAfter(presentationModifiers())
|
||||
.append("fun ")
|
||||
.appendWithSuffix(typeParameterList, " ")
|
||||
.append(name)
|
||||
.append("(")
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.jet.j2k.ast
|
||||
|
||||
import org.jetbrains.jet.j2k.*
|
||||
|
||||
class Initializer(val block: Block, modifiers: Set<Modifier>) : Member(Annotations.Empty, modifiers) {
|
||||
class Initializer(val block: Block, modifiers: Modifiers) : Member(Annotations.Empty, modifiers) {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
builder.append(block)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.jet.j2k.append
|
||||
class LocalVariable(
|
||||
private val identifier: Identifier,
|
||||
private val annotations: Annotations,
|
||||
private val modifiers: Set<Modifier>,
|
||||
private val modifiers: Modifiers,
|
||||
private val typeCalculator: () -> Type /* we use lazy type calculation for better performance */,
|
||||
private val initializer: Expression,
|
||||
private val isVal: Boolean,
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.jetbrains.jet.j2k.ast
|
||||
|
||||
import org.jetbrains.jet.j2k.CodeBuilder
|
||||
import org.jetbrains.jet.j2k.*
|
||||
import java.util.HashSet
|
||||
|
||||
enum class Modifier(val name: String) {
|
||||
PUBLIC: Modifier("public")
|
||||
@@ -33,16 +34,39 @@ enum class Modifier(val name: String) {
|
||||
val ACCESS_MODIFIERS = setOf(Modifier.PUBLIC, Modifier.PROTECTED, Modifier.PRIVATE)
|
||||
|
||||
fun Collection<Modifier>.accessModifier(): Modifier? {
|
||||
return firstOrNull { ACCESS_MODIFIERS.contains(it) }
|
||||
return firstOrNull { it in ACCESS_MODIFIERS }
|
||||
}
|
||||
|
||||
fun CodeBuilder.append(modifiers: List<Modifier>): CodeBuilder {
|
||||
if (!modifiers.isEmpty()) {
|
||||
for (modifier in modifiers) {
|
||||
append(modifier.toKotlin()).append(" ")
|
||||
}
|
||||
class Modifiers(val modifiers: Collection<Modifier>) : Element() {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
builder.append(modifiers.sortBy { it.ordinal() }.map { it.toKotlin() }.joinToString(" "))
|
||||
}
|
||||
|
||||
override val isEmpty: Boolean
|
||||
get() = modifiers.isEmpty()
|
||||
|
||||
fun with(modifier: Modifier): Modifiers = Modifiers(modifiers + listOf(modifier)).assignPrototypesFrom(this)
|
||||
|
||||
fun without(modifier: Modifier): Modifiers {
|
||||
val set = HashSet(modifiers)
|
||||
set.remove(modifier)
|
||||
return Modifiers(set).assignPrototypesFrom(this)
|
||||
}
|
||||
|
||||
fun contains(modifier: Modifier): Boolean = modifiers.contains(modifier)
|
||||
|
||||
class object {
|
||||
val Empty = Modifiers(listOf())
|
||||
}
|
||||
}
|
||||
|
||||
fun Modifiers.filter(predicate: (Modifier) -> Boolean): Modifiers
|
||||
= Modifiers(modifiers.filter(predicate)).assignPrototypesFrom(this)
|
||||
|
||||
fun CodeBuilder.appendWithSpaceAfter(modifiers: Modifiers): CodeBuilder {
|
||||
if (!modifiers.isEmpty) {
|
||||
this append modifiers append " "
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class Parameter(val identifier: Identifier,
|
||||
val `type`: Type,
|
||||
val varVal: Parameter.VarValModifier,
|
||||
val annotations: Annotations,
|
||||
val modifiers: List<Modifier>) : Element() {
|
||||
val modifiers: Modifiers) : Element() {
|
||||
public enum class VarValModifier {
|
||||
None
|
||||
Val
|
||||
@@ -30,7 +30,7 @@ class Parameter(val identifier: Identifier,
|
||||
}
|
||||
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
builder.append(annotations).append(modifiers)
|
||||
builder.append(annotations).appendWithSpaceAfter(modifiers)
|
||||
|
||||
if (`type` is VarArgType) {
|
||||
assert(varVal == VarValModifier.None)
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
package org.jetbrains.jet.j2k.ast
|
||||
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.j2k.CodeBuilder
|
||||
|
||||
class Trait(name: Identifier,
|
||||
annotations: Annotations,
|
||||
modifiers: Set<Modifier>,
|
||||
modifiers: Modifiers,
|
||||
typeParameterList: TypeParameterList,
|
||||
extendsTypes: List<Type>,
|
||||
baseClassParams: List<Expression>,
|
||||
@@ -34,10 +33,6 @@ class Trait(name: Identifier,
|
||||
|
||||
override fun appendPrimaryConstructorSignature(builder: CodeBuilder) { }
|
||||
|
||||
override fun appendModifiers(builder: CodeBuilder): CodeBuilder {
|
||||
val modifierList = ArrayList<Modifier>()
|
||||
modifiers.accessModifier()?.let { modifierList.add(it) }
|
||||
return builder.append(modifierList)
|
||||
}
|
||||
|
||||
override fun presentationModifiers(): Modifiers
|
||||
= modifiers.filter { it in ACCESS_MODIFIERS }
|
||||
}
|
||||
|
||||
@@ -742,6 +742,11 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv
|
||||
doTest("j2k/tests/testData/ast/comments/comments.java");
|
||||
}
|
||||
|
||||
@TestMetadata("comments2.java")
|
||||
public void testComments2() throws Exception {
|
||||
doTest("j2k/tests/testData/ast/comments/comments2.java");
|
||||
}
|
||||
|
||||
@TestMetadata("fieldWithEndOfLineComment.java")
|
||||
public void testFieldWithEndOfLineComment() throws Exception {
|
||||
doTest("j2k/tests/testData/ast/comments/fieldWithEndOfLineComment.java");
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
//file
|
||||
package foo;
|
||||
|
||||
class A {
|
||||
void/* nothing to return */ foo(/* no parameters at all */) {
|
||||
// let declare a variable
|
||||
// with 2 comments before
|
||||
int/*int*/ a /* it's a */ = 2 /* it's 2 */ + 1 /* it's 1 */; // variable a declared
|
||||
} // end of foo
|
||||
|
||||
int/* we return int*/ foo(int/*int*/ p/* parameter p */) { /* body is empty */ }
|
||||
|
||||
private/*it's private*/ int field = 0;
|
||||
|
||||
public /*it's public*/ char foo() { }
|
||||
|
||||
protected/*it's protected*/ void foo() { }
|
||||
|
||||
public/*it's public*/ static/*and static*/ final/*and final*/ int C = 1;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package foo
|
||||
|
||||
class A() {
|
||||
fun /* nothing to return */ foo(/* no parameters at all */) {
|
||||
// let declare a variable
|
||||
// with 2 comments before
|
||||
val /*int*/ a /* it's a */ = 2 /* it's 2 */ + 1 /* it's 1 */ // variable a declared
|
||||
} // end of foo
|
||||
|
||||
fun /* we return int*/ foo(/*int*/ p: Int/* parameter p */): Int {
|
||||
/* body is empty */
|
||||
}
|
||||
|
||||
private /*it's private*/ var field: Int = 0
|
||||
|
||||
public /*it's public*/ fun foo(): Char {
|
||||
}
|
||||
|
||||
protected /*it's protected*/ fun foo() {
|
||||
}
|
||||
|
||||
class object {
|
||||
|
||||
public /*it's public*//*and static*//*and final*/ val C: Int = 1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user