Converter:

Refactor handling of primitive types
Inject converter in places of use
Make Element and Node traits
This commit is contained in:
Pavel Talanov
2013-11-05 15:57:43 +04:00
committed by Pavel V. Talanov
parent ca99db3c47
commit 3edefcf598
26 changed files with 80 additions and 51 deletions
+1 -1
View File
@@ -218,7 +218,7 @@ public open class Converter(val project: Project) {
}
}
members.add(Constructor(Identifier.EMPTY_IDENTIFIER, arrayListOf(), Collections.emptySet<Modifier>(),
ClassType(name, Collections.emptyList<Element>(), false),
ClassType(name, Collections.emptyList<Element>(), false, this),
Collections.emptyList<Element>(),
ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)),
Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)),
@@ -19,8 +19,10 @@ package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.jet.j2k.ast.types.ArrayType
import org.jetbrains.jet.j2k.ast.types.isPrimitive
public open class ArrayInitializerExpression(val `type`: Type, val initializers: List<Expression>) : Expression() {
public open class ArrayInitializerExpression(val arrayType: ArrayType, val initializers: List<Expression>) : Expression() {
public override fun toKotlin(): String {
return createArrayFunction() + "(" + createInitializers() + ")"
}
@@ -30,16 +32,16 @@ public open class ArrayInitializerExpression(val `type`: Type, val initializers:
}
private fun createArrayFunction(): String {
var sType: String? = innerTypeStr()
if (Node.PRIMITIVE_TYPES.contains(sType)) {
return sType + "Array"
val elementType = arrayType.elementType
if (elementType.isPrimitive()) {
return (elementType.convertedToNotNull().toKotlin() + "Array").decapitalize()
}
return StringUtil.decapitalize(`type`.convertedToNotNull().toKotlin())!!
return arrayType.convertedToNotNull().toKotlin().decapitalize()
}
private fun innerTypeStr(): String {
return `type`.convertedToNotNull().toKotlin().replace("Array", "").toLowerCase()
return arrayType.convertedToNotNull().toKotlin().replace("Array", "").toLowerCase()
}
private fun explicitConvertIfNeeded(i: Expression): String {
@@ -16,7 +16,7 @@
package org.jetbrains.jet.j2k.ast
public open class CallChainExpression(val expression: Expression, val identifier: Expression) : Expression() {
public class CallChainExpression(val expression: Expression, val identifier: Expression) : Expression() {
public override fun isNullable(): Boolean {
if (!expression.isEmpty() && expression.isNullable()) return true
return identifier.isNullable()
+3 -2
View File
@@ -23,7 +23,7 @@ import org.jetbrains.jet.j2k.ast.types.Type
import java.util.HashSet
import java.util.ArrayList
public open class Class(converter: Converter,
public open class Class(val converter: Converter,
val name: Identifier,
val docComments: List<Node>,
modifiers: Set<Modifier>,
@@ -80,7 +80,8 @@ public open class Class(converter: Converter,
val constructorTypeParameters = ArrayList<Element>()
constructorTypeParameters.addAll(typeParameters)
constructorTypeParameters.addAll(f.typeParameters)
return Function(Identifier("init"), arrayList(), modifiers, ClassType(name, constructorTypeParameters, false),
return Function(Identifier("init"), arrayList(), modifiers,
ClassType(name, constructorTypeParameters, false, converter),
constructorTypeParameters, f.params, block)
}
+4 -4
View File
@@ -17,17 +17,17 @@
package org.jetbrains.jet.j2k.ast
public abstract class Element() : Node() {
public open fun isEmpty(): Boolean = false
public trait Element : Node {
public fun isEmpty(): Boolean = false
class object {
public val EMPTY_ELEMENT: Element = object : Element() {
public val EMPTY_ELEMENT: Element = object : Element {
override fun toKotlin() = ""
override fun isEmpty() = true
}
}
}
public class Comment(val text: String) : Element() {
public class Comment(val text: String) : Element {
override fun toKotlin() = text
}
+1 -1
View File
@@ -19,7 +19,7 @@ package org.jetbrains.jet.j2k.ast
public open class File(val packageName: String,
val imports: MutableList<Import>,
val body: MutableList<Node>,
val mainFunction: String) : Node() {
val mainFunction: String) : Node {
public override fun toKotlin(): String {
val common: String = imports.toKotlin("\n") + "\n\n" + body.toKotlin("\n") + "\n" + mainFunction
+1 -1
View File
@@ -17,6 +17,6 @@
package org.jetbrains.jet.j2k.ast
public open class Import(val name: String) : Node() {
public class Import(val name: String) : Node {
public override fun toKotlin() = "import " + name
}
@@ -17,11 +17,13 @@
package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
import org.jetbrains.jet.j2k.Converter
public class LocalVariable(val identifier: Identifier,
val modifiersSet: Set<Modifier>,
val javaType: Type,
val initializer: Expression) : Expression() {
val initializer: Expression,
val converter: Converter) : Expression() {
public fun isImmutable(): Boolean = forceImmutable || modifiersSet.contains(Modifier.FINAL)
+1 -1
View File
@@ -16,7 +16,7 @@
package org.jetbrains.jet.j2k.ast
public abstract class Member(val modifiers: Set<Modifier>) : Node() {
public abstract class Member(val modifiers: Set<Modifier>) : Node {
open fun accessModifier(): Modifier? {
return modifiers.find { m -> m == Modifier.PUBLIC || m == Modifier.PROTECTED || m == Modifier.PRIVATE }
}
+3 -6
View File
@@ -16,12 +16,9 @@
package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.Converter
public abstract class Node() {
public abstract fun toKotlin(): String
class object {
public val PRIMITIVE_TYPES: Set<String> = hashSet(
"double", "float", "long", "int", "short", "byte", "boolean", "char")
}
public trait Node {
public fun toKotlin(): String
}
@@ -18,6 +18,6 @@ package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
public open class ReferenceElement(val reference: Identifier, val types: List<Type>) : Element() {
public class ReferenceElement(val reference: Identifier, val types: List<Type>) : Element {
public override fun toKotlin() = reference.toKotlin() + types.toKotlin(", ", "<", ">")
}
@@ -17,7 +17,7 @@
package org.jetbrains.jet.j2k.ast
public abstract class Statement() : Element() {
public abstract class Statement() : Element {
class object {
public val EMPTY_STATEMENT: Statement = object : Statement() {
public override fun toKotlin() = ""
@@ -18,7 +18,7 @@ package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
public open class TypeElement(val `type`: Type) : Element() {
public open class TypeElement(val `type`: Type) : Element {
override fun toKotlin() = `type`.toKotlin()
public fun toKotlinNotNull(): String = `type`.convertedToNotNull().toKotlin()
@@ -18,9 +18,9 @@ package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
public open class TypeParameter(val name: Identifier, val extendsTypes: List<Type>) : Element() {
public open fun hasWhere(): Boolean = extendsTypes.size() > 1
public open fun getWhereToKotlin(): String {
public class TypeParameter(val name: Identifier, val extendsTypes: List<Type>) : Element {
public fun hasWhere(): Boolean = extendsTypes.size() > 1
public fun getWhereToKotlin(): String {
if (hasWhere()) {
return name.toKotlin() + " : " + extendsTypes.get(1).toKotlin()
}
@@ -16,7 +16,10 @@
package org.jetbrains.jet.j2k.ast.types
public open class ArrayType(val elementType: Type, nullable: Boolean) : Type(nullable) {
import org.jetbrains.jet.j2k.Converter
public class ArrayType(val elementType: Type, nullable: Boolean,
converter: Converter) : MayBeNullableType(nullable, converter) {
public override fun toKotlin(): String {
if (elementType is PrimitiveType) {
return elementType.toKotlin() + "Array" + isNullableStr()
@@ -25,5 +28,5 @@ public open class ArrayType(val elementType: Type, nullable: Boolean) : Type(nul
return "Array<" + elementType.toKotlin() + ">" + isNullableStr()
}
public override fun convertedToNotNull(): Type = ArrayType(elementType, false)
public override fun convertedToNotNull(): Type = ArrayType(elementType, false, converter)
}
@@ -19,8 +19,11 @@ package org.jetbrains.jet.j2k.ast.types
import org.jetbrains.jet.j2k.ast.Element
import org.jetbrains.jet.j2k.ast.Identifier
import java.util.ArrayList
import org.jetbrains.jet.j2k.Converter
public open class ClassType(val `type`: Identifier, val parameters: List<Element>, nullable: Boolean,
converter: Converter) : MayBeNullableType(nullable, converter) {
public open class ClassType(val `type`: Identifier, val parameters: List<Element>, nullable: Boolean) : Type(nullable) {
public override fun toKotlin(): String {
// TODO change to map() when KT-2051 is fixed
val parametersToKotlin = ArrayList<String>()
@@ -35,5 +38,5 @@ public open class ClassType(val `type`: Identifier, val parameters: List<Element
}
public override fun convertedToNotNull(): Type = ClassType(`type`, parameters, false)
public override fun convertedToNotNull(): Type = ClassType(`type`, parameters, false, converter)
}
@@ -16,6 +16,6 @@
package org.jetbrains.jet.j2k.ast.types
public open class EmptyType() : Type(false) {
public open class EmptyType() : NotNullType {
public override fun toKotlin(): String = "UNRESOLVED_TYPE"
}
@@ -16,6 +16,6 @@
package org.jetbrains.jet.j2k.ast.types
public open class InProjectionType(val bound: Type) : Type(false) {
public open class InProjectionType(val bound: Type) : NotNullType {
public override fun toKotlin(): String = "in " + bound.toKotlin()
}
@@ -16,6 +16,6 @@
package org.jetbrains.jet.j2k.ast.types
public open class OutProjectionType(val bound: Type) : Type(false) {
public open class OutProjectionType(val bound: Type) : NotNullType {
public override fun toKotlin(): String = "out " + bound.toKotlin()
}
@@ -18,6 +18,6 @@ package org.jetbrains.jet.j2k.ast.types
import org.jetbrains.jet.j2k.ast.Identifier
public open class PrimitiveType(val `type`: Identifier) : Type(false) {
public open class PrimitiveType(val `type`: Identifier) : NotNullType {
public override fun toKotlin(): String = `type`.toKotlin()
}
@@ -16,6 +16,6 @@
package org.jetbrains.jet.j2k.ast.types
public open class StarProjectionType() : Type(false) {
public open class StarProjectionType() : NotNullType {
public override fun toKotlin(): String = "*"
}
@@ -17,14 +17,28 @@
package org.jetbrains.jet.j2k.ast.types
import org.jetbrains.jet.j2k.ast.Element
import org.jetbrains.jet.j2k.Converter
public fun Type.isPrimitive(): Boolean = this is PrimitiveType
public abstract class MayBeNullableType(override public val nullable: Boolean, val converter: Converter): Type {
}
public trait NotNullType : Type {
override public val nullable: Boolean
get() = false
}
public trait Type : Element {
public val nullable: Boolean
public abstract class Type(val nullable: Boolean) : Element() {
public open fun convertedToNotNull(): Type {
if (nullable) throw UnsupportedOperationException("convertedToNotNull must be defined")
return this
}
public open fun isNullableStr(): String? {
protected fun isNullableStr(): String? {
return (if (nullable && !forceNotNullTypes)
"?"
else
@@ -16,6 +16,6 @@
package org.jetbrains.jet.j2k.ast.types
public open class VarArg(val `type`: Type) : Type(false) {
public open class VarArg(val `type`: Type) : NotNullType {
public override fun toKotlin(): String = `type`.toKotlin()
}
@@ -43,7 +43,8 @@ public open class ElementVisitor(val myConverter: Converter) : JavaElementVisito
myResult = LocalVariable(Identifier(theVariable.getName()!!),
Converter.modifiersListToModifiersSet(theVariable.getModifierList()),
kType,
myConverter.expressionToExpression(theVariable.getInitializer(), theVariable.getType()))
myConverter.expressionToExpression(theVariable.getInitializer(), theVariable.getType()),
myConverter)
}
public override fun visitExpressionList(list: PsiExpressionList?) {
@@ -28,6 +28,7 @@ import com.intellij.psi.CommonClassNames.*
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.jet.lang.types.lang.PrimitiveType
import org.jetbrains.jet.j2k.isAnnotatedAsNotNull
import org.jetbrains.jet.j2k.ast.types.ArrayType
public open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter) {
{
@@ -47,7 +48,9 @@ public open class ExpressionVisitor(converter: Converter) : StatementVisitor(con
}
public override fun visitArrayInitializerExpression(expression: PsiArrayInitializerExpression?) {
myResult = ArrayInitializerExpression(getConverter().typeToType(expression?.getType()),
val expressionType = getConverter().typeToType(expression?.getType())
assert(expressionType is ArrayType) { "Array initializer must have array type" }
myResult = ArrayInitializerExpression(expressionType as ArrayType,
getConverter().expressionsToExpressionList(expression?.getInitializers()!!))
}
@@ -25,6 +25,9 @@ import org.jetbrains.jet.j2k.ast.types.*
import java.util.LinkedList
import com.intellij.openapi.util.text.StringUtil
import java.util.ArrayList
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType
private val PRIMITIVE_TYPES_NAMES = JvmPrimitiveType.values().map { it.getName() }
public open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisitor<Type>() {
private var myResult: Type = EmptyType()
@@ -37,7 +40,7 @@ public open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisit
if (name == "void") {
myResult = PrimitiveType(Identifier("Unit"))
}
else if (Node.PRIMITIVE_TYPES.contains(name)) {
else if (PRIMITIVE_TYPES_NAMES.contains(name)) {
myResult = PrimitiveType(Identifier(StringUtil.capitalize(name)))
}
else {
@@ -48,7 +51,7 @@ public open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisit
public override fun visitArrayType(arrayType: PsiArrayType?): Type {
if (myResult is EmptyType) {
myResult = ArrayType(myConverter.typeToType(arrayType?.getComponentType()), true)
myResult = ArrayType(myConverter.typeToType(arrayType?.getComponentType()), true, myConverter)
}
return myResult
@@ -63,18 +66,18 @@ public open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisit
if (resolvedClassTypeParams.size() == 1) {
if ((resolvedClassTypeParams.get(0) as ClassType).`type`.name == "Any") {
starParamList.add(StarProjectionType())
myResult = ClassType(identifier, starParamList, true)
myResult = ClassType(identifier, starParamList, true, myConverter)
}
else {
myResult = ClassType(identifier, resolvedClassTypeParams, true)
myResult = ClassType(identifier, resolvedClassTypeParams, true, myConverter)
}
}
else {
myResult = ClassType(identifier, resolvedClassTypeParams, true)
myResult = ClassType(identifier, resolvedClassTypeParams, true, myConverter)
}
}
else {
myResult = ClassType(identifier, myConverter.typesToTypeList(classType.getParameters()), true)
myResult = ClassType(identifier, myConverter.typesToTypeList(classType.getParameters()), true, myConverter)
}
return myResult
}
@@ -121,7 +124,7 @@ public open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisit
val boundType: Type = (if (superTypes.size > 0)
ClassType(Identifier(getClassTypeName(superTypes[0])),
myConverter.typesToTypeList(superTypes[0].getParameters()),
true)
true, myConverter)
else
StarProjectionType())
typeParams.add(boundType)