J2K: singletons are back
This commit is contained in:
committed by
valentin
parent
567bb6fd1a
commit
7de15ec2a8
@@ -31,7 +31,7 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
private fun convertAnnotationsOnly(owner: PsiModifierListOwner): Annotations {
|
||||
val modifierList = owner.getModifierList()
|
||||
val annotations = modifierList?.getAnnotations()?.filter { it.getQualifiedName() !in annotationsToRemove }
|
||||
if (annotations == null || annotations.isEmpty()) return Annotations.Empty()
|
||||
if (annotations == null || annotations.isEmpty()) return Annotations.Empty
|
||||
|
||||
val newLines = run {
|
||||
if (!modifierList!!.isInSingleLine()) {
|
||||
|
||||
@@ -68,7 +68,7 @@ class CodeConverter(public val converter: Converter,
|
||||
= CodeConverter(converter, expressionConverter, statementConverter, methodReturnType)
|
||||
|
||||
public fun convertBlock(block: PsiCodeBlock?, notEmpty: Boolean = true, statementFilter: (PsiStatement) -> Boolean = { true }): Block {
|
||||
if (block == null) return Block.Empty()
|
||||
if (block == null) return Block.Empty
|
||||
|
||||
val lBrace = LBrace().assignPrototype(block.getLBrace())
|
||||
val rBrace = RBrace().assignPrototype(block.getRBrace())
|
||||
@@ -103,7 +103,7 @@ class CodeConverter(public val converter: Converter,
|
||||
}
|
||||
|
||||
public fun convertExpression(expression: PsiExpression?, expectedType: PsiType?): Expression {
|
||||
if (expression == null) return Identifier.Empty()
|
||||
if (expression == null) return Identifier.Empty
|
||||
|
||||
var convertedExpression = convertExpression(expression)
|
||||
if (expectedType == null || expectedType == PsiType.VOID) return convertedExpression
|
||||
|
||||
@@ -166,7 +166,7 @@ class ConstructorConverter(private val psiClass: PsiClass,
|
||||
val params = converter.convertParameterList(constructor.getParameterList())
|
||||
val containingClass = constructor.getContainingClass()
|
||||
val typeParameterList = converter.convertTypeParameterList(containingClass?.getTypeParameterList())
|
||||
val factoryFunctionType = ClassType(ReferenceElement(containingClass?.declarationIdentifier() ?: Identifier.Empty(), typeParameterList.parameters).assignNoPrototype(),
|
||||
val factoryFunctionType = ClassType(ReferenceElement(containingClass?.declarationIdentifier() ?: Identifier.Empty, typeParameterList.parameters).assignNoPrototype(),
|
||||
Nullability.NotNull,
|
||||
converter.settings).assignNoPrototype()
|
||||
|
||||
@@ -254,7 +254,7 @@ class ConstructorConverter(private val psiClass: PsiClass,
|
||||
}
|
||||
}
|
||||
else {
|
||||
{ it -> Block.Empty() }
|
||||
{ it -> Block.Empty }
|
||||
}
|
||||
|
||||
// we need to replace renamed parameter usages in base class constructor arguments and in default values
|
||||
@@ -359,11 +359,11 @@ class ConstructorConverter(private val psiClass: PsiClass,
|
||||
Parameter(property.identifier, property.type, varValModifier, property.annotations, property.modifiers.filter { it in ACCESS_MODIFIERS }).assignPrototypesFrom(property)
|
||||
}
|
||||
|
||||
val modifiers = Modifiers.Empty()
|
||||
val modifiers = Modifiers.Empty
|
||||
//TODO: we can generate it private when secondary constructors are supported by Kotlin
|
||||
//val modifiers = Modifiers(listOf(Modifier.PRIVATE)).assignNoPrototype()
|
||||
val parameterList = ParameterList(parameters).assignNoPrototype()
|
||||
val constructorSignature = PrimaryConstructorSignature(Annotations.Empty(), modifiers, parameterList).assignNoPrototype()
|
||||
val constructorSignature = PrimaryConstructorSignature(Annotations.Empty, modifiers, parameterList).assignNoPrototype()
|
||||
val updatedMembers = classBody.members.filter { !propertiesToInitialize.contains(it) }
|
||||
return ClassBody(constructorSignature, classBody.baseClassParams, updatedMembers, classBody.classObjectMembers, classBody.factoryFunctions, classBody.lBrace, classBody.rBrace)
|
||||
}
|
||||
@@ -395,7 +395,7 @@ class ConstructorConverter(private val psiClass: PsiClass,
|
||||
statements[i] = ReturnStatement(constructorCall).assignNoPrototype()
|
||||
return statements
|
||||
}
|
||||
val localVar = LocalVariable(tempValIdentifier(), Annotations.Empty(), Modifiers.Empty(), null, constructorCall, true).assignNoPrototype()
|
||||
val localVar = LocalVariable(tempValIdentifier(), Annotations.Empty, Modifiers.Empty, null, constructorCall, true).assignNoPrototype()
|
||||
statements[i] = DeclarationStatement(listOf(localVar)).assignNoPrototype()
|
||||
statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype())
|
||||
return statements
|
||||
@@ -439,8 +439,8 @@ class ConstructorConverter(private val psiClass: PsiClass,
|
||||
val initializer = MethodCallExpression.buildNotNull(null, className, arguments).assignNoPrototype()
|
||||
if (statements.isNotEmpty()) {
|
||||
val localVar = LocalVariable(tempValIdentifier(),
|
||||
Annotations.Empty(),
|
||||
Modifiers.Empty(),
|
||||
Annotations.Empty,
|
||||
Modifiers.Empty,
|
||||
null,
|
||||
initializer,
|
||||
true).assignNoPrototype()
|
||||
|
||||
@@ -236,7 +236,7 @@ class Converter private(private val elementToConvert: PsiElement,
|
||||
annotationConverter.convertAnnotationMethodDefault(method)).assignPrototype(method, noBlankLinesInheritance)
|
||||
}
|
||||
val parameterList = ParameterList(parameters).assignNoPrototype()
|
||||
val constructorSignature = PrimaryConstructorSignature(Annotations.Empty(), Modifiers.Empty(), parameterList).assignNoPrototype()
|
||||
val constructorSignature = PrimaryConstructorSignature(Annotations.Empty, Modifiers.Empty, parameterList).assignNoPrototype()
|
||||
|
||||
// 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, false).convertBody()
|
||||
@@ -246,7 +246,7 @@ class Converter private(private val elementToConvert: PsiElement,
|
||||
return Class(psiClass.declarationIdentifier(),
|
||||
convertAnnotations(psiClass) + Annotations(listOf(annotationAnnotation)),
|
||||
convertModifiers(psiClass).without(Modifier.ABSTRACT),
|
||||
TypeParameterList.Empty(),
|
||||
TypeParameterList.Empty,
|
||||
listOf(),
|
||||
listOf(),
|
||||
listOf(),
|
||||
@@ -331,8 +331,8 @@ class Converter private(private val elementToConvert: PsiElement,
|
||||
for (parameter in method.getParameterList().getParameters()) {
|
||||
if (parameter.hasWriteAccesses(referenceSearcher, method)) {
|
||||
val variable = LocalVariable(parameter.declarationIdentifier(),
|
||||
Annotations.Empty(),
|
||||
Modifiers.Empty(),
|
||||
Annotations.Empty,
|
||||
Modifiers.Empty,
|
||||
null,
|
||||
parameter.declarationIdentifier(),
|
||||
false).assignNoPrototype()
|
||||
@@ -479,7 +479,7 @@ class Converter private(private val elementToConvert: PsiElement,
|
||||
public fun convertParameter(parameter: PsiParameter,
|
||||
nullability: Nullability = Nullability.Default,
|
||||
varValModifier: Parameter.VarValModifier = Parameter.VarValModifier.None,
|
||||
modifiers: Modifiers = Modifiers.Empty(),
|
||||
modifiers: Modifiers = Modifiers.Empty,
|
||||
defaultValue: DeferredElement<Expression>? = null): Parameter {
|
||||
var type = typeConverter.convertVariableType(parameter)
|
||||
when (nullability) {
|
||||
@@ -491,7 +491,7 @@ class Converter private(private val elementToConvert: PsiElement,
|
||||
}
|
||||
|
||||
public fun convertIdentifier(identifier: PsiIdentifier?): Identifier {
|
||||
if (identifier == null) return Identifier.Empty()
|
||||
if (identifier == null) return Identifier.Empty
|
||||
|
||||
return Identifier(identifier.getText()!!).assignPrototype(identifier)
|
||||
}
|
||||
@@ -513,7 +513,7 @@ class Converter private(private val elementToConvert: PsiElement,
|
||||
val types = throwsList.getReferencedTypes()
|
||||
val refElements = throwsList.getReferenceElements()
|
||||
assert(types.size == refElements.size)
|
||||
if (types.isEmpty()) return Annotations.Empty()
|
||||
if (types.isEmpty()) return Annotations.Empty
|
||||
val arguments = types.indices.map { index ->
|
||||
val convertedType = typeConverter.convertType(types[index], Nullability.NotNull)
|
||||
null to deferredElement<Expression> { MethodCallExpression.buildNotNull(null, "javaClass", listOf(), listOf(convertedType)).assignPrototype(refElements[index]) }
|
||||
|
||||
@@ -398,13 +398,13 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
override fun visitSuperExpression(expression: PsiSuperExpression) {
|
||||
val psiQualifier = expression.getQualifier()
|
||||
val qualifier = psiQualifier?.getReferenceName()
|
||||
result = SuperExpression(if (qualifier != null) Identifier(qualifier).assignPrototype(psiQualifier) else Identifier.Empty())
|
||||
result = SuperExpression(if (qualifier != null) Identifier(qualifier).assignPrototype(psiQualifier) else Identifier.Empty)
|
||||
}
|
||||
|
||||
override fun visitThisExpression(expression: PsiThisExpression) {
|
||||
val psiQualifier = expression.getQualifier()
|
||||
val qualifier = psiQualifier?.getReferenceName()
|
||||
result = ThisExpression(if (qualifier != null) Identifier(qualifier).assignPrototype(psiQualifier) else Identifier.Empty())
|
||||
result = ThisExpression(if (qualifier != null) Identifier(qualifier).assignPrototype(psiQualifier) else Identifier.Empty)
|
||||
}
|
||||
|
||||
override fun visitTypeCastExpression(expression: PsiTypeCastExpression) {
|
||||
|
||||
@@ -65,7 +65,7 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
|
||||
override fun visitBreakStatement(statement: PsiBreakStatement) {
|
||||
if (statement.getLabelIdentifier() == null) {
|
||||
result = BreakStatement(Identifier.Empty())
|
||||
result = BreakStatement(Identifier.Empty)
|
||||
}
|
||||
else {
|
||||
result = BreakStatement(converter.convertIdentifier(statement.getLabelIdentifier()))
|
||||
@@ -74,7 +74,7 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
|
||||
override fun visitContinueStatement(statement: PsiContinueStatement) {
|
||||
if (statement.getLabelIdentifier() == null) {
|
||||
result = ContinueStatement(Identifier.Empty())
|
||||
result = ContinueStatement(Identifier.Empty)
|
||||
}
|
||||
else {
|
||||
result = ContinueStatement(converter.convertIdentifier(statement.getLabelIdentifier()))
|
||||
@@ -190,7 +190,7 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
convertedType,
|
||||
Parameter.VarValModifier.None,
|
||||
annotations,
|
||||
Modifiers.Empty()).assignPrototype(parameter)
|
||||
Modifiers.Empty).assignPrototype(parameter)
|
||||
catches.add(CatchStatement(convertedParameter, blockConverted).assignNoPrototype())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ class Annotations(val annotations: List<Annotation>) : Element() {
|
||||
fun plus(other: Annotations) = Annotations(annotations + other.annotations).assignNoPrototype()
|
||||
|
||||
class object {
|
||||
fun Empty() = Annotations(listOf())
|
||||
val Empty = Annotations(listOf())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(), Modifiers.Empty(), 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)
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class Block(val statements: List<Statement>, val lBrace: LBrace, val rBrace: RBr
|
||||
}
|
||||
|
||||
class object {
|
||||
fun Empty() = Block(listOf(), LBrace(), RBrace())
|
||||
val Empty = Block(listOf(), LBrace(), RBrace())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class PrimaryConstructor(annotations: Annotations,
|
||||
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)
|
||||
|
||||
@@ -57,7 +57,18 @@ fun Element.canonicalCode(): String {
|
||||
}
|
||||
|
||||
abstract class Element {
|
||||
public open var prototypes: List<PrototypeInfo>? = null
|
||||
public var prototypes: List<PrototypeInfo>? = null
|
||||
set(value) {
|
||||
// do not assign prototypes to singleton instances
|
||||
if (canBeSingleton) {
|
||||
$prototypes = listOf()
|
||||
return
|
||||
}
|
||||
$prototypes = value
|
||||
}
|
||||
|
||||
protected open val canBeSingleton: Boolean
|
||||
get() = isEmpty
|
||||
|
||||
public var createdAt: String?
|
||||
= if (saveCreationStacktraces)
|
||||
@@ -75,7 +86,6 @@ abstract class Element {
|
||||
object Empty : Element() {
|
||||
override fun generateCode(builder: CodeBuilder) { }
|
||||
override val isEmpty: Boolean get() = true
|
||||
override var prototypes: List<PrototypeInfo>? by EmptyElementPrototypes // to not hold references to psi
|
||||
}
|
||||
|
||||
class object {
|
||||
@@ -83,11 +93,6 @@ abstract class Element {
|
||||
}
|
||||
}
|
||||
|
||||
object EmptyElementPrototypes {
|
||||
public fun get(thisRef: Element, desc: PropertyMetadata): List<PrototypeInfo>? = null
|
||||
public fun set(thisRef: Element, desc: PropertyMetadata, value: List<PrototypeInfo>?) { }
|
||||
}
|
||||
|
||||
// this class should never be created directly - Converter.deferredElement() should be used!
|
||||
class DeferredElement<TResult : Element>(
|
||||
private var generator: (CodeConverter) -> TResult,
|
||||
@@ -100,6 +105,10 @@ class DeferredElement<TResult : Element>(
|
||||
assignNoPrototype()
|
||||
}
|
||||
|
||||
// need to override it to not use isEmpty
|
||||
override val canBeSingleton: Boolean
|
||||
get() = false
|
||||
|
||||
public fun unfold(codeConverter: CodeConverter) {
|
||||
assert(result == null)
|
||||
result = generator(codeConverter)
|
||||
|
||||
@@ -25,6 +25,5 @@ abstract class Expression() : Statement() {
|
||||
object Empty : Expression() {
|
||||
override fun generateCode(builder: CodeBuilder) {}
|
||||
override val isEmpty: Boolean get() = true
|
||||
override var prototypes: List<PrototypeInfo>? by EmptyElementPrototypes // to not hold references to psi
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.jet.j2k.CodeConverter
|
||||
|
||||
fun PsiNameIdentifierOwner.declarationIdentifier(): Identifier {
|
||||
val name = getName()
|
||||
return if (name != null) Identifier(name, false).assignPrototype(getNameIdentifier()!!) else Identifier.Empty()
|
||||
return if (name != null) Identifier(name, false).assignPrototype(getNameIdentifier()!!) else Identifier.Empty
|
||||
}
|
||||
|
||||
class Identifier(
|
||||
@@ -51,7 +51,7 @@ class Identifier(
|
||||
override fun toString() = if (isNullable) "$name?" else name
|
||||
|
||||
class object {
|
||||
fun Empty() = Identifier("")
|
||||
val Empty = Identifier("")
|
||||
|
||||
val ONLY_KOTLIN_KEYWORDS: Set<String> = setOf(
|
||||
"package", "as", "type", "val", "var", "fun", "is", "in", "object", "when", "trait", "This"
|
||||
|
||||
@@ -18,11 +18,15 @@ package org.jetbrains.jet.j2k.ast
|
||||
|
||||
import org.jetbrains.jet.j2k.*
|
||||
|
||||
class Initializer(val body: DeferredElement<Block>, modifiers: Modifiers) : Member(Annotations.Empty(), modifiers) {
|
||||
class Initializer(val body: DeferredElement<Block>, modifiers: Modifiers) : Member(Annotations.Empty, modifiers) {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
builder.append(body)
|
||||
}
|
||||
|
||||
override val isEmpty: Boolean
|
||||
get() = body.isEmpty
|
||||
|
||||
// need to override it to not use isEmpty
|
||||
override val canBeSingleton: Boolean
|
||||
get() = false
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class Modifiers(val modifiers: Collection<Modifier>) : Element() {
|
||||
fun accessModifier(): Modifier? = modifiers.firstOrNull { it in ACCESS_MODIFIERS }
|
||||
|
||||
class object {
|
||||
fun Empty() = Modifiers(listOf())
|
||||
val Empty = Modifiers(listOf())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ abstract class Statement() : Element() {
|
||||
object Empty : Statement() {
|
||||
override fun generateCode(builder: CodeBuilder) { }
|
||||
override val isEmpty: Boolean get() = true
|
||||
override var prototypes: List<PrototypeInfo>? by EmptyElementPrototypes // to not hold references to psi
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,13 +105,13 @@ class ForeachStatement(
|
||||
}
|
||||
}
|
||||
|
||||
class BreakStatement(val label: Identifier = Identifier.Empty()) : Statement() {
|
||||
class BreakStatement(val label: Identifier = Identifier.Empty) : Statement() {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
builder.append("break").appendWithPrefix(label, "@")
|
||||
}
|
||||
}
|
||||
|
||||
class ContinueStatement(val label: Identifier = Identifier.Empty()) : Statement() {
|
||||
class ContinueStatement(val label: Identifier = Identifier.Empty) : Statement() {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
builder.append("continue").appendWithPrefix(label, "@")
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class TypeParameterList(val parameters: List<TypeParameter>) : Element() {
|
||||
private fun hasWhere(): Boolean = parameters.any { it.hasWhere() }
|
||||
|
||||
class object {
|
||||
fun Empty() = TypeParameterList(listOf())
|
||||
val Empty = TypeParameterList(listOf())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,5 +69,5 @@ fun Converter.convertTypeParameterList(typeParameterList: PsiTypeParameterList?)
|
||||
return if (typeParameterList != null)
|
||||
TypeParameterList(typeParameterList.getTypeParameters()!!.toList().map { convertTypeParameter(it) }).assignPrototype(typeParameterList)
|
||||
else
|
||||
TypeParameterList.Empty()
|
||||
TypeParameterList.Empty
|
||||
}
|
||||
@@ -39,7 +39,7 @@ class FieldToPropertyProcessing(val field: PsiField, val propertyName: String, v
|
||||
if (refExpr.resolve() == null)
|
||||
identifier
|
||||
else
|
||||
QualifiedExpression(ThisExpression(Identifier.Empty()).assignNoPrototype(), identifier) //TODO: this is not correct in case of nested/anonymous classes
|
||||
QualifiedExpression(ThisExpression(Identifier.Empty).assignNoPrototype(), identifier) //TODO: this is not correct in case of nested/anonymous classes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user