Merge remote branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-09-07 11:34:37 +04:00
14 changed files with 542 additions and 114 deletions
@@ -11,6 +11,8 @@ import org.jetbrains.jet.lang.types.JetType;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.HashMap;
public class ClassContext {
public static final ClassContext STATIC = new ClassContext(null, OwnerKind.NAMESPACE, null, null, null);
private final DeclarationDescriptor contextType;
@@ -19,6 +21,8 @@ public class ClassContext {
private final ClassContext parentContext;
private final ClosureCodegen closure;
private boolean thisWasUsed = false;
HashMap<JetType,Integer> typeInfoConstants;
public ClassContext(DeclarationDescriptor contextType, OwnerKind contextKind, StackValue thisExpression, ClassContext parentContext, ClosureCodegen closureCodegen) {
this.contextType = contextType;
@@ -32,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;
}
@@ -164,4 +175,19 @@ public class ClassContext {
final ClassContext parent = getParentContext();
return parent != null ? parent.enclosingClassType(mapper) : null;
}
public int getTypeInfoConstantIndex(JetType type) {
if(parentContext != STATIC)
return parentContext.getTypeInfoConstantIndex(type);
if(typeInfoConstants == null)
typeInfoConstants = new HashMap<JetType, Integer>();
Integer index = typeInfoConstants.get(type);
if(index == null) {
index = Integer.valueOf(typeInfoConstants.size());
typeInfoConstants.put(type, index);
}
return index;
}
}
@@ -15,10 +15,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
@@ -1478,7 +1475,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
public void generateStringBuilderConstructor() {
Type type = Type.getObjectType(CLASS_STRING_BUILDER);
Type type = JetTypeMapper.JL_STRING_BUILDER;
v.anew(type);
v.dup();
Method method = new Method("<init>", Type.VOID_TYPE, new Type[0]);
@@ -1500,7 +1497,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
public void invokeAppendMethod(Type exprType) {
Method appendDescriptor = new Method("append", Type.getObjectType(CLASS_STRING_BUILDER),
Method appendDescriptor = new Method("append", JetTypeMapper.JL_STRING_BUILDER,
new Type[] { exprType.getSort() == Type.OBJECT ? JetTypeMapper.TYPE_OBJECT : exprType});
v.invokevirtual(CLASS_STRING_BUILDER, "append", appendDescriptor.getDescriptor());
}
@@ -1938,17 +1935,32 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
private void generateTypeInfo(JetType jetType) {
String knownTypeInfo = typeMapper.isKnownTypeInfo(jetType);
if(knownTypeInfo != null) {
v.getstatic("jet/typeinfo/TypeInfo", knownTypeInfo, "Ljet/typeinfo/TypeInfo;");
return;
}
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
if (declarationDescriptor instanceof TypeParameterDescriptor) {
loadTypeParameterTypeInfo((TypeParameterDescriptor) declarationDescriptor);
return;
}
final Type jvmType = typeMapper.mapType(jetType, OwnerKind.INTERFACE);
if (jvmType.getSort() <= Type.DOUBLE) {
v.getstatic("jet/typeinfo/TypeInfo", PRIMITIVE_TYPE_INFO_FIELDS[jvmType.getSort()], "Ljet/typeinfo/TypeInfo;");
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;");
return;
}
boolean hasUnsubstituted = TypeUtils.hasUnsubstitutedTypeParameters(jetType);
if(!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);
@@ -1974,7 +1986,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
public static void genTypeInfoToProjection(InstructionAdapter v, Variance variance) {
if(variance == Variance.INVARIANT)
v.invokestatic("jet/typeinfo/TypeInfo", "invariantProjection", "(Ljet/typeinfo/TypeInfo;)Ljet/typeinfo/TypeInfoProjection;");
v.checkcast(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
else if(variance == Variance.IN_VARIANCE)
v.invokestatic("jet/typeinfo/TypeInfo", "inProjection", "(Ljet/typeinfo/TypeInfo;)Ljet/typeinfo/TypeInfoProjection;");
else if(variance == Variance.OUT_VARIANCE)
@@ -94,7 +94,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateFieldForTypeInfo() {
final boolean typeInfoIsStatic = descriptor.getTypeConstructor().getParameters().size() == 0;
v.visitField(Opcodes.ACC_PRIVATE | (typeInfoIsStatic ? Opcodes.ACC_STATIC : 0), "$typeInfo",
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | (typeInfoIsStatic ? Opcodes.ACC_STATIC : 0), "$typeInfo",
"Ljet/typeinfo/TypeInfo;", null, null);
if (typeInfoIsStatic) {
staticInitializerChunks.add(new CodeChunk() {
@@ -7,26 +7,6 @@ import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
public class InstructionAdapterEx extends InstructionAdapter {
private static final Type BYTE_TYPE = Type.getObjectType("java/lang/Byte");
private static final Type BOOLEAN_TYPE = Type.getObjectType("java/lang/Boolean");
private static final Type SHORT_TYPE = Type.getObjectType("java/lang/Short");
private static final Type CHARACTER_TYPE = Type.getObjectType("java/lang/Character");
private static final Type INTEGER_TYPE = Type.getObjectType("java/lang/Integer");
private static final Type FLOAT_TYPE = Type.getObjectType("java/lang/Float");
private static final Type LONG_TYPE = Type.getObjectType("java/lang/Long");
private static final Type DOUBLE_TYPE = Type.getObjectType("java/lang/Double");
private static final Type NUMBER_TYPE = Type.getObjectType("java/lang/Number");
private static final Type OBJECT_TYPE = Type.getObjectType("java/lang/Object");
private static final Method BOOLEAN_VALUE = Method.getMethod("boolean booleanValue()");
private static final Method CHAR_VALUE = Method.getMethod("char charValue()");
@@ -46,21 +26,21 @@ public class InstructionAdapterEx extends InstructionAdapter {
private static Type getBoxedType(final Type type) {
switch (type.getSort()) {
case Type.BYTE:
return BYTE_TYPE;
return JetTypeMapper.JL_BYTE_TYPE;
case Type.BOOLEAN:
return BOOLEAN_TYPE;
return JetTypeMapper.JL_BOOLEAN_TYPE;
case Type.SHORT:
return SHORT_TYPE;
return JetTypeMapper.JL_SHORT_TYPE;
case Type.CHAR:
return CHARACTER_TYPE;
return JetTypeMapper.JL_CHAR_TYPE;
case Type.INT:
return INTEGER_TYPE;
return JetTypeMapper.JL_INTEGER_TYPE;
case Type.FLOAT:
return FLOAT_TYPE;
return JetTypeMapper.JL_FLOAT_TYPE;
case Type.LONG:
return LONG_TYPE;
return JetTypeMapper.JL_LONG_TYPE;
case Type.DOUBLE:
return DOUBLE_TYPE;
return JetTypeMapper.JL_DOUBLE_TYPE;
}
return type;
}
@@ -78,17 +58,17 @@ public class InstructionAdapterEx extends InstructionAdapter {
}
public void unbox(final Type type) {
Type t = NUMBER_TYPE;
Type t = JetTypeMapper.JL_NUMBER_TYPE;
Method sig = null;
switch (type.getSort()) {
case Type.VOID:
return;
case Type.CHAR:
t = CHARACTER_TYPE;
t = JetTypeMapper.JL_CHAR_TYPE;
sig = CHAR_VALUE;
break;
case Type.BOOLEAN:
t = BOOLEAN_TYPE;
t = JetTypeMapper.JL_BOOLEAN_TYPE;
sig = BOOLEAN_VALUE;
break;
case Type.DOUBLE:
@@ -28,6 +28,16 @@ public class JetTypeMapper {
public static final Type TYPE_JET_OBJECT = Type.getType(JetObject.class);
public static final Type TYPE_CLASS = Type.getType(Class.class);
public static final Type TYPE_NOTHING = Type.getObjectType("jet/Nothing");
public static final Type JL_INTEGER_TYPE = Type.getObjectType("java/lang/Integer");
public static final Type JL_LONG_TYPE = Type.getObjectType("java/lang/Long");
public static final Type JL_SHORT_TYPE = Type.getObjectType("java/lang/Short");
public static final Type JL_BYTE_TYPE = Type.getObjectType("java/lang/Byte");
public static final Type JL_CHAR_TYPE = Type.getObjectType("java/lang/Character");
public static final Type JL_FLOAT_TYPE = Type.getObjectType("java/lang/Float");
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("java/lang/StringBuilder");
private final JetStandardLibrary standardLibrary;
private final BindingContext bindingContext;
@@ -298,50 +308,50 @@ public class JetTypeMapper {
if (jetType.equals(standardLibrary.getIntType())) {
return Type.INT_TYPE;
}
if (jetType.equals(TypeUtils.makeNullable(standardLibrary.getIntType()))) {
return Type.getObjectType("java/lang/Integer");
if (jetType.equals(standardLibrary.getNullableIntType())) {
return JL_INTEGER_TYPE;
}
if (jetType.equals(standardLibrary.getLongType())) {
return Type.LONG_TYPE;
}
if (jetType.equals(TypeUtils.makeNullable(standardLibrary.getLongType()))) {
return Type.getObjectType("java/lang/Long");
if (jetType.equals(standardLibrary.getNullableLongType())) {
return JL_LONG_TYPE;
}
if (jetType.equals(standardLibrary.getShortType())) {
return Type.SHORT_TYPE;
}
if (jetType.equals(TypeUtils.makeNullable(standardLibrary.getShortType()))) {
return Type.getObjectType("java/lang/Short");
if (jetType.equals(standardLibrary.getNullableShortType())) {
return JL_SHORT_TYPE;
}
if (jetType.equals(standardLibrary.getByteType())) {
return Type.BYTE_TYPE;
}
if (jetType.equals(TypeUtils.makeNullable(standardLibrary.getByteType()))) {
return Type.getObjectType("java/lang/Byte");
if (jetType.equals(standardLibrary.getNullableByteType())) {
return JL_BYTE_TYPE;
}
if (jetType.equals(standardLibrary.getCharType())) {
return Type.CHAR_TYPE;
}
if (jetType.equals(TypeUtils.makeNullable(standardLibrary.getCharType()))) {
return Type.getObjectType("java/lang/Char");
if (jetType.equals(standardLibrary.getNullableCharType())) {
return JL_CHAR_TYPE;
}
if (jetType.equals(standardLibrary.getFloatType())) {
return Type.FLOAT_TYPE;
}
if (jetType.equals(TypeUtils.makeNullable(standardLibrary.getFloatType()))) {
return Type.getObjectType("java/lang/Float");
if (jetType.equals(standardLibrary.getNullableFloatType())) {
return JL_FLOAT_TYPE;
}
if (jetType.equals(standardLibrary.getDoubleType())) {
return Type.DOUBLE_TYPE;
}
if (jetType.equals(TypeUtils.makeNullable(standardLibrary.getDoubleType()))) {
return Type.getObjectType("java/lang/Double");
if (jetType.equals(standardLibrary.getNullableDoubleType())) {
return JL_DOUBLE_TYPE;
}
if (jetType.equals(standardLibrary.getBooleanType())) {
return Type.BOOLEAN_TYPE;
}
if (jetType.equals(TypeUtils.makeNullable(standardLibrary.getBooleanType()))) {
return Type.getObjectType("java/lang/Boolean");
if (jetType.equals(standardLibrary.getNullableBooleanType())) {
return JL_BOOLEAN_TYPE;
}
if (jetType.equals(standardLibrary.getStringType()) || jetType.equals(standardLibrary.getNullableStringType())) {
return Type.getType(String.class);
@@ -374,23 +384,23 @@ public class JetTypeMapper {
public Type boxType(Type asmType) {
switch (asmType.getSort()) {
case Type.VOID:
return Type.getObjectType("java/lang/Void");
return Type.VOID_TYPE;
case Type.BYTE:
return Type.getObjectType("java/lang/Byte");
return JL_BYTE_TYPE;
case Type.BOOLEAN:
return Type.getObjectType("java/lang/Boolean");
return JL_BOOLEAN_TYPE;
case Type.SHORT:
return Type.getObjectType("java/lang.Short");
return JL_SHORT_TYPE;
case Type.CHAR:
return Type.getObjectType("java/lang/Character");
return JL_CHAR_TYPE;
case Type.INT:
return Type.getObjectType("java/lang/Integer");
return JL_INTEGER_TYPE;
case Type.FLOAT:
return Type.getObjectType("java/lang/Float");
return JL_FLOAT_TYPE;
case Type.LONG:
return Type.getObjectType("java/lang/Long");
return JL_LONG_TYPE;
case Type.DOUBLE:
return Type.getObjectType("java/lang/Double");
return JL_DOUBLE_TYPE;
}
return asmType;
@@ -618,4 +628,68 @@ public class JetTypeMapper {
}
return result;
}
public String isKnownTypeInfo(JetType jetType) {
if (jetType.equals(standardLibrary.getIntType())) {
return "INT_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getNullableIntType())) {
return "NULLABLE_INT_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getLongType())) {
return "LONG_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getNullableLongType())) {
return "NULLABLE_LONG_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getShortType())) {
return "SHORT_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getNullableShortType())) {
return "NULLABLE_SHORT_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getByteType())) {
return "BYTE_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getNullableByteType())) {
return "NULLABLE_BYTE_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getCharType())) {
return "CHAR_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getNullableCharType())) {
return "NULLABLE_CHAR_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getFloatType())) {
return "FLOAT_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getNullableFloatType())) {
return "NULLABLE_FLOAT_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getDoubleType())) {
return "DOUBLE_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getNullableDoubleType())) {
return "NULLABLE_DOUBLE_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getBooleanType())) {
return "BOOLEAN_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getNullableBooleanType())) {
return "NULLABLE_BOOLEAN_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getStringType())) {
return "STRING_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getNullableStringType())) {
return "NULLABLE_STRING_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getTuple0Type())) {
return "TUPLE0_TYPE_INFO";
}
if (jetType.equals(standardLibrary.getNullableTuple0Type())) {
return "NULLABLE_TUPLE0_TYPE_INFO";
}
return null;
}
}
@@ -1,15 +1,22 @@
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.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
import org.jetbrains.jet.lang.types.JetType;
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.*;
import static org.objectweb.asm.Opcodes.*;
/**
* @author max
*/
@@ -21,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",
@@ -42,10 +49,6 @@ public class NamespaceCodegen {
GenerationState.prepareAnonymousClasses(namespace, state.getTypeMapper());
if (hasNonConstantPropertyInitializers(namespace)) {
generateStaticInitializers(namespace);
}
for (JetDeclaration declaration : namespace.getDeclarations()) {
if (declaration instanceof JetProperty) {
propertyCodegen.gen((JetProperty) declaration);
@@ -65,10 +68,16 @@ public class NamespaceCodegen {
state.forNamespace(childNamespace).generate(childNamespace);
}
}
if (hasNonConstantPropertyInitializers(namespace, context)) {
generateStaticInitializers(namespace, context);
}
generateTypeInfoFields(namespace, context);
}
private void generateStaticInitializers(JetNamespace namespace) {
MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
private void generateStaticInitializers(JetNamespace namespace, ClassContext context) {
MethodVisitor mv = v.visitMethod(ACC_PUBLIC | ACC_STATIC,
"<clinit>", "()V", null, null);
mv.visitCode();
@@ -85,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();
@@ -183,10 +183,10 @@ public abstract class StackValue {
else if (this.type.getSort() == Type.OBJECT && type.getSort() <= Type.DOUBLE) {
if (this.type.equals(JetTypeMapper.TYPE_OBJECT)) {
if (type.getSort() == Type.BOOLEAN) {
v.checkcast(Type.getObjectType("java/lang/Boolean"));
v.checkcast(JetTypeMapper.JL_BOOLEAN_TYPE);
}
else {
v.checkcast(Type.getObjectType("java/lang/Number"));
v.checkcast(JetTypeMapper.JL_NUMBER_TYPE);
}
}
unbox(type, v);
@@ -56,16 +56,32 @@ public class JetStandardLibrary {
private final ClassDescriptor arrayClass;
private final ClassDescriptor iterableClass;
private final ClassDescriptor typeInfoClass;
private final ClassDescriptor tuple0Class;
private final JetType byteType;
private final JetType nullableByteType;
private final JetType charType;
private final JetType nullableCharType;
private final JetType shortType;
private final JetType nullableShortType;
private final JetType intType;
private final JetType nullableIntType;
private final JetType longType;
private final JetType nullableLongType;
private final JetType floatType;
private final JetType nullableFloatType;
private final JetType doubleType;
private final JetType nullableDoubleType;
private final JetType booleanType;
private final JetType nullableBooleanType;
private final JetType stringType;
private final JetType nullableTuple0Type;
public JetType getTuple0Type() {
return tuple0Type;
}
private final JetType tuple0Type;
private final JetType nullableStringType;
private final NamespaceDescriptor typeInfoNamespace;
@@ -100,6 +116,7 @@ public class JetStandardLibrary {
this.stringClass = (ClassDescriptor) libraryScope.getClassifier("String");
this.arrayClass = (ClassDescriptor) libraryScope.getClassifier("Array");
this.iterableClass = (ClassDescriptor) libraryScope.getClassifier("Iterable");
this.tuple0Class = (ClassDescriptor) libraryScope.getClassifier("Tuple0");
typeInfoNamespace = libraryScope.getNamespace("typeinfo");
this.typeInfoClass = (ClassDescriptor) typeInfoNamespace.getMemberScope().getClassifier("TypeInfo");
typeInfoFunction = typeInfoNamespace.getMemberScope().getFunctionGroup("typeinfo");
@@ -113,7 +130,18 @@ public class JetStandardLibrary {
this.doubleType = new JetTypeImpl(getDouble());
this.booleanType = new JetTypeImpl(getBoolean());
this.stringType = new JetTypeImpl(getString());
this.tuple0Type = new JetTypeImpl(getTuple0());
this.nullableByteType = TypeUtils.makeNullable(byteType);
this.nullableCharType = TypeUtils.makeNullable(charType);
this.nullableShortType = TypeUtils.makeNullable(shortType);
this.nullableIntType = TypeUtils.makeNullable(intType);
this.nullableLongType = TypeUtils.makeNullable(longType);
this.nullableFloatType = TypeUtils.makeNullable(floatType);
this.nullableDoubleType = TypeUtils.makeNullable(doubleType);
this.nullableBooleanType = TypeUtils.makeNullable(booleanType);
this.nullableStringType = TypeUtils.makeNullable(stringType);
this.nullableTuple0Type = TypeUtils.makeNullable(tuple0Type);
} catch (IOException e) {
throw new IllegalStateException(e);
}
@@ -178,6 +206,10 @@ public class JetStandardLibrary {
return iterableClass;
}
public ClassDescriptor getTuple0() {
return tuple0Class;
}
public NamespaceDescriptor getTypeInfoNamespace() {
return typeInfoNamespace;
}
@@ -275,4 +307,40 @@ public class JetStandardLibrary {
public JetType getNullableStringType() {
return nullableStringType;
}
public JetType getNullableByteType() {
return nullableByteType;
}
public JetType getNullableCharType() {
return nullableCharType;
}
public JetType getNullableShortType() {
return nullableShortType;
}
public JetType getNullableIntType() {
return nullableIntType;
}
public JetType getNullableLongType() {
return nullableLongType;
}
public JetType getNullableFloatType() {
return nullableFloatType;
}
public JetType getNullableDoubleType() {
return nullableDoubleType;
}
public JetType getNullableBooleanType() {
return nullableBooleanType;
}
public JetType getNullableTuple0Type() {
return nullableTuple0Type;
}
}
@@ -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;
@@ -320,4 +320,17 @@ public class TypeUtils {
if (declarationDescriptor2 == null) return false; // Class of type1 is not null
return declarationDescriptor1.getOriginal().equals(declarationDescriptor2.getOriginal());
}
public static boolean hasUnsubstitutedTypeParameters(JetType type) {
if(type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor)
return true;
for(TypeProjection proj : type.getArguments()) {
if(hasUnsubstitutedTypeParameters(proj.getType())) {
return true;
}
}
return false;
}
}
@@ -70,6 +70,11 @@ public class JetStructureViewElement implements StructureViewTreeElement {
: null;
}
@Override
public TextAttributesKey getTextAttributesKey() {
return null;
}
};
}
+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 {
+14
View File
@@ -1,6 +1,7 @@
package jet.typeinfo;
import jet.JetObject;
import jet.Tuple0;
import java.lang.reflect.Field;
import java.util.Arrays;
@@ -19,6 +20,19 @@ public abstract class TypeInfo<T> implements JetObject {
public static final TypeInfo<Boolean> BOOL_TYPE_INFO = getTypeInfo(Boolean.class, false);
public static final TypeInfo<Float> FLOAT_TYPE_INFO = getTypeInfo(Float.class, false);
public static final TypeInfo<Double> DOUBLE_TYPE_INFO = getTypeInfo(Double.class, false);
public static final TypeInfo<String> STRING_TYPE_INFO = getTypeInfo(String.class, false);
public static final TypeInfo<Tuple0> TUPLE0_TYPE_INFO = getTypeInfo(Tuple0.class, false);
public static final TypeInfo<Byte> NULLABLE_BYTE_TYPE_INFO = getTypeInfo(Byte.class, true);
public static final TypeInfo<Short> NULLABLE_SHORT_TYPE_INFO = getTypeInfo(Short.class, true);
public static final TypeInfo<Integer> NULLABLE_INT_TYPE_INFO = getTypeInfo(Integer.class, true);
public static final TypeInfo<Long> NULLABLE_LONG_TYPE_INFO = getTypeInfo(Long.class, true);
public static final TypeInfo<Character> NULLABLE_CHAR_TYPE_INFO = getTypeInfo(Character.class, true);
public static final TypeInfo<Boolean> NULLABLE_BOOL_TYPE_INFO = getTypeInfo(Boolean.class, true);
public static final TypeInfo<Float> NULLABLE_FLOAT_TYPE_INFO = getTypeInfo(Float.class, true);
public static final TypeInfo<Double> NULLABLE_DOUBLE_TYPE_INFO = getTypeInfo(Double.class, true);
public static final TypeInfo<String> NULLABLE_STRING_TYPE_INFO = getTypeInfo(String.class, true);
public static final TypeInfo<Tuple0> NULLABLE_TUPLE0_TYPE_INFO = getTypeInfo(Tuple0.class, true);
private TypeInfo<?> typeInfo;
private final Class<T> theClass;