Merge remote branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-05-16 15:05:59 +04:00
8 changed files with 97 additions and 26 deletions
@@ -6,7 +6,8 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.JetType;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -14,6 +15,7 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -210,6 +212,14 @@ public class ClassCodegen {
iv.invokespecial(superClass, "<init>", /* TODO super constructor descriptor */"()V");
}
HashSet<FunctionDescriptor> overriden = new HashSet<FunctionDescriptor>();
for (JetDeclaration declaration : aClass.getDeclarations()) {
if (declaration instanceof JetFunction) {
overriden.addAll(bindingContext.getFunctionDescriptor((JetFunction) declaration).getOverriddenFunctions());
}
}
int n = 0;
for (JetDelegationSpecifier specifier : specifiers) {
boolean delegateOnStack = specifier instanceof JetDelegatorToSuperCall && n > 0 ||
@@ -267,7 +277,7 @@ public class ClassCodegen {
JetClass superClass = (JetClass) bindingContext.getDeclarationPsiElement(superClassDescriptor);
generateDelegates(aClass, superClass, v,
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false),
JetTypeMapper.jvmNameForInterface(superClassDescriptor)));
JetTypeMapper.jvmNameForInterface(superClassDescriptor)), overriden);
}
n++;
@@ -364,7 +374,7 @@ public class ClassCodegen {
}
}
private void generateDelegates(JetClass inClass, JetClass toClass, ClassVisitor v, OwnerKind kind) {
private void generateDelegates(JetClass inClass, JetClass toClass, ClassVisitor v, OwnerKind kind, Set<FunctionDescriptor> overriden) {
final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
final FunctionCodegen functionCodegen = new FunctionCodegen(toClass, v, standardLibrary, bindingContext);
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, standardLibrary, bindingContext, functionCodegen);
@@ -374,7 +384,9 @@ public class ClassCodegen {
propertyCodegen.gen((JetProperty) declaration, kind);
}
else if (declaration instanceof JetFunction) {
functionCodegen.gen((JetFunction) declaration, kind);
if (!overriden.contains(bindingContext.getFunctionDescriptor((JetFunction) declaration))) {
functionCodegen.gen((JetFunction) declaration, kind);
}
}
}
@@ -1268,9 +1268,6 @@ public class ExpressionCodegen extends JetVisitor {
else {
JetTypeReference typeReference = expression.getRight();
JetType jetType = bindingContext.resolveTypeReference(typeReference);
if (jetType.getArguments().size() > 0) {
throw new UnsupportedOperationException("don't know how to handle type arguments in as/as?");
}
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
if (!(descriptor instanceof ClassDescriptor)) {
throw new UnsupportedOperationException("don't know how to handle non-class types in as/as?");
@@ -1278,8 +1275,7 @@ public class ExpressionCodegen extends JetVisitor {
Type type = typeMapper.jvmType((ClassDescriptor) descriptor, OwnerKind.INTERFACE);
gen(expression.getLeft(), OBJECT_TYPE);
if (opToken == JetTokens.AS_SAFE) {
v.dup();
v.instanceOf(type);
generateInstanceOf(expression.getLeft(), jetType, true);
Label isInstance = new Label();
v.ifne(isInstance);
v.pop();
@@ -1288,7 +1284,7 @@ public class ExpressionCodegen extends JetVisitor {
myStack.push(StackValue.onStack(type));
}
else {
throw new UnsupportedOperationException("as not yet implemented");
throw new UnsupportedOperationException("'as' not yet implemented");
}
}
}
@@ -1307,22 +1303,32 @@ public class ExpressionCodegen extends JetVisitor {
}
JetTypeReference typeReference = ((JetTypePattern) pattern).getTypeReference();
JetType jetType = bindingContext.resolveTypeReference(typeReference);
generateInstanceOf(expression.getLeftHandSide(), jetType, false);
StackValue value = StackValue.onStack(Type.BOOLEAN_TYPE);
myStack.push(expression.isNot() ? StackValue.not(value) : value);
}
private void generateInstanceOf(JetExpression expression, JetType jetType, boolean leaveExpressionOnStack) {
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
if (!(descriptor instanceof ClassDescriptor)) {
throw new UnsupportedOperationException("don't know how to handle non-class types in is");
throw new UnsupportedOperationException("don't know how to handle non-class types");
}
if (jetType.getArguments().size() > 0) {
generateTypeInfo(jetType);
gen(expression.getLeftHandSide(), OBJECT_TYPE);
gen(expression, OBJECT_TYPE);
if (leaveExpressionOnStack) {
v.dupX1();
}
v.invokevirtual("jet/typeinfo/TypeInfo", "isInstance", "(Ljava/lang/Object;)Z");
}
else {
gen(expression.getLeftHandSide(), OBJECT_TYPE);
gen(expression, OBJECT_TYPE);
if (leaveExpressionOnStack) {
v.dup();
}
Type type = typeMapper.jvmType((ClassDescriptor) descriptor, OwnerKind.INTERFACE);
v.instanceOf(type);
}
StackValue value = StackValue.onStack(Type.BOOLEAN_TYPE);
myStack.push(expression.isNot() ? StackValue.not(value) : value);
}
private void generateTypeInfo(JetType jetType) {
@@ -1330,9 +1336,8 @@ public class ExpressionCodegen extends JetVisitor {
if (declarationDescriptor instanceof TypeParameterDescriptor) {
DeclarationDescriptor containingDeclaration = declarationDescriptor.getContainingDeclaration();
if (containingDeclaration == contextType && contextType instanceof ClassDescriptor) {
int index = indexOfTypeParameter((ClassDescriptor) contextType, (TypeParameterDescriptor) declarationDescriptor);
loadTypeInfo((ClassDescriptor) contextType, v);
v.iconst(index);
v.iconst(((TypeParameterDescriptor) declarationDescriptor).getIndex());
v.invokevirtual("jet/typeinfo/TypeInfo", "getTypeParameter", "(I)Ljet/typeinfo/TypeInfo;");
return;
}
@@ -1361,15 +1366,6 @@ public class ExpressionCodegen extends JetVisitor {
}
}
private int indexOfTypeParameter(ClassDescriptor classDescriptor, TypeParameterDescriptor typeParameterDescriptor) {
List<TypeParameterDescriptor> parameters = classDescriptor.getTypeConstructor().getParameters();
int index = parameters.indexOf(typeParameterDescriptor);
if (index < 0) {
throw new UnsupportedOperationException("can't find type parameter index");
}
return index;
}
private static class CompilationException extends RuntimeException {
}
}
@@ -0,0 +1,22 @@
class Base() {
public var v : Int
}
class Left() : Base() {}
class Right() : Base() {}
class D() : Left(), Right()
fun vl(l : Left) : Int = l.v
fun vr(r : Right) : Int = r.v
fun box() : String {
val d = new D()
d.v = 42
if (d.v != 42) return "Fail #1"
if (vl(d) != 42) return "Fail #2"
if (vr(d) != 42) return "Fail #3"
return "OK"
}
@@ -0,0 +1,18 @@
class Left() {}
class Right() {
virtual fun f() = 42
}
class D() : Left(), Right() {
override fun f() = 239
}
fun box() : String {
val r : Right = new Right()
val d : D = new D()
if (r.f() != 42) return "Fail #1"
if (d.f() != 239) return "Fail #2"
return "OK"
}
@@ -0,0 +1,8 @@
class Wrapper<T>() {
fun castToSelf(wrapper: Any) = wrapper as? Wrapper<T>
}
fun foo() {
val wrapper = new Wrapper<Int>()
return wrapper.castToSelf(new Wrapper<String>())
}
@@ -36,6 +36,14 @@ public class ClassGenTest extends CodegenTestCase {
blackBoxFile("classes/propertyDelegation.jet");
}
public void testDiamondInheritance() throws Exception {
blackBoxFile("classes/diamondInheritance.jet");
}
public void testRightHandOverride() throws Exception {
blackBoxFile("classes/rightHandOverride.jet");
}
private static void checkInterface(Class aClass, Class ifs) {
for (Class anInterface : aClass.getInterfaces()) {
if (anInterface == ifs) return;
@@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.parsing.JetParsingTest;
import javax.swing.JComponent;
import java.lang.reflect.Method;
import java.nio.channels.NonWritableChannelException;
import java.util.HashMap;
@@ -65,6 +65,12 @@ public class TypeInfoTest extends CodegenTestCase {
assertFalse((Boolean) foo.invoke(null));
}
public void testAsSafeWithGenerics() throws Exception {
loadFile();
Method foo = generateFunction();
assertNull(foo.invoke(null));
}
private Runnable newRunnable() {
return new Runnable() {
@Override