KT-696 Create a bunch of functions for java.lang.Object compatibility

This commit is contained in:
Sergey Ignatov
2011-12-06 17:33:00 +04:00
parent 6cc8caa1eb
commit 91689b59b0
10 changed files with 178 additions and 17 deletions
+23 -3
View File
@@ -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;
@@ -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()
+3 -3
View File
@@ -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()
+35
View File
@@ -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();
}
}
+23
View File
@@ -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()
}
}