KT-4 fixed

This commit is contained in:
Alex Tkachman
2011-09-06 23:45:04 +02:00
parent c0dfe933c6
commit 6898ff5665
7 changed files with 289 additions and 55 deletions
@@ -36,6 +36,13 @@ public class ClassContext {
return contextType;
}
public String getNamespaceClassName() {
if(parentContext != STATIC)
return parentContext.getNamespaceClassName();
return NamespaceCodegen.getJVMClassName(contextType.getName());
}
public OwnerKind getContextKind() {
return contextKind;
}
@@ -171,7 +178,7 @@ public class ClassContext {
public int getTypeInfoConstantIndex(JetType type) {
if(parentContext != STATIC)
parentContext.getTypeInfoConstantIndex(type);
return parentContext.getTypeInfoConstantIndex(type);
if(typeInfoConstants == null)
typeInfoConstants = new HashMap<JetType, Integer>();
@@ -1947,8 +1947,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return;
}
final Type jvmType = typeMapper.mapType(jetType, OwnerKind.INTERFACE);
if(jetType.getArguments().size() == 0 && !(declarationDescriptor instanceof JavaClassDescriptor)) {
// TODO: we need some better checks here
v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
@@ -1957,9 +1955,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
boolean hasUnsubstituted = TypeUtils.hasUnsubstitutedTypeParameters(jetType);
if(!hasUnsubstituted) {
context.getTypeInfoConstantIndex(jetType);
int typeInfoConstantIndex = context.getTypeInfoConstantIndex(jetType);
v.invokestatic(context.getNamespaceClassName(), "$getCachedTypeInfo$" + typeInfoConstantIndex, "()Ljet/typeinfo/TypeInfo;");
return;
}
final Type jvmType = typeMapper.mapType(jetType, OwnerKind.INTERFACE);
v.aconst(jvmType);
v.iconst(jetType.isNullable()?1:0);
List<TypeProjection> arguments = jetType.getArguments();
@@ -37,7 +37,7 @@ public class JetTypeMapper {
public static final Type JL_DOUBLE_TYPE = Type.getObjectType("java/lang/Double");
public static final Type JL_BOOLEAN_TYPE = Type.getObjectType("java/lang/Boolean");
public static final Type JL_NUMBER_TYPE = Type.getObjectType("java/lang/Number");
public static final Type JL_STRING_BUILDER = Type.getObjectType(ExpressionCodegen.CLASS_STRING_BUILDER);
public static final Type JL_STRING_BUILDER = Type.getObjectType("java/lang/StringBuilder");
private final JetStandardLibrary standardLibrary;
private final BindingContext bindingContext;
@@ -1,20 +1,21 @@
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiFile;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.objectweb.asm.*;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.*;
import static org.objectweb.asm.Opcodes.*;
/**
* @author max
@@ -27,8 +28,8 @@ public class NamespaceCodegen {
this.v = v;
this.state = state;
v.visit(Opcodes.V1_6,
Opcodes.ACC_PUBLIC,
v.visit(V1_6,
ACC_PUBLIC,
getJVMClassName(fqName),
null,
//"jet/lang/Namespace",
@@ -68,18 +69,15 @@ public class NamespaceCodegen {
}
}
// System.out.println("-----------");
// for(Map.Entry<JetType,Integer> e : (context.typeInfoConstants != null ? context.typeInfoConstants : Collections.<JetType,Integer>emptyMap()).entrySet()) {
// System.out.println(e.getKey() + " -> " + e.getValue());
// }
if (hasNonConstantPropertyInitializers(namespace)) {
if (hasNonConstantPropertyInitializers(namespace, context)) {
generateStaticInitializers(namespace, context);
}
generateTypeInfoFields(namespace, context);
}
private void generateStaticInitializers(JetNamespace namespace, ClassContext context) {
MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
MethodVisitor mv = v.visitMethod(ACC_PUBLIC | ACC_STATIC,
"<clinit>", "()V", null, null);
mv.visitCode();
@@ -96,12 +94,85 @@ public class NamespaceCodegen {
}
}
}
mv.visitInsn(Opcodes.RETURN);
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
private static boolean hasNonConstantPropertyInitializers(JetNamespace namespace) {
private void generateTypeInfoFields(JetNamespace namespace, ClassContext context) {
if(context.typeInfoConstants != null) {
String jvmClassName = getJVMClassName(namespace.getName());
for(Map.Entry<JetType,Integer> e : (context.typeInfoConstants != null ? context.typeInfoConstants : Collections.<JetType,Integer>emptyMap()).entrySet()) {
String fieldName = "$typeInfoCache$" + e.getValue();
v.visitField(ACC_PRIVATE|ACC_STATIC|ACC_SYNTHETIC, fieldName, "Ljet/typeinfo/TypeInfo;", null, null);
MethodVisitor mmv = v.visitMethod(ACC_PUBLIC|ACC_STATIC|ACC_SYNTHETIC, "$getCachedTypeInfo$" + e.getValue(), "()Ljet/typeinfo/TypeInfo;", null, null);
InstructionAdapterEx v = new InstructionAdapterEx(mmv);
v.visitFieldInsn(GETSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
v.visitInsn(DUP);
Label end = new Label();
v.visitJumpInsn(IFNONNULL, end);
v.pop();
generateTypeInfo(context, v, e.getKey(), state.getTypeMapper(), e.getKey());
v.dup();
v.visitFieldInsn(PUTSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
v.visitLabel(end);
v.visitInsn(ARETURN);
v.visitMaxs(0, 0);
v.visitEnd();
}
}
}
private void generateTypeInfo(ClassContext context, InstructionAdapterEx v, JetType jetType, JetTypeMapper typeMapper, JetType root) {
String knownTypeInfo = typeMapper.isKnownTypeInfo(jetType);
if(knownTypeInfo != null) {
v.getstatic("jet/typeinfo/TypeInfo", knownTypeInfo, "Ljet/typeinfo/TypeInfo;");
return;
}
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
if(!jetType.equals(root) && jetType.getArguments().size() == 0 && !(declarationDescriptor instanceof JavaClassDescriptor)) {
// TODO: we need some better checks here
v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
return;
}
boolean hasUnsubstituted = TypeUtils.hasUnsubstitutedTypeParameters(jetType);
if(!jetType.equals(root) && !hasUnsubstituted) {
int typeInfoConstantIndex = context.getTypeInfoConstantIndex(jetType);
v.invokestatic(context.getNamespaceClassName(), "$getCachedTypeInfo$" + typeInfoConstantIndex, "()Ljet/typeinfo/TypeInfo;");
return;
}
final Type jvmType = typeMapper.mapType(jetType, OwnerKind.INTERFACE);
v.aconst(jvmType);
v.iconst(jetType.isNullable() ? 1 : 0);
List<TypeProjection> arguments = jetType.getArguments();
if (arguments.size() > 0) {
v.iconst(arguments.size());
v.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
for (int i = 0, argumentsSize = arguments.size(); i < argumentsSize; i++) {
TypeProjection argument = arguments.get(i);
v.dup();
v.iconst(i);
generateTypeInfo(context, v, argument.getType(), typeMapper, root);
ExpressionCodegen.genTypeInfoToProjection(v, argument.getProjectionKind());
v.astore(JetTypeMapper.TYPE_OBJECT);
}
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z[Ljet/typeinfo/TypeInfoProjection;)Ljet/typeinfo/TypeInfo;");
}
else {
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;");
}
}
private static boolean hasNonConstantPropertyInitializers(JetNamespace namespace, ClassContext context) {
for (JetDeclaration declaration : namespace.getDeclarations()) {
if (declaration instanceof JetProperty) {
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
@@ -96,7 +96,7 @@ public final class JetTypeImpl extends AnnotatedImpl implements JetType {
JetTypeImpl type = (JetTypeImpl) o;
// TODO
return equalTypes(this, type, EMPTY_AXIOMS);
return nullable == type.nullable && equalTypes(this, type, EMPTY_AXIOMS);
// if (nullable != type.nullable) return false;
// if (arguments != null ? !arguments.equals(type.arguments) : type.arguments != null) return false;
// if (constructor != null ? !constructor.equals(type.constructor) : type.constructor != null) return false;
+183 -29
View File
@@ -8,52 +8,143 @@ class B<T>() {
fun t1() : Boolean {
val a = A()
if(a !is A) return false
return true
}
fun t2() : Boolean {
val a = A()
if(a !is A?) return false
return true
}
fun t3() : Boolean {
val a = A()
if(null !is A?) return false
return true
}
fun t2 () : Boolean {
fun t4 () : Boolean {
val b = B<String>()
if(b !is B<String>) return false
return true
}
fun t5 () : Boolean {
val b = B<String>()
if(b !is B<String>?) return false
return true
}
fun t6 () : Boolean {
if(null !is B<String>?) return false
return true
}
val v = b as B<String> //ok
val u = b as B<String>? //TypeCastException
fun t7 () : Boolean {
val b = B<String>()
if(!b.isT("aaa")) return false
return true
}
fun t8 () : Boolean {
val b = B<String>()
if(b.isT(10)) return false
return true
}
fun t9 () : Boolean {
val b = B<String>()
if(b.isT(null)) return false
return true
}
fun t10 () : Boolean {
val d = B<String?>()
if(!d.isT("aaa")) return false
return true
}
fun t11 () : Boolean {
val d = B<String?>()
if(d.isT(10)) return false
return true
}
fun t12 () : Boolean {
val d = B<String?>()
if(!d.isT(null)) return false
return true
}
fun t13 () : Boolean {
val f = B<java.lang.String?>()
if(!f.isT("aaa")) return false
return true
}
fun t14 () : Boolean {
val f = B<java.lang.String?>()
if(f.isT(10)) return false
return true
}
fun t15 () : Boolean {
val f = B<java.lang.String?>()
if(!f.isT(null)) return false
return true
}
fun t16 () : Boolean {
val c = B<Int>()
if(c.isT("aaa")) return false
return true
}
fun t17 () : Boolean {
val c = B<Int>()
if(!c.isT(10)) return false
return true
}
fun t18 () : Boolean {
val c = B<Int>()
if(c.isT(null)) return false
return true
}
fun t19 () : Boolean {
val e = B<Int?>()
if(e.isT("aaa")) return false
return true
}
fun t20 () : Boolean {
val e = B<Int?>()
if(!e.isT(10)) return false
return true
}
fun t21 () : Boolean {
val e = B<Int?>()
if(!e.isT(null)) return false
return true
}
fun t22 () : Boolean {
val b = B<String>()
val w : B<String>? = b as B<String> //ok
val x = w as B<String>? //TypeCastException
return true
}
fun t3 () : Boolean {
fun t23 () : Boolean {
val b = B<String>()
if(!b.isT("aaa")) return false
if(b.isT(10)) return false
if(b.isT(null)) return false
val d = B<String?>()
if(!d.isT("aaa")) return false
if(d.isT(10)) return false
if(!d.isT(null)) return false
val f = B<java.lang.String?>()
if(!f.isT("aaa")) return false
if(f.isT(10)) return false
if(!f.isT(null)) return false
val c = B<Int>()
if(c.isT("aaa")) return false
if(!c.isT(10)) return false
if(c.isT(null)) return false
val e = B<Int?>()
if(e.isT("aaa")) return false
if(!e.isT(10)) return false
if(!e.isT(null)) return false
val v = b as B<String> //ok
return true
}
fun t24 () : Boolean {
val b = B<String>()
val u = b as B<String>? //TypeCastException
return true
}
@@ -67,5 +158,68 @@ fun box() : String {
if(!t3()) {
return "t3 failed"
}
return "OK"
if(!t4()) {
return "t4 failed"
}
if(!t5()) {
return "t5 failed"
}
if(!t6()) {
return "t6 failed"
}
if(!t7()) {
return "t7 failed"
}
if(!t8()) {
return "t8 failed"
}
if(!t9()) {
return "t9 failed"
}
if(!t10()) {
return "t10 failed"
}
if(!t11()) {
return "t11 failed"
}
if(!t12()) {
return "t12 failed"
}
if(!t13()) {
return "t13 failed"
}
if(!t14()) {
return "t14 failed"
}
if(!t15()) {
return "t15 failed"
}
if(!t16()) {
return "t16 failed"
}
if(!t17()) {
return "t17 failed"
}
if(!t18()) {
return "t18 failed"
}
if(!t19()) {
return "t19 failed"
}
if(!t20()) {
return "t10 failed"
}
if(!t21()) {
return "t21 failed"
}
if(!t22()) {
return "t22 failed"
}
if(!t23()) {
return "t23 failed"
}
if(!t24()) {
return "t24 failed"
}
return "OK"
}
@@ -49,8 +49,8 @@ public class PatternMatchingTest extends CodegenTestCase {
public void testIs() throws Exception {
loadFile();
blackBox();
System.out.println(generateToText());
blackBox();
}
public void testRange() throws Exception {