From c0dfe933c6e0eb4d1482b9f72a02cb0ab788bb42 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Tue, 6 Sep 2011 16:30:48 +0200 Subject: [PATCH] half way to KT-4 --- .../jetbrains/jet/codegen/ClassContext.java | 19 +++ .../jet/codegen/ExpressionCodegen.java | 28 ++-- .../codegen/ImplementationBodyCodegen.java | 2 +- .../jet/codegen/InstructionAdapterEx.java | 42 ++---- .../jetbrains/jet/codegen/JetTypeMapper.java | 124 ++++++++++++++---- .../jet/codegen/NamespaceCodegen.java | 21 ++- .../org/jetbrains/jet/codegen/StackValue.java | 4 +- .../jet/lang/types/JetStandardLibrary.java | 68 ++++++++++ .../jetbrains/jet/lang/types/TypeUtils.java | 13 ++ .../JetStructureViewElement.java | 5 + stdlib/src/jet/typeinfo/TypeInfo.java | 14 ++ 11 files changed, 267 insertions(+), 73 deletions(-) diff --git a/idea/src/org/jetbrains/jet/codegen/ClassContext.java b/idea/src/org/jetbrains/jet/codegen/ClassContext.java index d553ca2774e..3ad0f4da7ca 100644 --- a/idea/src/org/jetbrains/jet/codegen/ClassContext.java +++ b/idea/src/org/jetbrains/jet/codegen/ClassContext.java @@ -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 typeInfoConstants; public ClassContext(DeclarationDescriptor contextType, OwnerKind contextKind, StackValue thisExpression, ClassContext parentContext, ClosureCodegen closureCodegen) { this.contextType = contextType; @@ -164,4 +168,19 @@ public class ClassContext { final ClassContext parent = getParentContext(); return parent != null ? parent.enclosingClassType(mapper) : null; } + + public int getTypeInfoConstantIndex(JetType type) { + if(parentContext != STATIC) + parentContext.getTypeInfoConstantIndex(type); + + if(typeInfoConstants == null) + typeInfoConstants = new HashMap(); + + Integer index = typeInfoConstants.get(type); + if(index == null) { + index = Integer.valueOf(typeInfoConstants.size()); + typeInfoConstants.put(type, index); + } + return index; + } } diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 521ae9e361a..95588c972c3 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -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 { } 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("", Type.VOID_TYPE, new Type[0]); @@ -1500,7 +1497,7 @@ public class ExpressionCodegen extends JetVisitor { } 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,6 +1935,12 @@ public class ExpressionCodegen extends JetVisitor { } 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); @@ -1945,10 +1948,17 @@ public class ExpressionCodegen extends JetVisitor { } 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) { + context.getTypeInfoConstantIndex(jetType); + } v.aconst(jvmType); v.iconst(jetType.isNullable()?1:0); @@ -1974,7 +1984,7 @@ public class ExpressionCodegen extends JetVisitor { 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) diff --git a/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 8f1be52b429..ec4c31d888b 100644 --- a/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -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() { diff --git a/idea/src/org/jetbrains/jet/codegen/InstructionAdapterEx.java b/idea/src/org/jetbrains/jet/codegen/InstructionAdapterEx.java index 48c9c163486..f78095819d2 100644 --- a/idea/src/org/jetbrains/jet/codegen/InstructionAdapterEx.java +++ b/idea/src/org/jetbrains/jet/codegen/InstructionAdapterEx.java @@ -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: diff --git a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java index d48c8eec52e..745074db43f 100644 --- a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -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(ExpressionCodegen.CLASS_STRING_BUILDER); 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; + } } diff --git a/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 1b8ee6b5429..7f0b3c961a0 100644 --- a/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -4,12 +4,18 @@ import com.intellij.psi.PsiFile; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; +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.objectweb.asm.commons.InstructionAdapter; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + /** * @author max */ @@ -42,10 +48,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,9 +67,18 @@ public class NamespaceCodegen { state.forNamespace(childNamespace).generate(childNamespace); } } + +// System.out.println("-----------"); +// for(Map.Entry e : (context.typeInfoConstants != null ? context.typeInfoConstants : Collections.emptyMap()).entrySet()) { +// System.out.println(e.getKey() + " -> " + e.getValue()); +// } + + if (hasNonConstantPropertyInitializers(namespace)) { + generateStaticInitializers(namespace, context); + } } - private void generateStaticInitializers(JetNamespace namespace) { + private void generateStaticInitializers(JetNamespace namespace, ClassContext context) { MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "", "()V", null, null); mv.visitCode(); diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java index 6ff96e485c3..b657161eb12 100644 --- a/idea/src/org/jetbrains/jet/codegen/StackValue.java +++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java @@ -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); diff --git a/idea/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/idea/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index 220ea250226..bb642d8df68 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -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; + } } diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java b/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java index 10215de1dec..75ed47acf37 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -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; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/structureView/JetStructureViewElement.java b/idea/src/org/jetbrains/jet/plugin/structureView/JetStructureViewElement.java index fb7d05ede1e..1cb819b2154 100644 --- a/idea/src/org/jetbrains/jet/plugin/structureView/JetStructureViewElement.java +++ b/idea/src/org/jetbrains/jet/plugin/structureView/JetStructureViewElement.java @@ -70,6 +70,11 @@ public class JetStructureViewElement implements StructureViewTreeElement { : null; } + @Override + public TextAttributesKey getTextAttributesKey() { + return null; + } + }; } diff --git a/stdlib/src/jet/typeinfo/TypeInfo.java b/stdlib/src/jet/typeinfo/TypeInfo.java index 6a531d7695f..e8c7f5e36d2 100644 --- a/stdlib/src/jet/typeinfo/TypeInfo.java +++ b/stdlib/src/jet/typeinfo/TypeInfo.java @@ -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 implements JetObject { public static final TypeInfo BOOL_TYPE_INFO = getTypeInfo(Boolean.class, false); public static final TypeInfo FLOAT_TYPE_INFO = getTypeInfo(Float.class, false); public static final TypeInfo DOUBLE_TYPE_INFO = getTypeInfo(Double.class, false); + public static final TypeInfo STRING_TYPE_INFO = getTypeInfo(String.class, false); + public static final TypeInfo TUPLE0_TYPE_INFO = getTypeInfo(Tuple0.class, false); + + public static final TypeInfo NULLABLE_BYTE_TYPE_INFO = getTypeInfo(Byte.class, true); + public static final TypeInfo NULLABLE_SHORT_TYPE_INFO = getTypeInfo(Short.class, true); + public static final TypeInfo NULLABLE_INT_TYPE_INFO = getTypeInfo(Integer.class, true); + public static final TypeInfo NULLABLE_LONG_TYPE_INFO = getTypeInfo(Long.class, true); + public static final TypeInfo NULLABLE_CHAR_TYPE_INFO = getTypeInfo(Character.class, true); + public static final TypeInfo NULLABLE_BOOL_TYPE_INFO = getTypeInfo(Boolean.class, true); + public static final TypeInfo NULLABLE_FLOAT_TYPE_INFO = getTypeInfo(Float.class, true); + public static final TypeInfo NULLABLE_DOUBLE_TYPE_INFO = getTypeInfo(Double.class, true); + public static final TypeInfo NULLABLE_STRING_TYPE_INFO = getTypeInfo(String.class, true); + public static final TypeInfo NULLABLE_TUPLE0_TYPE_INFO = getTypeInfo(Tuple0.class, true); private TypeInfo typeInfo; private final Class theClass;