KT-696 Create a bunch of functions for java.lang.Object compatibility
This commit is contained in:
@@ -26,6 +26,10 @@ public class Converter {
|
||||
}
|
||||
} ;
|
||||
private static Set<String> ourClassIdentifiers = new HashSet<String>();
|
||||
private static final Dispatcher ourDispatcher = new Dispatcher();
|
||||
// private static ExpressionVisitor ourExpressionVisitor = new ExpressionVisitor();
|
||||
|
||||
private static final java.lang.Class<ExpressionVisitor> visitorClass = ExpressionVisitor.class;
|
||||
|
||||
public static void setClassIdentifiers(Set<String> identifiers) {
|
||||
ourClassIdentifiers = identifiers;
|
||||
@@ -107,7 +111,7 @@ public class Converter {
|
||||
List<Statement> result = new LinkedList<Statement>();
|
||||
for (Field f : fields) {
|
||||
final String identifierToKotlin = f.getIdentifier().toKotlin();
|
||||
result.add(new DummyStringStatement("$" + identifierToKotlin + " = " + identifierToKotlin));
|
||||
result.add(new DummyStringExpression("$" + identifierToKotlin + " = " + identifierToKotlin));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -184,7 +188,7 @@ public class Converter {
|
||||
|
||||
newStatements.add(
|
||||
0,
|
||||
new DummyStringStatement(
|
||||
new DummyStringExpression(
|
||||
"val __ = " + createPrimaryConstructorInvocation(
|
||||
name.toKotlin(),
|
||||
finalOrWithEmptyInitializer,
|
||||
@@ -294,6 +298,11 @@ public class Converter {
|
||||
|
||||
@NotNull
|
||||
private static Function methodToFunction(@NotNull PsiMethod method, boolean notEmpty) {
|
||||
if (isOverrideObjectDirect(method))
|
||||
ourDispatcher.setExpressionVisitor(new ExpressionVisitorForDirectObjectInheritors());
|
||||
else
|
||||
ourDispatcher.setExpressionVisitor(new ExpressionVisitor());
|
||||
|
||||
final IdentifierImpl identifier = new IdentifierImpl(method.getName());
|
||||
final Type returnType = typeToType(method.getReturnType(), isNotNull(method.getModifierList()));
|
||||
final Block body = blockToBlock(method.getBody(), notEmpty);
|
||||
@@ -350,6 +359,17 @@ public class Converter {
|
||||
return counter > 0;
|
||||
}
|
||||
|
||||
private static boolean isOverrideObjectDirect(@NotNull final PsiMethod method) {
|
||||
List<HierarchicalMethodSignature> superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures();
|
||||
if (superSignatures.size() == 1) {
|
||||
final PsiClass containingClass = superSignatures.get(0).getMethod().getContainingClass();
|
||||
final String qualifiedName = containingClass != null ? containingClass.getQualifiedName() : "";
|
||||
if (qualifiedName != null && qualifiedName.equals("java.lang.Object"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Block blockToBlock(@Nullable PsiCodeBlock block, boolean notEmpty) {
|
||||
if (block == null) return Block.EMPTY_BLOCK;
|
||||
@@ -386,7 +406,7 @@ public class Converter {
|
||||
@NotNull
|
||||
public static Expression expressionToExpression(@Nullable PsiExpression e) {
|
||||
if (e == null) return Expression.EMPTY_EXPRESSION;
|
||||
final ExpressionVisitor expressionVisitor = new ExpressionVisitor();
|
||||
final ExpressionVisitor expressionVisitor = ourDispatcher.getExpressionVisitor();
|
||||
e.accept(expressionVisitor);
|
||||
return expressionVisitor.getResult();
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author ignatov
|
||||
*/
|
||||
public class DummyMethodCallExpression extends Expression {
|
||||
private final Expression myWho;
|
||||
private final Element myWho;
|
||||
private final String myMethodName;
|
||||
private final Expression myWhat;
|
||||
private final Element myWhat;
|
||||
|
||||
public DummyMethodCallExpression(Expression who, String methodName, Expression what) {
|
||||
public DummyMethodCallExpression(Element who, String methodName, Element what) {
|
||||
myWho = who;
|
||||
myMethodName = methodName;
|
||||
myWhat = what;
|
||||
|
||||
+2
-2
@@ -5,10 +5,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author ignatov
|
||||
*/
|
||||
public class DummyStringStatement extends Statement {
|
||||
public class DummyStringExpression extends Expression {
|
||||
private final String myString;
|
||||
|
||||
public DummyStringStatement(String string) {
|
||||
public DummyStringExpression(String string) {
|
||||
myString = string;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.jetbrains.jet.j2k.visitors;
|
||||
|
||||
/**
|
||||
* @author ignatov
|
||||
*/
|
||||
public class Dispatcher {
|
||||
private ExpressionVisitor myExpressionVisitor;
|
||||
|
||||
public void setExpressionVisitor(final ExpressionVisitor expressionVisitor) {
|
||||
this.myExpressionVisitor = expressionVisitor;
|
||||
}
|
||||
|
||||
public Dispatcher() {
|
||||
myExpressionVisitor = new ExpressionVisitor();
|
||||
}
|
||||
|
||||
public ExpressionVisitor getExpressionVisitor() {
|
||||
return myExpressionVisitor;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,12 @@ import static org.jetbrains.jet.j2k.Converter.*;
|
||||
* @author ignatov
|
||||
*/
|
||||
public class ExpressionVisitor extends StatementVisitor {
|
||||
private Expression myResult = Expression.EMPTY_EXPRESSION;
|
||||
Expression myResult = Expression.EMPTY_EXPRESSION;
|
||||
|
||||
@Override
|
||||
public void visitExpression(final PsiExpression expression) {
|
||||
myResult = Expression.EMPTY_EXPRESSION;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -295,7 +300,7 @@ public class ExpressionVisitor extends StatementVisitor {
|
||||
final boolean hasReceiver = isFieldReference && insideSecondaryConstructor;
|
||||
final boolean isThis = isThisExpression(expression);
|
||||
final boolean isNullable = typeToType(expression.getType()).isNullable();
|
||||
final String className = getClassName(expression);
|
||||
final String className = getClassNameWithConstructor(expression);
|
||||
|
||||
Expression identifier = new IdentifierImpl(expression.getReferenceName(), isNullable);
|
||||
|
||||
@@ -316,7 +321,7 @@ public class ExpressionVisitor extends StatementVisitor {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getClassName(@NotNull PsiReferenceExpression expression) {
|
||||
static String getClassNameWithConstructor(@NotNull PsiReferenceExpression expression) {
|
||||
PsiElement context = expression.getContext();
|
||||
while (context != null) {
|
||||
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
|
||||
@@ -332,6 +337,21 @@ public class ExpressionVisitor extends StatementVisitor {
|
||||
return "";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static String getClassName(@NotNull PsiExpression expression) {
|
||||
PsiElement context = expression.getContext();
|
||||
while (context != null) {
|
||||
if (context instanceof PsiClass) {
|
||||
final PsiClass containingClass = (PsiClass) context;
|
||||
final PsiIdentifier identifier = containingClass.getNameIdentifier();
|
||||
if (identifier != null)
|
||||
return identifier.getText();
|
||||
}
|
||||
context = context.getContext();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static boolean isFieldReference(@NotNull PsiReferenceExpression expression, PsiClass currentClass) {
|
||||
final PsiReference reference = expression.getReference();
|
||||
if (reference != null) {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.jetbrains.jet.j2k.visitors;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.j2k.Converter;
|
||||
import org.jetbrains.jet.j2k.ast.DummyMethodCallExpression;
|
||||
import org.jetbrains.jet.j2k.ast.DummyStringExpression;
|
||||
import org.jetbrains.jet.j2k.ast.IdentifierImpl;
|
||||
|
||||
/**
|
||||
* @author ignatov
|
||||
*/
|
||||
public class ExpressionVisitorForDirectObjectInheritors extends ExpressionVisitor {
|
||||
@Override
|
||||
public void visitMethodCallExpression(@NotNull final PsiMethodCallExpression expression) {
|
||||
if (superMethodInvocation(expression.getMethodExpression(), "hashCode"))
|
||||
myResult = new DummyMethodCallExpression(new IdentifierImpl("System"), "identityHashCode", new IdentifierImpl("this"));
|
||||
else if (superMethodInvocation(expression.getMethodExpression(), "equals"))
|
||||
myResult = new DummyMethodCallExpression(new IdentifierImpl("this"), "identityEquals", Converter.elementToElement(expression.getArgumentList()));
|
||||
else if (superMethodInvocation(expression.getMethodExpression(), "toString"))
|
||||
myResult = new DummyStringExpression(String.format("getJavaClass<%s>.getName() + '@' + Integer.toHexString(hashCode())", getClassName(expression.getMethodExpression())));
|
||||
else
|
||||
super.visitMethodCallExpression(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(@NotNull final PsiReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
}
|
||||
|
||||
private static boolean superMethodInvocation(@NotNull final PsiReferenceExpression expression, final String methodName) {
|
||||
String referenceName = expression.getReferenceName();
|
||||
PsiExpression qualifierExpression = expression.getQualifierExpression();
|
||||
if (referenceName != null && referenceName.equals(methodName)) {
|
||||
if (qualifierExpression instanceof PsiSuperExpression) {
|
||||
PsiType type = qualifierExpression.getType();
|
||||
if (type != null && type.getCanonicalText().equals("java.lang.Object"))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -18,16 +18,16 @@ super.finalize()
|
||||
}
|
||||
open class Base() {
|
||||
open public fun hashCode() : Int {
|
||||
return super.hashCode()
|
||||
return System.identityHashCode(this)
|
||||
}
|
||||
open public fun equals(o : Any?) : Boolean {
|
||||
return super.equals(o)
|
||||
return this.identityEquals(o)
|
||||
}
|
||||
open protected fun clone() : Any? {
|
||||
return super.clone()
|
||||
}
|
||||
open public fun toString() : String? {
|
||||
return super.toString()
|
||||
return getJavaClass<Base>.getName() + '@' + Integer.toHexString(hashCode())
|
||||
}
|
||||
open protected fun finalize() : Unit {
|
||||
super.finalize()
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
namespace test
|
||||
open class Test() {
|
||||
open public fun hashCode() : Int {
|
||||
return super.hashCode()
|
||||
return System.identityHashCode(this)
|
||||
}
|
||||
open public fun equals(o : Any?) : Boolean {
|
||||
return super.equals(o)
|
||||
return this.identityEquals(o)
|
||||
}
|
||||
open protected fun clone() : Any? {
|
||||
return super.clone()
|
||||
}
|
||||
open public fun toString() : String? {
|
||||
return super.toString()
|
||||
return getJavaClass<Test>.getName() + '@' + Integer.toHexString(hashCode())
|
||||
}
|
||||
open protected fun finalize() : Unit {
|
||||
super.finalize()
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package test;
|
||||
|
||||
class Base {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Base {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace test
|
||||
open class Base() {
|
||||
open public fun hashCode() : Int {
|
||||
return System.identityHashCode(this)
|
||||
}
|
||||
open public fun equals(o : Any?) : Boolean {
|
||||
return this.identityEquals(o)
|
||||
}
|
||||
open public fun toString() : String? {
|
||||
return getJavaClass<Base>.getName() + '@' + Integer.toHexString(hashCode())
|
||||
}
|
||||
}
|
||||
open class Child() : Base() {
|
||||
override public fun hashCode() : Int {
|
||||
return super.hashCode()
|
||||
}
|
||||
override public fun equals(o : Any?) : Boolean {
|
||||
return super.equals(o)
|
||||
}
|
||||
override public fun toString() : String? {
|
||||
return super.toString()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user