supported some generics constrcutors and methods for KT-540

This commit is contained in:
Sergey Ignatov
2011-11-21 16:09:23 +04:00
parent ccb3e63638
commit ef415f4748
5 changed files with 103 additions and 20 deletions
@@ -4,6 +4,7 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.j2k.Converter;
import org.jetbrains.jet.j2k.ast.*;
@@ -185,31 +186,45 @@ public class ExpressionVisitor extends StatementVisitor {
super.visitNewExpression(expression);
if (expression.getArrayInitializer() != null) // new Foo[] {}
myResult = expressionToExpression(expression.getArrayInitializer());
myResult = createNewEmptyArray(expression);
else if (expression.getArrayDimensions().length > 0) { // new Foo[5]
final List<Expression> callExpression = expressionsToExpressionList(expression.getArrayDimensions());
callExpression.add(new IdentifierImpl("{null}")); // TODO: remove
myResult = new NewClassExpression(
typeToType(expression.getType()), // TODO: remove
new ExpressionList(callExpression)
);
myResult = createNewNonEmptyArray(expression);
} else { // new Class(): common case
final PsiAnonymousClass anonymousClass = expression.getAnonymousClass();
myResult = new NewClassExpression(
myResult = createNewClassExpression(expression);
}
}
@NotNull
private Expression createNewClassExpression(@NotNull PsiNewExpression expression) {
final PsiAnonymousClass anonymousClass = expression.getAnonymousClass();
final PsiMethod constructor = expression.resolveMethod();
if (constructor == null || isConstructorPrimary(constructor)) {
return new NewClassExpression(
expressionToExpression(expression.getQualifier()),
elementToElement(expression.getClassOrAnonymousClassReference()),
elementToElement(expression.getArgumentList()),
anonymousClass != null ? anonymousClassToAnonymousClass(anonymousClass) : null
);
// is constructor secondary
final PsiMethod constructor = expression.resolveMethod();
if (constructor != null && !isConstructorPrimary(constructor)) {
myResult = new CallChainExpression(
new IdentifierImpl(constructor.getName(), false),
new MethodCallExpression(new IdentifierImpl("init"), elementToElement(expression.getArgumentList()), false, typesToTypeList(expression.getTypeArguments())));
}
}
// is constructor secondary
return new CallChainExpression(
new IdentifierImpl(constructor.getName(), false),
new MethodCallExpression(new IdentifierImpl("init"), elementToElement(expression.getArgumentList()), false, typesToTypeList(expression.getTypeArguments())));
}
@NotNull
private NewClassExpression createNewNonEmptyArray(@NotNull PsiNewExpression expression) {
final List<Expression> callExpression = expressionsToExpressionList(expression.getArrayDimensions());
callExpression.add(new IdentifierImpl("{null}")); // TODO: remove
return new NewClassExpression(
typeToType(expression.getType()),
new ExpressionList(callExpression)
);
}
@NotNull
private static Expression createNewEmptyArray(@NotNull PsiNewExpression expression) {
return expressionToExpression(expression.getArrayInitializer());
}
@Override
@@ -242,7 +257,7 @@ public class ExpressionVisitor extends StatementVisitor {
public void visitReferenceExpression(PsiReferenceExpression expression) {
super.visitReferenceExpression(expression);
final boolean isFieldReference = isFieldReference(expression);
final boolean isFieldReference = isFieldReference(expression, getContainingClass(expression));
final boolean hasDollar = isFieldReference && isInsidePrimaryConstructor(expression);
final boolean insideSecondaryConstructor = isInsideSecondaryConstructor(expression);
final boolean hasReceiver = isFieldReference && insideSecondaryConstructor;
@@ -285,13 +300,13 @@ public class ExpressionVisitor extends StatementVisitor {
return "";
}
private boolean isFieldReference(PsiReferenceExpression expression) {
private boolean isFieldReference(PsiReferenceExpression expression, PsiClass currentClass) {
final PsiReference reference = expression.getReference();
if (reference != null) {
final PsiElement resolvedReference = reference.resolve();
if (resolvedReference != null) {
if (resolvedReference instanceof PsiField) {
return true;
return ((PsiField) resolvedReference).getContainingClass() == currentClass;
}
}
}
@@ -318,6 +333,17 @@ public class ExpressionVisitor extends StatementVisitor {
return false;
}
@Nullable
private PsiClass getContainingClass(@NotNull PsiExpression expression) {
PsiElement context = expression.getContext();
while (context != null) {
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor())
return ((PsiMethod) context).getContainingClass();
context = context.getContext();
}
return null;
}
private boolean isThisExpression(PsiReferenceExpression expression) {
for (PsiReference r : expression.getReferences())
if (r.getCanonicalText().equals("this")) {
@@ -0,0 +1,15 @@
package demo;
class Collection<E> {
Collection(E e) {
System.out.println(e);
}
}
class Test {
void main() {
Collection raw1 = new Collection(1);
Collection raw2 = new Collection<Integer>(1);
Collection raw3 = new Collection<String>("1");
}
}
@@ -0,0 +1,14 @@
namespace demo {
open class Collection<E>(e : E?) {
{
System.out?.println(e)
}
}
open class Test() {
open fun main() : Unit {
var raw1 : Collection<*>? = Collection(1)
var raw2 : Collection<*>? = Collection<Int?>(1)
var raw3 : Collection<*>? = Collection<String?>("1")
}
}
}
@@ -0,0 +1,14 @@
package demo;
class TestT {
<T> void getT() { }
}
class U {
void main() {
TestT t = new TestT();
t.<String>getT();
t.<Integer>getT();
t.getT();
}
}
@@ -0,0 +1,14 @@
namespace demo {
open class TestT() {
open fun getT<T>() : Unit {
}
}
open class U() {
open fun main() : Unit {
var t : TestT? = TestT()
t?.getT<String?>()
t?.getT<Int?>()
t?.getT()
}
}
}