another one case with constructors supported
This commit is contained in:
@@ -7,12 +7,10 @@ import org.jetbrains.jet.j2k.ast.*;
|
||||
import org.jetbrains.jet.j2k.ast.Class;
|
||||
import org.jetbrains.jet.j2k.ast.Enum;
|
||||
import org.jetbrains.jet.j2k.ast.Modifier;
|
||||
import org.jetbrains.jet.j2k.util.AstUtil;
|
||||
import org.jetbrains.jet.j2k.visitors.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author ignatov
|
||||
@@ -45,6 +43,39 @@ public class Converter {
|
||||
);
|
||||
}
|
||||
|
||||
private static List<Field> getFinalOrWithEmptyInitializer(List<? extends Field> fields) {
|
||||
List<Field> result = new LinkedList<Field>();
|
||||
for (Field f : fields)
|
||||
if (f.isFinal() || f.getInitializer().toKotlin().isEmpty())
|
||||
result.add(f);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<Parameter> createParametersFromFields(List<? extends Field> fields) {
|
||||
List<Parameter> result = new LinkedList<Parameter>();
|
||||
for (Field f : fields)
|
||||
result.add(new Parameter(f.getIdentifier(), f.getType()));
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<Statement> createInitStatementsFromFields(List<? extends Field> fields) {
|
||||
List<Statement> result = new LinkedList<Statement>();
|
||||
for (Field f : fields) {
|
||||
final String identifierToKotlin = f.getIdentifier().toKotlin();
|
||||
result.add(new DummyStringStatement("this." + identifierToKotlin + " = " + identifierToKotlin));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String createPrimaryConstructorInvocation(String s, List<? extends Field> fields, Map<String, String> initializers) {
|
||||
List<String> result = new LinkedList<String>();
|
||||
for (Field f : fields) {
|
||||
final String id = f.getIdentifier().toKotlin();
|
||||
result.add(initializers.get(id));
|
||||
}
|
||||
return s + "(" + AstUtil.join(result, ", ") + ")";
|
||||
}
|
||||
|
||||
public static Class classToClass(PsiClass psiClass) {
|
||||
final Set<String> modifiers = modifiersListToModifiersSet(psiClass.getModifierList());
|
||||
final List<Class> innerClasses = classesToClassList(psiClass.getAllInnerClasses());
|
||||
@@ -53,8 +84,68 @@ public class Converter {
|
||||
final List<Element> typeParameters = elementsToElementList(psiClass.getTypeParameters());
|
||||
final List<Type> implementsTypes = typesToNotNullableTypeList(psiClass.getImplementsListTypes());
|
||||
final List<Type> extendsTypes = typesToNotNullableTypeList(psiClass.getExtendsListTypes());
|
||||
|
||||
final IdentifierImpl name = new IdentifierImpl(psiClass.getName());
|
||||
|
||||
// we create primary constructor
|
||||
if (!psiClass.isEnum() && getPrimaryConstructor(psiClass) == null) {
|
||||
final List<Field> finalOrWithEmptyInitializer = getFinalOrWithEmptyInitializer(fields);
|
||||
final Map<String, String> initializers = new HashMap<String, String>();
|
||||
|
||||
for (Field f : finalOrWithEmptyInitializer) {
|
||||
String init = getDefaultInitializer(f);
|
||||
initializers.put(f.getIdentifier().toKotlin(), init);
|
||||
}
|
||||
|
||||
for (final Function f : methods) {
|
||||
// and modify secondaries
|
||||
if (f.getKind() == INode.Kind.CONSTRUCTOR && !((Constructor) f).isPrimary()) {
|
||||
final List<Statement> newStatements = new LinkedList<Statement>();
|
||||
|
||||
for (Statement s : f.getBlock().getStatements()) {
|
||||
boolean isRemoved = false;
|
||||
|
||||
if (s.getKind() == INode.Kind.ASSINGNMENT_EXPRESSION) {
|
||||
final AssignmentExpression assignmentExpression = (AssignmentExpression) s;
|
||||
if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) {
|
||||
for (Field fo : finalOrWithEmptyInitializer) {
|
||||
final String id = fo.getIdentifier().toKotlin();
|
||||
if (((CallChainExpression) assignmentExpression.getLeft()).getIdentifier().toKotlin().endsWith(id)) {
|
||||
initializers.put(id, assignmentExpression.getRight().toKotlin());
|
||||
isRemoved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isRemoved) {
|
||||
newStatements.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
newStatements.add(
|
||||
0,
|
||||
new DummyStringStatement(
|
||||
"val __ = " + createPrimaryConstructorInvocation(
|
||||
name.toKotlin(),
|
||||
finalOrWithEmptyInitializer,
|
||||
initializers)));
|
||||
|
||||
f.setBlock(new Block(newStatements));
|
||||
}
|
||||
}
|
||||
|
||||
methods.add(
|
||||
new Constructor(
|
||||
Identifier.EMPTY_IDENTIFIER,
|
||||
new HashSet<String>(),
|
||||
new ClassType(name, false),
|
||||
new LinkedList<Element>(),
|
||||
new ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)),
|
||||
new Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)),
|
||||
true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (psiClass.isInterface())
|
||||
return new Trait(name, modifiers, typeParameters, extendsTypes, implementsTypes, innerClasses, methods, fields);
|
||||
if (psiClass.isEnum())
|
||||
@@ -63,6 +154,15 @@ public class Converter {
|
||||
return new Class(name, modifiers, typeParameters, extendsTypes, implementsTypes, innerClasses, methods, fields);
|
||||
}
|
||||
|
||||
private static String getDefaultInitializer(Field f) {
|
||||
if (f.getType().isNullable()) return "null";
|
||||
|
||||
final String typeToKotlin = f.getType().toKotlin();
|
||||
if (typeToKotlin.equals("Boolean")) return "false";
|
||||
if (typeToKotlin.equals("Int")) return "0";
|
||||
return "TYPE: " + typeToKotlin + " HAVEN'T DEFAULT VALUE";
|
||||
}
|
||||
|
||||
// TODO: hack for enums
|
||||
private static List<Field> fieldsToFieldListForEnums(PsiField[] fields) {
|
||||
List<Field> result = new LinkedList<Field>();
|
||||
|
||||
@@ -10,6 +10,14 @@ public class AssignmentExpression extends Expression {
|
||||
private final Expression myRight;
|
||||
private final String myOp;
|
||||
|
||||
public Expression getLeft() {
|
||||
return myLeft;
|
||||
}
|
||||
|
||||
public Expression getRight() {
|
||||
return myRight;
|
||||
}
|
||||
|
||||
public AssignmentExpression(Expression left, Expression right, String op) {
|
||||
myLeft = left;
|
||||
myRight = right;
|
||||
@@ -21,4 +29,10 @@ public class AssignmentExpression extends Expression {
|
||||
public String toKotlin() {
|
||||
return myLeft.toKotlin() + SPACE + myOp + SPACE + myRight.toKotlin();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Kind getKind() {
|
||||
return Kind.ASSINGNMENT_EXPRESSION;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,16 @@ public class CallChainExpression extends Expression {
|
||||
private Expression myExpression;
|
||||
private Expression myIdentifier;
|
||||
|
||||
public Expression getIdentifier() {
|
||||
return myIdentifier;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Kind getKind() {
|
||||
return Kind.CALL_CHAIN;
|
||||
}
|
||||
|
||||
public CallChainExpression(Expression expression, Expression identifier) {
|
||||
myExpression = expression;
|
||||
myIdentifier = identifier;
|
||||
|
||||
@@ -52,7 +52,7 @@ public class Class extends Member {
|
||||
|
||||
String primaryConstructorBodyToKotlin() {
|
||||
Constructor maybeConstructor = getPrimaryConstructor();
|
||||
if (maybeConstructor != null)
|
||||
if (maybeConstructor != null && !maybeConstructor.getBlock().isEmpty())
|
||||
return maybeConstructor.primaryBodyToKotlin();
|
||||
return EMPTY;
|
||||
}
|
||||
@@ -150,10 +150,10 @@ public class Class extends Member {
|
||||
String bodyToKotlin() {
|
||||
return SPACE + "{" + N +
|
||||
AstUtil.joinNodes(getNonStatic(myFields), N) + N +
|
||||
primaryConstructorBodyToKotlin() + N +
|
||||
classObjectToKotlin() + N +
|
||||
AstUtil.joinNodes(getNonStatic(methodsExceptConstructors()), N) + N +
|
||||
AstUtil.joinNodes(getNonStatic(myInnerClasses), N) + N +
|
||||
primaryConstructorBodyToKotlin() + N +
|
||||
"}";
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.jetbrains.jet.j2k.ast;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author ignatov
|
||||
*/
|
||||
public class DummyStringStatement extends Statement {
|
||||
private String myString;
|
||||
|
||||
public DummyStringStatement(String string) {
|
||||
myString = string;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toKotlin() {
|
||||
return myString;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,18 @@ public class Field extends Member {
|
||||
myInitializer = initializer;
|
||||
}
|
||||
|
||||
public Element getInitializer() {
|
||||
return myInitializer;
|
||||
}
|
||||
|
||||
public Identifier getIdentifier() {
|
||||
return myIdentifier;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return myType;
|
||||
}
|
||||
|
||||
String modifiersToKotlin() {
|
||||
List<String> modifierList = new LinkedList<String>();
|
||||
|
||||
@@ -43,6 +55,10 @@ public class Field extends Member {
|
||||
return myModifiers.contains(Modifier.STATIC);
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return myModifiers.contains(Modifier.FINAL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toKotlin() {
|
||||
|
||||
@@ -15,7 +15,13 @@ public class Function extends Member {
|
||||
private final Type myType;
|
||||
private final List<Element> myTypeParameters;
|
||||
final Element myParams;
|
||||
final Block myBlock;
|
||||
|
||||
// TODO: maybe remove it?
|
||||
public void setBlock(Block block) {
|
||||
myBlock = block;
|
||||
}
|
||||
|
||||
Block myBlock;
|
||||
|
||||
public Function(Identifier name, Set<String> modifiers, Type type, List<Element> typeParameters, Element params, Block block) {
|
||||
myName = name;
|
||||
|
||||
@@ -13,6 +13,6 @@ public interface INode {
|
||||
public Kind getKind();
|
||||
|
||||
public enum Kind {
|
||||
UNDEFINED, TYPE, CONSTRUCTOR, BREAK, CONTINUE, VARARG, TRAIT,
|
||||
UNDEFINED, TYPE, CONSTRUCTOR, BREAK, CONTINUE, VARARG, TRAIT, ASSINGNMENT_EXPRESSION, CALL_CHAIN,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author ignatov
|
||||
*/
|
||||
public class Parameter extends Expression {
|
||||
private final IdentifierImpl myIdentifier;
|
||||
private final Identifier myIdentifier;
|
||||
private final Type myType;
|
||||
|
||||
public Parameter(IdentifierImpl identifier, Type type) {
|
||||
public Parameter(Identifier identifier, Type type) {
|
||||
myIdentifier = identifier;
|
||||
myType = type;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
open class Library() {
|
||||
open class Library(ourOut : PrintStream?) {
|
||||
class object {
|
||||
val ourOut : PrintStream?
|
||||
}
|
||||
{
|
||||
this.ourOut = ourOut
|
||||
}
|
||||
}
|
||||
open class User() {
|
||||
open fun main() : Unit {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
open class Library() {
|
||||
open class Library(myString : String?) {
|
||||
public val myString : String?
|
||||
{
|
||||
this.myString = myString
|
||||
}
|
||||
}
|
||||
open class User() {
|
||||
open fun main() : Unit {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
abstract open class Shape() {
|
||||
public var color : String?
|
||||
{
|
||||
}
|
||||
open public fun setColor(c : String?) : Unit {
|
||||
color = c
|
||||
}
|
||||
@@ -9,4 +7,6 @@ open public fun getColor() : String? {
|
||||
return color
|
||||
}
|
||||
abstract open public fun area() : Double
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
class T() {
|
||||
class T(a : String?, b : String?) {
|
||||
var a : String?
|
||||
var b : String?
|
||||
var c : String? = "abc"
|
||||
{
|
||||
this.a = a
|
||||
this.b = b
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
open class C(arg1 : Int, arg2 : Int, arg3 : Int) {
|
||||
{
|
||||
}
|
||||
class object {
|
||||
open fun init(arg1 : Int, arg2 : Int) : C {
|
||||
val __ = C(arg1, arg2, 0)
|
||||
@@ -11,6 +9,8 @@ val __ = C(arg1, 0, 0)
|
||||
return __
|
||||
}
|
||||
}
|
||||
{
|
||||
}
|
||||
}
|
||||
public open class User() {
|
||||
class object {
|
||||
|
||||
@@ -2,11 +2,6 @@ open class C(arg1 : Int) {
|
||||
val myArg1 : Int
|
||||
var myArg2 : Int
|
||||
var myArg3 : Int
|
||||
{
|
||||
$myArg1 = arg1
|
||||
$myArg2 = 0
|
||||
$myArg3 = 0
|
||||
}
|
||||
class object {
|
||||
open fun init(arg1 : Int, arg2 : Int, arg3 : Int) : C {
|
||||
val __ = C(arg1)
|
||||
@@ -21,6 +16,11 @@ __.myArg3 = 0
|
||||
return __
|
||||
}
|
||||
}
|
||||
{
|
||||
$myArg1 = arg1
|
||||
$myArg2 = 0
|
||||
$myArg3 = 0
|
||||
}
|
||||
}
|
||||
public open class User() {
|
||||
class object {
|
||||
|
||||
@@ -2,12 +2,6 @@ namespace org.test.customer {
|
||||
open class Customer(first : String?, last : String?) {
|
||||
public val _firstName : String?
|
||||
public val _lastName : String?
|
||||
{
|
||||
doSmthBefore()
|
||||
$_firstName = first
|
||||
$_lastName = last
|
||||
doSmthAfter()
|
||||
}
|
||||
open public fun getFirstName() : String? {
|
||||
return _firstName
|
||||
}
|
||||
@@ -18,6 +12,12 @@ open private fun doSmthBefore() : Unit {
|
||||
}
|
||||
open private fun doSmthAfter() : Unit {
|
||||
}
|
||||
{
|
||||
doSmthBefore()
|
||||
$_firstName = first
|
||||
$_lastName = last
|
||||
doSmthAfter()
|
||||
}
|
||||
}
|
||||
open class CustomerBuilder() {
|
||||
public var _firstName : String? = "Homer"
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
public class Identifier {
|
||||
private final String myName;
|
||||
private boolean myHasDollar;
|
||||
private boolean myNullable = true;
|
||||
|
||||
public Identifier(String name) {
|
||||
myName = name;
|
||||
}
|
||||
|
||||
public Identifier(String name, boolean isNullable) {
|
||||
myName = name;
|
||||
myNullable = isNullable;
|
||||
}
|
||||
|
||||
public Identifier(String name, boolean hasDollar, boolean isNullable) {
|
||||
myName = name;
|
||||
myHasDollar = hasDollar;
|
||||
myNullable = isNullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
}
|
||||
|
||||
public class User {
|
||||
public static void main() {
|
||||
Identifier i1 = new Identifier("name", false, true);
|
||||
Identifier i2 = new Identifier("name", false);
|
||||
Identifier i3 = new Identifier("name");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
public open class Identifier(myName : String?, myHasDollar : Boolean) {
|
||||
private val myName : String?
|
||||
private var myHasDollar : Boolean
|
||||
private var myNullable : Boolean = true
|
||||
class object {
|
||||
open public fun init(name : String?) : Identifier {
|
||||
val __ = Identifier(name, false)
|
||||
return __
|
||||
}
|
||||
open public fun init(name : String?, isNullable : Boolean) : Identifier {
|
||||
val __ = Identifier(name, false)
|
||||
__.myNullable = isNullable
|
||||
return __
|
||||
}
|
||||
open public fun init(name : String?, hasDollar : Boolean, isNullable : Boolean) : Identifier {
|
||||
val __ = Identifier(name, hasDollar)
|
||||
__.myNullable = isNullable
|
||||
return __
|
||||
}
|
||||
}
|
||||
open public fun getName() : String? {
|
||||
return myName
|
||||
}
|
||||
{
|
||||
this.myName = myName
|
||||
this.myHasDollar = myHasDollar
|
||||
}
|
||||
}
|
||||
public open class User() {
|
||||
class object {
|
||||
open public fun main() : Unit {
|
||||
var i1 : Identifier? = Identifier.init("name", false, true)
|
||||
var i2 : Identifier? = Identifier.init("name", false)
|
||||
var i3 : Identifier? = Identifier.init("name")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
enum Color {
|
||||
WHITE(21)
|
||||
BLACK(22)
|
||||
RED(23)
|
||||
YELLOW(24)
|
||||
BLUE(25)
|
||||
enum Color(c: Int) {
|
||||
WHITE : Color(21)
|
||||
BLACK : Color(22)
|
||||
RED : Color(23)
|
||||
YELLOW : Color(24)
|
||||
BLUE : Color(25)
|
||||
private var code : Int
|
||||
open private (c : Int) {
|
||||
{
|
||||
$code = c
|
||||
}
|
||||
open public fun getCode() : Int {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
class C {
|
||||
Foo f;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class C {
|
||||
private Foo f;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class C {
|
||||
protected Foo f;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class C {
|
||||
public Foo f;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class C {
|
||||
final Foo f = new Foo(1, 2);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class C {
|
||||
Foo f = new Foo(1, 2);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class C {
|
||||
Foo f;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
Foo f;
|
||||
@@ -1 +0,0 @@
|
||||
var f : Foo?
|
||||
@@ -1 +0,0 @@
|
||||
private Foo f;
|
||||
@@ -1 +0,0 @@
|
||||
private var f : Foo?
|
||||
@@ -1 +0,0 @@
|
||||
protected Foo f;
|
||||
@@ -1 +0,0 @@
|
||||
protected var f : Foo?
|
||||
@@ -1 +0,0 @@
|
||||
public Foo f;
|
||||
@@ -1 +0,0 @@
|
||||
public var f : Foo?
|
||||
@@ -1 +0,0 @@
|
||||
final Foo f = new Foo(1, 2);
|
||||
@@ -1 +0,0 @@
|
||||
val f : Foo? = Foo(1, 2)
|
||||
@@ -1 +0,0 @@
|
||||
Foo f = new Foo(1, 2);
|
||||
@@ -1 +0,0 @@
|
||||
var f : Foo? = Foo(1, 2)
|
||||
@@ -1 +0,0 @@
|
||||
Foo f;
|
||||
@@ -1 +0,0 @@
|
||||
var f : Foo?
|
||||
@@ -4,10 +4,10 @@ open class `$`() {
|
||||
}
|
||||
open class `$$`(`$$$$` : `$$$$$`?) : `$` {
|
||||
val `$$$` : `$$$$$`?
|
||||
{
|
||||
$`$$$` = `$$$$`
|
||||
}
|
||||
open public fun `$$$$$$`() : `$$$$$`? {
|
||||
return `$$$`
|
||||
}
|
||||
{
|
||||
$`$$$` = `$$$$`
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@ open fun call() : Unit {
|
||||
}
|
||||
}
|
||||
open class A() : B {
|
||||
{
|
||||
super()
|
||||
}
|
||||
override fun call() : Unit {
|
||||
return super.call()
|
||||
}
|
||||
{
|
||||
super()
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,9 @@ val IN : String? = "in"
|
||||
val AT : String? = "@"
|
||||
val COMMA_WITH_SPACE : String? = (COMMA + SPACE)
|
||||
}
|
||||
{
|
||||
this.IN = IN
|
||||
this.AT = AT
|
||||
this.COMMA_WITH_SPACE = COMMA_WITH_SPACE
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,9 @@ public val IN : String? = "in"
|
||||
public val AT : String? = "@"
|
||||
public val COMMA_WITH_SPACE : String? = (COMMA + SPACE)
|
||||
}
|
||||
{
|
||||
this.IN = IN
|
||||
this.AT = AT
|
||||
this.COMMA_WITH_SPACE = COMMA_WITH_SPACE
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user