From 510fb25e806503d42d18be45edd7e5b42a634c86 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Mon, 7 Nov 2011 15:58:32 +0400 Subject: [PATCH] nullable safe calls supported (for methods and instances) --- .../jet/j2k/ast/MethodCallExpression.java | 9 ++++++++- .../jetbrains/jet/j2k/ast/PrimitiveType.java | 5 +++++ src/org/jetbrains/jet/j2k/ast/Type.java | 7 ++++++- .../jet/j2k/visitors/ExpressionVisitor.java | 13 +++++++------ .../ast/callChain/file/libraryMethodCall.jav | 12 ++++++++++++ .../ast/callChain/file/libraryMethodCall.kt | 17 +++++++++++++++++ .../file/libraryMethodCallFromInstance.jav | 16 ++++++++++++++++ .../file/libraryMethodCallFromInstance.kt | 18 ++++++++++++++++++ .../callChain/file/libraryStringFieldCall.jav | 9 +++++++++ .../callChain/file/libraryStringFieldCall.kt | 10 ++++++++++ 10 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 testData/ast/callChain/file/libraryMethodCall.jav create mode 100644 testData/ast/callChain/file/libraryMethodCall.kt create mode 100644 testData/ast/callChain/file/libraryMethodCallFromInstance.jav create mode 100644 testData/ast/callChain/file/libraryMethodCallFromInstance.kt create mode 100644 testData/ast/callChain/file/libraryStringFieldCall.jav create mode 100644 testData/ast/callChain/file/libraryStringFieldCall.kt diff --git a/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.java b/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.java index 9178f9ef278..78f65584a21 100644 --- a/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.java +++ b/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.java @@ -8,10 +8,17 @@ import org.jetbrains.annotations.NotNull; public class MethodCallExpression extends Expression { private final Expression myMethodCall; private final Element myParamList; + private boolean myIsResultNullable; - public MethodCallExpression(Expression methodCall, Element paramList) { + public MethodCallExpression(Expression methodCall, Element paramList, boolean nullable) { myMethodCall = methodCall; myParamList = paramList; + myIsResultNullable = nullable; + } + + @Override + public boolean isNullable() { + return myIsResultNullable; } @NotNull diff --git a/src/org/jetbrains/jet/j2k/ast/PrimitiveType.java b/src/org/jetbrains/jet/j2k/ast/PrimitiveType.java index cb862c0b11c..9a84b467fa2 100644 --- a/src/org/jetbrains/jet/j2k/ast/PrimitiveType.java +++ b/src/org/jetbrains/jet/j2k/ast/PrimitiveType.java @@ -12,6 +12,11 @@ public class PrimitiveType extends Type { myType = type; } + @Override + public boolean isNullable() { + return false; + } + @NotNull @Override public String toKotlin() { diff --git a/src/org/jetbrains/jet/j2k/ast/Type.java b/src/org/jetbrains/jet/j2k/ast/Type.java index fa6160c5bb3..e8f27fd9eb1 100644 --- a/src/org/jetbrains/jet/j2k/ast/Type.java +++ b/src/org/jetbrains/jet/j2k/ast/Type.java @@ -19,7 +19,7 @@ public abstract class Type extends Element { myNullable = nullable; } - boolean isNullable() { + public boolean isNullable() { return myNullable; } @@ -36,5 +36,10 @@ public abstract class Type extends Element { public String toKotlin() { return "UNRESOLVED_TYPE"; } + + @Override + public boolean isNullable() { + return false; + } } } diff --git a/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java b/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java index 947e9550a65..9af9ed3a73f 100644 --- a/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java +++ b/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java @@ -165,7 +165,8 @@ public class ExpressionVisitor extends StatementVisitor implements Visitor { myResult = // TODO: not resolved new MethodCallExpression( expressionToExpression(expression.getMethodExpression()), - elementToElement(expression.getArgumentList()) + elementToElement(expression.getArgumentList()), + typeToType(expression.getType()).isNullable() ); } @@ -225,11 +226,11 @@ public class ExpressionVisitor extends StatementVisitor implements Visitor { @Override public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); - final IdentifierImpl identifier = expression.getType() != null ? // TODO: if type exists so id is nullable - new IdentifierImpl(expression.getReferenceName()) : - new IdentifierImpl(expression.getReferenceName(), false); - - myResult = new CallChain(expressionToExpression(expression.getQualifierExpression()), identifier); + boolean isNullable = typeToType(expression.getType()).isNullable(); + myResult = new CallChain( + expressionToExpression(expression.getQualifierExpression()), + new IdentifierImpl(expression.getReferenceName(), isNullable) // TODO: if type exists so id is nullable + ); } @Override diff --git a/testData/ast/callChain/file/libraryMethodCall.jav b/testData/ast/callChain/file/libraryMethodCall.jav new file mode 100644 index 00000000000..265696edc72 --- /dev/null +++ b/testData/ast/callChain/file/libraryMethodCall.jav @@ -0,0 +1,12 @@ +class Library { + static void call() {} + + static String getString() { return ""; } +} + +class User { + void main() { + Library.call(); + Library.getString().isEmpty(); + } +} \ No newline at end of file diff --git a/testData/ast/callChain/file/libraryMethodCall.kt b/testData/ast/callChain/file/libraryMethodCall.kt new file mode 100644 index 00000000000..f5e0204d979 --- /dev/null +++ b/testData/ast/callChain/file/libraryMethodCall.kt @@ -0,0 +1,17 @@ +namespace { +open class Library { +class object { +fun call() : Unit { +} +fun getString() : String? { +return "" +} +} +} +open class User { +fun main() : Unit { +Library.call() +Library.getString()?.isEmpty() +} +} +} \ No newline at end of file diff --git a/testData/ast/callChain/file/libraryMethodCallFromInstance.jav b/testData/ast/callChain/file/libraryMethodCallFromInstance.jav new file mode 100644 index 00000000000..3a22446070d --- /dev/null +++ b/testData/ast/callChain/file/libraryMethodCallFromInstance.jav @@ -0,0 +1,16 @@ +class Library { + void call() {} + + String getString() { return ""; } +} + +class User { + void main() { + Library lib = new Library(); + lib.call(); + lib.getString().isEmpty(); + + new Library().call(); + new Library().getString().isEmpty(); + } +} \ No newline at end of file diff --git a/testData/ast/callChain/file/libraryMethodCallFromInstance.kt b/testData/ast/callChain/file/libraryMethodCallFromInstance.kt new file mode 100644 index 00000000000..0160fa34117 --- /dev/null +++ b/testData/ast/callChain/file/libraryMethodCallFromInstance.kt @@ -0,0 +1,18 @@ +namespace { +open class Library { +fun call() : Unit { +} +fun getString() : String? { +return "" +} +} +open class User { +fun main() : Unit { +var lib : Library? = Library() +lib?.call() +lib?.getString()?.isEmpty() +Library().call() +Library().getString()?.isEmpty() +} +} +} \ No newline at end of file diff --git a/testData/ast/callChain/file/libraryStringFieldCall.jav b/testData/ast/callChain/file/libraryStringFieldCall.jav new file mode 100644 index 00000000000..67d826da1d9 --- /dev/null +++ b/testData/ast/callChain/file/libraryStringFieldCall.jav @@ -0,0 +1,9 @@ +class Library { + final public String myString; +} + +class User { + void main() { + Library.myString.isEmpty(); + } +} \ No newline at end of file diff --git a/testData/ast/callChain/file/libraryStringFieldCall.kt b/testData/ast/callChain/file/libraryStringFieldCall.kt new file mode 100644 index 00000000000..382a87f7797 --- /dev/null +++ b/testData/ast/callChain/file/libraryStringFieldCall.kt @@ -0,0 +1,10 @@ +namespace { +open class Library { +public val myString : String? +} +open class User { +fun main() : Unit { +Library.myString?.isEmpty() +} +} +} \ No newline at end of file