J2K: singletons are back

This commit is contained in:
Valentin Kipyatkov
2014-10-29 16:45:48 +03:00
committed by valentin
parent 567bb6fd1a
commit 7de15ec2a8
18 changed files with 55 additions and 44 deletions
@@ -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()
+7 -7
View File
@@ -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)
}
+1 -1
View File
@@ -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)
+16 -7
View File
@@ -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
}
}
}