diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 6a0140211ea..f388bcc53e0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -2,22 +2,26 @@ package org.jetbrains.jet.codegen; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.JetType; /** * @author abreslav + * @author alex.tkachman */ public class CodegenUtil { - public static boolean isInterface(DeclarationDescriptor descriptor, BindingContext bindingContext) { - PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); - if(psiElement instanceof JetClass) { - return ((JetClass)psiElement).isTrait(); - } - if(psiElement instanceof PsiClass) { - return ((PsiClass)psiElement).isInterface(); - } - return false; + private CodegenUtil() { + } + + public static boolean isInterface(DeclarationDescriptor descriptor) { + return descriptor instanceof ClassDescriptor && ((ClassDescriptor)descriptor).getKind() == ClassKind.TRAIT; + } + + public static boolean isInterface(JetType type) { + return isInterface(type.getConstructor().getDeclarationDescriptor()); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index c5ccf901bfb..b5d9adb0dfe 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -721,7 +721,7 @@ public class ExpressionCodegen extends JetVisitor { receiver.put(receiverType != null ? typeMapper.mapType(receiverType) : JetTypeMapper.TYPE_OBJECT, v); if(receiverType != null) { ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration(); - if(!CodegenUtil.isInterface(propReceiverDescriptor, bindingContext) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor(), bindingContext)) { + if(!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) { // I hope it happens only in case of required super class for traits v.checkcast(typeMapper.mapType(propReceiverDescriptor.getDefaultType())); } @@ -2026,7 +2026,7 @@ public class ExpressionCodegen extends JetVisitor { JetType defaultType = descriptor.getDefaultType(); Type ownerType = typeMapper.mapType(defaultType); ownerType = JetTypeMapper.boxType(ownerType); - if(!typeMapper.isInterface(descriptor)) { + if(!CodegenUtil.isInterface(descriptor)) { if (descriptor.getTypeConstructor().getParameters().size() > 0) { v.load(0, JetTypeMapper.TYPE_OBJECT); v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;"); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index ac8c94bad21..d7b0b188569 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -8,7 +8,6 @@ import org.jetbrains.jet.lang.psi.JetDeclarationWithBody; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.TypeUtils; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -47,33 +46,6 @@ public class FunctionCodegen { generatedMethod(bodyExpression, jvmMethod, funContext, functionDescriptor); } - private void generateBridgeMethod(Method function, Method overriden) - { - int flags = Opcodes.ACC_PUBLIC; // TODO. - - final MethodVisitor mv = v.visitMethod(flags, function.getName(), overriden.getDescriptor(), null, null); - mv.visitCode(); - - Type[] argTypes = function.getArgumentTypes(); - InstructionAdapter iv = new InstructionAdapter(mv); - iv.load(0, JetTypeMapper.TYPE_OBJECT); - for (int i = 0, reg = 1; i < argTypes.length; i++) { - Type argType = argTypes[i]; - iv.load(reg, argType); - //noinspection AssignmentToForLoopParameter - reg += argType.getSize(); - } - - iv.invokevirtual(state.getTypeMapper().jvmName((ClassDescriptor) owner.getContextDescriptor(), OwnerKind.IMPLEMENTATION), function.getName(), function.getDescriptor()); - if(JetTypeMapper.isPrimitive(function.getReturnType()) && !JetTypeMapper.isPrimitive(overriden.getReturnType())) - StackValue.valueOf(iv, function.getReturnType()); - if(function.getReturnType() == Type.VOID_TYPE) - iv.aconst(null); - iv.areturn(overriden.getReturnType()); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - private void generatedMethod(JetExpression bodyExpressions, Method jvmSignature, ClassContext context, @@ -86,10 +58,13 @@ public class FunctionCodegen { OwnerKind kind = context.getContextKind(); + if(kind == OwnerKind.TRAIT_IMPL && bodyExpressions == null) + return; + boolean isStatic = kind == OwnerKind.NAMESPACE || kind == OwnerKind.TRAIT_IMPL; if (isStatic) flags |= Opcodes.ACC_STATIC; - boolean isAbstract = !isStatic && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration(), state.getBindingContext())); + boolean isAbstract = !isStatic && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration())); if (isAbstract) flags |= Opcodes.ACC_ABSTRACT; final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null); @@ -122,21 +97,58 @@ public class FunctionCodegen { iv.invokeinterface(dk.getOwnerClass(), jvmSignature.getName(), jvmSignature.getDescriptor()); iv.areturn(jvmSignature.getReturnType()); } - else if (!isAbstract) { + else { codegen.returnExpression(bodyExpressions); } mv.visitMaxs(0, 0); mv.visitEnd(); - Set overriddenFunctions = functionDescriptor.getOverriddenDescriptors(); - if(overriddenFunctions.size() > 0) { - for (FunctionDescriptor overriddenFunction : overriddenFunctions) { - // TODO should we check params here as well? - if(!TypeUtils.equalClasses(overriddenFunction.getOriginal().getReturnType(), functionDescriptor.getReturnType())) { - generateBridgeMethod(jvmSignature, state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal())); - } - } + generateBridgeIfNeeded(owner, state, v, jvmSignature, functionDescriptor, kind); + } + } + + static void generateBridgeIfNeeded(ClassContext owner, GenerationState state, ClassVisitor v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { + Set overriddenFunctions = functionDescriptor.getOverriddenDescriptors(); + if(kind != OwnerKind.TRAIT_IMPL) { + for (FunctionDescriptor overriddenFunction : overriddenFunctions) { + // TODO should we check params here as well? + checkOverride(owner, state, v, jvmSignature, functionDescriptor, overriddenFunction); } + checkOverride(owner, state, v, jvmSignature, functionDescriptor, functionDescriptor.getOriginal()); + } + } + + private static void checkOverride(ClassContext owner, GenerationState state, ClassVisitor v, Method jvmSignature, FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenFunction) { + Type type1 = state.getTypeMapper().mapType(overriddenFunction.getOriginal().getReturnType()); + Type type2 = state.getTypeMapper().mapType(functionDescriptor.getReturnType()); + if(!type1.equals(type2)) { + Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()); + int flags = Opcodes.ACC_PUBLIC; // TODO. + + final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), overriden.getDescriptor(), null, null); + mv.visitCode(); + + Type[] argTypes = jvmSignature.getArgumentTypes(); + InstructionAdapter iv = new InstructionAdapter(mv); + iv.load(0, JetTypeMapper.TYPE_OBJECT); + for (int i = 0, reg = 1; i < argTypes.length; i++) { + Type argType = argTypes[i]; + iv.load(reg, argType); + if(argType.getSort() == Type.OBJECT) { + iv.checkcast(argType); + } + //noinspection AssignmentToForLoopParameter + reg += argType.getSize(); + } + + iv.invokevirtual(state.getTypeMapper().jvmName((ClassDescriptor) owner.getContextDescriptor(), OwnerKind.IMPLEMENTATION), jvmSignature.getName(), jvmSignature.getDescriptor()); + if(JetTypeMapper.isPrimitive(jvmSignature.getReturnType()) && !JetTypeMapper.isPrimitive(overriden.getReturnType())) + StackValue.valueOf(iv, jvmSignature.getReturnType()); + if(jvmSignature.getReturnType() == Type.VOID_TYPE) + iv.aconst(null); + iv.areturn(overriden.getReturnType()); + mv.visitMaxs(0, 0); + mv.visitEnd(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 697c82e7147..f3fdbb7b180 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.OverridingUtil; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; @@ -314,74 +315,60 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if(!(myClass instanceof JetClass) || ((JetClass)myClass).isTrait() || ((JetClass)myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD)) return; - HashSet set = new HashSet(); - getAbstractMethods(descriptor.getDefaultType(), set); - for(FunctionDescriptor fun: set) { - int flags = Opcodes.ACC_PUBLIC; // TODO. + for (CallableDescriptor callableDescriptor : OverridingUtil.getEffectiveMembers(descriptor)) { + if(callableDescriptor instanceof FunctionDescriptor) { + FunctionDescriptor fun = (FunctionDescriptor) callableDescriptor; + DeclarationDescriptor containingDeclaration = fun.getContainingDeclaration(); + if(containingDeclaration instanceof ClassDescriptor) { + ClassDescriptor declaration = (ClassDescriptor) containingDeclaration; + PsiElement psiElement = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaration); + if(psiElement instanceof JetClass) { + JetClass jetClass = (JetClass) psiElement; + if(jetClass.isTrait()) { + int flags = Opcodes.ACC_PUBLIC; // TODO. - Method function = state.getTypeMapper().mapSignature(fun.getName(), fun); + Method function = state.getTypeMapper().mapSignature(fun.getName(), fun); + Method functionOriginal = state.getTypeMapper().mapSignature(fun.getName(), fun.getOriginal()); - final MethodVisitor mv = v.visitMethod(flags, function.getName(), function.getDescriptor(), null, null); - mv.visitCode(); + final MethodVisitor mv = v.visitMethod(flags, function.getName(), function.getDescriptor(), null, null); + mv.visitCode(); - codegen.generateThisOrOuter(descriptor); + codegen.generateThisOrOuter(descriptor); - Type[] argTypes = function.getArgumentTypes(); - InstructionAdapter iv = new InstructionAdapter(mv); - iv.load(0, JetTypeMapper.TYPE_OBJECT); - for (int i = 0, reg = 1; i < argTypes.length; i++) { - Type argType = argTypes[i]; - iv.load(reg, argType); - //noinspection AssignmentToForLoopParameter - reg += argType.getSize(); - } + Type[] argTypes = function.getArgumentTypes(); + InstructionAdapter iv = new InstructionAdapter(mv); + iv.load(0, JetTypeMapper.TYPE_OBJECT); + for (int i = 0, reg = 1; i < argTypes.length; i++) { + Type argType = argTypes[i]; + iv.load(reg, argType); + //noinspection AssignmentToForLoopParameter + reg += argType.getSize(); + } - ClassDescriptor containingDeclaration = (ClassDescriptor) fun.getContainingDeclaration(); - JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, state.getBindingContext()); - Type type = state.getTypeMapper().mapType(jetType); - if(type.getInternalName().equals("java/lang/Object")) { - jetType = containingDeclaration.getDefaultType(); - type = state.getTypeMapper().mapType(jetType); - } + JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, state.getBindingContext()); + Type type = state.getTypeMapper().mapType(jetType); + if(type.getInternalName().equals("java/lang/Object")) { + jetType = declaration.getDefaultType(); + type = state.getTypeMapper().mapType(jetType); + } - String fdescriptor = function.getDescriptor().replace("(","(" + type.getDescriptor()); - iv.invokestatic(state.getTypeMapper().jvmName((ClassDescriptor) fun.getContainingDeclaration(), OwnerKind.TRAIT_IMPL), function.getName(), fdescriptor); - iv.areturn(function.getReturnType()); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - } - - private void getAbstractMethods(JetType type, Set set) { - if(type.equals(JetStandardClasses.getAny())) { - return; - } + String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor()); + iv.invokestatic(state.getTypeMapper().jvmName((ClassDescriptor) fun.getContainingDeclaration(), OwnerKind.TRAIT_IMPL), function.getName(), fdescriptor); + if(function.getReturnType().getSort() == Type.OBJECT) { + iv.checkcast(function.getReturnType()); + } + iv.areturn(function.getReturnType()); + mv.visitMaxs(0, 0); + mv.visitEnd(); - for(JetType superType : type.getConstructor().getSupertypes()) { - getAbstractMethods(superType, set); - } - - PsiElement psiElement = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, type.getConstructor().getDeclarationDescriptor()); - if(psiElement instanceof JetClass) { - JetClass jetClass = (JetClass) psiElement; - for(JetDeclaration decl : jetClass.getDeclarations()) { - if(decl instanceof JetNamedFunction) { - JetNamedFunction jetNamedFunction = (JetNamedFunction) decl; - FunctionDescriptor funDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, decl); - set.removeAll(funDescriptor.getOverriddenDescriptors()); - - if(jetNamedFunction.getBodyExpression() == null || jetClass.isTrait()) { - set.add(funDescriptor); + FunctionCodegen.generateBridgeIfNeeded(context, state, v, function, fun, kind); + } } } } } - else if(psiElement instanceof PsiClass) { - // todo - PsiClass psiClass = (PsiClass) psiElement; - } } - + @Nullable private ClassDescriptor getOuterClassDescriptor() { if (myClass.getParent() instanceof JetClassObject) { @@ -762,9 +749,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return false; } - public boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) { + public static boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) { if(!exceptOwn) { - if(!state.getTypeMapper().isInterface((ClassDescriptor) type.getConstructor().getDeclarationDescriptor())) + if(!CodegenUtil.isInterface(type)) if(isParametrizedClass(type)) return true; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index c44f54556af..b637bcfb43f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -222,14 +222,6 @@ public class JetTypeMapper { return jvmName(descriptor, OwnerKind.IMPLEMENTATION); } - public boolean isInterface(ClassDescriptor jetClass) { - PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, jetClass); - if (declaration instanceof JetObjectDeclaration) { - return false; - } - return declaration instanceof JetClass && ((JetClass) declaration).isTrait(); - } - private static String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) { if (jetClass.getKind() == ClassKind.OBJECT) { return jvmNameForImplementation(jetClass); @@ -496,7 +488,7 @@ public class JetTypeMapper { else if (functionParent instanceof ClassDescriptor) { ClassDescriptor containingClass = (ClassDescriptor) functionParent; owner = jvmName(containingClass, OwnerKind.IMPLEMENTATION); - invokeOpcode = isInterface(containingClass) + invokeOpcode = CodegenUtil.isInterface(containingClass) ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL; needsReceiver = true; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MethodCodeGen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MethodCodeGen.java deleted file mode 100644 index d9d657ac822..00000000000 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MethodCodeGen.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.jetbrains.jet.codegen; - -/** - * @author max - */ -public class MethodCodeGen { - -} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 0de28e5e0fe..6dc17c82643 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -2,9 +2,7 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; -import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; -import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor; -import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; @@ -52,6 +50,10 @@ public class PropertyCodegen { private void generateBackingField(JetProperty p, PropertyDescriptor propertyDescriptor) { if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { + DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); + if(CodegenUtil.isInterface(containingDeclaration)) + return; + Object value = null; final JetExpression initializer = p.getInitializer(); if (initializer != null) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java index 087cbb7d6c4..50b34b7df98 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java @@ -18,6 +18,9 @@ import java.util.Set; */ public class OverridingUtil { + private OverridingUtil() { + } + public static Set getEffectiveMembers(@NotNull ClassDescriptor classDescriptor) { Collection allDescriptors = classDescriptor.getDefaultType().getMemberScope().getAllDescriptors(); Set allMembers = Sets.newLinkedHashSet(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeProjection.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeProjection.java index d401d388834..f85c20a6e2d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeProjection.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeProjection.java @@ -31,7 +31,7 @@ public class TypeProjection { @Override public String toString() { if (projection == Variance.INVARIANT) { - return type + ""; + return type.toString(); } return projection + " " + type; } diff --git a/idea/testData/codegen/traits/stdlib.jet b/idea/testData/codegen/traits/stdlib.jet new file mode 100644 index 00000000000..7be1c38af9c --- /dev/null +++ b/idea/testData/codegen/traits/stdlib.jet @@ -0,0 +1,44 @@ +trait ISized { + val size : Int +} + +trait ReadOnlyArray : ISized, Iterable { + fun get(index : Int) : T + + override fun iterator () : Iterator = object : Iterator { + private var index = 0 + + override fun hasNext() : Boolean = index < size + + val next : T + get() = get(index++) + } +} + +trait WriteOnlyArray : ISized { + fun set(index : Int, value : T) : Unit + + fun set(from: Int, count: Int, value: T) { + for(i in 0..(count-1)) { + set(i, value) + } + } +} + +class MutableArray(length: Int) : ReadOnlyArray, WriteOnlyArray { + private val array = Array(length) + + override fun get(index : Int) : T = array[index] + override fun set(index : Int, value : T) : Unit { array[index] = value } + + override val size : Int + get() = array.size +} + +fun box() : String { + var a = MutableArray (4) + a [0] = 10 + a.set(1, 2, 13) + a [3] = 40 + return "OK" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/codegen/TraitsTest.java b/idea/tests/org/jetbrains/jet/codegen/TraitsTest.java index 8ed803135fb..07acb80f120 100644 --- a/idea/tests/org/jetbrains/jet/codegen/TraitsTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/TraitsTest.java @@ -20,4 +20,9 @@ public class TraitsTest extends CodegenTestCase { blackBoxFile("traits/multiple.jet"); System.out.println(generateToText()); } + + public void testStdlib () throws Exception { + blackBoxFile("traits/stdlib.jet"); + System.out.println(generateToText()); + } } diff --git a/stdlib/src/jet/typeinfo/TypeInfo.java b/stdlib/src/jet/typeinfo/TypeInfo.java index 8fd2391567b..e4a971e90fe 100644 --- a/stdlib/src/jet/typeinfo/TypeInfo.java +++ b/stdlib/src/jet/typeinfo/TypeInfo.java @@ -1,6 +1,5 @@ package jet.typeinfo; -import com.sun.org.apache.bcel.internal.generic.MethodGen; import jet.JetObject; import jet.Tuple0; @@ -92,7 +91,7 @@ public abstract class TypeInfo implements JetObject { nullable = false; } - public TypeInfoVar(boolean nullable, Integer varIndex) { + public TypeInfoVar(boolean nullable, int varIndex) { this.nullable = nullable; this.varIndex = varIndex; } @@ -474,11 +473,12 @@ public abstract class TypeInfo implements JetObject { public List parseVars() { List list = null; - while(cur != string.length && string[cur] == 'T') { + while(cur < string.length && string[cur] == 'T') { if(list == null) { list = new LinkedList(); variables = new HashMap(); } + cur++; list.add(parseVar()); } return list == null ? Collections.emptyList() : list; @@ -508,7 +508,7 @@ public abstract class TypeInfo implements JetObject { } private String parseName() { - int c = ++cur; // skip 'T' + int c = cur; while (string[c] != ';') { c++; } @@ -522,7 +522,7 @@ public abstract class TypeInfo implements JetObject { cur += 3; return TypeInfoVariance.IN_VARIANCE; } - else if (string[cur] == 'o' && string[cur+1] == 'u' && string[cur+2] == 't' && string[cur+2] == ' ') { + else if (string[cur] == 'o' && string[cur+1] == 'u' && string[cur+2] == 't' && string[cur+3] == ' ') { cur += 4; return TypeInfoVariance.OUT_VARIANCE; } @@ -545,6 +545,7 @@ public abstract class TypeInfo implements JetObject { private TypeInfo parseType() { switch (string[cur]) { case 'L': + cur++; String name = parseName(); Class aClass; try { @@ -572,6 +573,7 @@ public abstract class TypeInfo implements JetObject { return new TypeInfoImpl(aClass, nullable,proj.toArray(new TypeInfoProjection[proj.size()])); case 'T': + cur++; return parseTypeVar(); default: @@ -580,6 +582,7 @@ public abstract class TypeInfo implements JetObject { } private TypeInfo parseTypeVar() { + TypeInfoVariance variance = parseVariance(); String name = parseName(); boolean nullable = false; if(string[cur] == '?') {