예제 #1
0
    def testRewriteClass(self):
        package = ir.Package(id=ids.TARGET_PACKAGE_ID)
        package.buildNameIndex()
        rootType = ir_types.getRootClassType()
        trait = package.addTrait(Name(["Tr"]),
                                 typeParameters=[], supertypes=[rootType], flags=frozenset([]))
        traitType = ir_types.ClassType(trait)
        traitMethod = package.addFunction(Name(["Tr", "m"]),
                                          returnType=ir_types.UnitType, typeParameters=[],
                                          parameterTypes=[traitType],
                                          flags=frozenset([PUBLIC, ABSTRACT,
                                                           METHOD]))
        trait.methods = [traitMethod]
        field = package.newField(Name(["Foo", "x"]),
                                 type=ir_types.I64Type, flags=frozenset([PRIVATE]))
        clas = package.addClass(Name(["Foo"]), typeParameters=[],
                                supertypes=[rootType, traitType],
                                constructors=[], fields=[field], methods=[],
                                flags=frozenset([PUBLIC, FINAL, ARRAY]))
        typeParam = package.addTypeParameter(clas, Name(["Foo", "T"]),
                                             upperBound=ir_types.getRootClassType(),
                                             lowerBound=ir_types.getNothingClassType(),
                                             flags=frozenset([STATIC]))
        clas.elementType = ir_types.VariableType(typeParam)
        ty = ir_types.ClassType(clas)
        constructor = package.addFunction(Name(["Foo", CONSTRUCTOR_SUFFIX]),
                                          returnType=ir_types.UnitType, typeParameters=[],
                                          parameterTypes=[ty],
                                          flags=frozenset([PUBLIC, METHOD]))
        clas.constructors = [constructor]
        localMethod = package.addFunction(Name(["Foo", "m"]), returnType=ir_types.I64Type,
                                          typeParameters=[], parameterTypes=[ty],
                                          flags=frozenset([PUBLIC, OVERRIDE,
                                                           METHOD]))
        otherPackage = ir.Package()
        loader = utils_test.FakePackageLoader([otherPackage])
        otherMethod = otherPackage.addFunction(Name(["Foo", "o"]),
                                               returnType=ir_types.I64Type,
                                               typeParameters=[],
                                               parameterTypes=[ir_types.getRootClassType()],
                                               flags=frozenset([PUBLIC, METHOD]))
        info = CompileInfo(None, package, loader)
        externMethod = externalizeDefn(info, otherMethod)
        builtinMethod = builtins.getBuiltinFunctionById(bytecode.BUILTIN_ROOT_CLASS_TO_STRING_ID)
        clas.methods = [localMethod, externMethod, builtinMethod]

        self.ser.package = package
        self.ser.writeClass(clas)
        self.des.package = package
        outClass = ir.Class(None, clas.id)
        self.des.readClass(outClass)
        self.assertEquals(clas, outClass)
예제 #2
0
    def defineClass(classData):
        clas = _builtinClassNameMap[classData["name"]]
        clas.id = getattr(bytecode, classData["id"])
        if not classData["isPrimitive"]:
            if classData["supertype"] is not None:
                superclass = _builtinClassNameMap[classData["supertype"]]
                clas.supertypes = [ir_types.ClassType(superclass)]
            else:
                clas.supertypes = []
            clas.constructors = [
                buildConstructor(ctorData, clas)
                for ctorData in classData["constructors"]
            ]
            clas.fields = [
                buildField(fieldData, index, clas)
                for index, fieldData in enumerate(classData["fields"])
            ]
        else:
            clas.supertypes = []
            clas.fields = []
            clas.isPrimitive = True
        inheritedMethodCount = len(clas.methods)
        for m in classData["methods"]:
            method = buildMethod(m, clas)
            clas.methods.append(method)

        _builtinClassTypeMap[classData["name"]] = clas
        _builtinClassIdMap[clas.id] = clas
예제 #3
0
    def setUp(self):
        super(TestExternalization, self).setUp()
        self.package = ir.Package(ids.TARGET_PACKAGE_ID)
        self.package.buildNameIndex()
        self.rootClassType = ir_types.getRootClassType()
        self.nothingClassType = ir_types.getNothingClassType()
        self.otherPackage = ir.Package()
        self.packageLoader = utils_test.FakePackageLoader([self.otherPackage])
        self.info = CompileInfo(None, self.package, self.packageLoader)

        field = self.otherPackage.newField(Name(["x"]),
                                           type=ir_types.I64Type,
                                           flags=frozenset([PUBLIC]))
        self.clas = self.otherPackage.addClass(Name(["Foo"]),
                                               typeParameters=[],
                                               supertypes=[self.rootClassType],
                                               constructors=[],
                                               fields=[field],
                                               methods=[],
                                               flags=frozenset([PUBLIC]))
        self.classTy = ir_types.ClassType(self.clas)
        ctor = self.otherPackage.addFunction(Name([CONSTRUCTOR_SUFFIX]),
                                             returnType=ir_types.UnitType,
                                             typeParameters=[],
                                             parameterTypes=[],
                                             flags=frozenset([PUBLIC, METHOD]))
        self.clas.constructors = [ctor]
        method = self.otherPackage.addFunction(Name(["m"]),
                                               returnType=ir_types.UnitType,
                                               typeParameters=[],
                                               parameterTypes=[],
                                               flags=frozenset(
                                                   [PUBLIC, METHOD]))
        self.clas.methods = [method]
        self.dep = self.package.ensureDependency(self.otherPackage)
예제 #4
0
 def testRewriteNestedExistentialClassType(self):
     package = ir.Package(id=ids.TARGET_PACKAGE_ID)
     C = package.addClass(Name(["C"]), typeParameters=[], fields=[])
     T = package.addTypeParameter(C, Name(["C", "T"]),
                                  upperBound=ir_types.getRootClassType(),
                                  lowerBound=ir_types.getNothingClassType(),
                                  flags=frozenset([STATIC]))
     X = package.addTypeParameter(None, Name(["X"]),
                                  upperBound=ir_types.VariableType(T),
                                  lowerBound=ir_types.getNothingClassType(),
                                  flags=frozenset([STATIC]),
                                  index=1)
     Y = package.addTypeParameter(None, Name(["Y"]),
                                  upperBound=ir_types.VariableType(X),
                                  lowerBound=ir_types.getNothingClassType(),
                                  flags=frozenset([STATIC]),
                                  index=2)
     package.buildNameIndex()
     self.des.typeParameters = [T]
     ty = ir_types.ExistentialType(
         [X],
         ir_types.ExistentialType(
             [Y],
             ir_types.ClassType(C, (ir_types.VariableType(Y),))))
     self.checkType(ty, package)
예제 #5
0
 def testExternalizeClassType(self):
     C = self.otherPackage.addClass(
         Name(["C"]),
         typeParameters=[],
         supertypes=[ir_types.getRootClassType()],
         constructors=[],
         fields=[],
         methods=[],
         flags=frozenset([PUBLIC]))
     externalizeType(self.info, ir_types.ClassType(C))
     self.assertIsNotNone(C.id.externIndex)
예제 #6
0
 def testExternalizeLocalClassTypeWithForeignArg(self):
     F = self.otherPackage.addClass(
         Name(["F"]),
         typeParameters=[],
         supertypes=[ir_types.getRootClassType()],
         constructors=[],
         fields=[],
         methods=[],
         flags=frozenset([PUBLIC]))
     C = self.package.addClass(Name(["C"]),
                               typeParameters=[],
                               supertypes=[ir_types.getRootClassType()],
                               constructors=[],
                               fields=[],
                               methods=[])
     T = self.package.addTypeParameter(
         C,
         Name(["T"]),
         upperBound=ir_types.getRootClassType(),
         lowerBound=ir_types.getNothingClassType())
     CFType = ir_types.ClassType(C, (ir_types.ClassType(F), ))
     externalizeType(self.info, CFType)
     self.assertIsNotNone(F.id.externIndex)
예제 #7
0
    def testRewriteExternClassType(self):
        package = ir.Package(id=ids.TARGET_PACKAGE_ID)
        package.buildNameIndex()
        depPackage = ir.Package()
        loader = utils_test.FakePackageLoader([depPackage])
        depClass = depPackage.addClass(Name(["C"]), typeParameters=[],
                                       supertypes=[ir_types.getRootClassType()],
                                       constructors=[], fields=[],
                                       methods=[], flags=frozenset([PUBLIC]))
        info = CompileInfo(None, package, loader)
        externClass = externalizeDefn(info, depClass)
        self.assertIn(EXTERN, externClass.flags)
        self.assertIs(depPackage, package.dependencies[0].package)
        self.assertIs(externClass, package.dependencies[0].externClasses[0])

        nullFlags = frozenset([ir_types.NULLABLE_TYPE_FLAG])
        externClassType = ir_types.ClassType(externClass, (), nullFlags)
        self.ser.writeType(externClassType)

        self.des.package = package
        outType = self.des.readType()
        self.assertEquals(externClassType, outType)
예제 #8
0
 def buildType(typeName):
     if typeName == "unit":
         return ir_types.UnitType
     elif typeName == "boolean":
         return ir_types.BooleanType
     elif typeName == "i8":
         return ir_types.I8Type
     elif typeName == "i16":
         return ir_types.I16Type
     elif typeName == "i32":
         return ir_types.I32Type
     elif typeName == "i64":
         return ir_types.I64Type
     elif typeName == "f32":
         return ir_types.F32Type
     elif typeName == "f64":
         return ir_types.F64Type
     else:
         m = re.match(r"([A-Za-z0-9_-]+)(\??)", typeName)
         clas = _builtinClassNameMap[m.group(1)]
         flags = frozenset([ir_types.NULLABLE_TYPE_FLAG] if m.group(2) ==
                           "?" else [])
         return ir_types.ClassType(clas, (), flags)
예제 #9
0
    def readType(self):
        bits = self.readVbn()
        form = bits & 0xF
        flagBits = bits >> 4

        flags = []
        if (flagBits & 1) != 0:
            flags.append(ir_types.NULLABLE_TYPE_FLAG)
        if (flagBits & ~1) != 0:
            raise IOError("invalid type flags")
        flags = frozenset(flags)

        ty = None
        if form == 0:
            ty = ir_types.UnitType
        elif form == 1:
            ty = ir_types.BooleanType
        elif form == 2:
            ty = ir_types.I8Type
        elif form == 3:
            ty = ir_types.I16Type
        elif form == 4:
            ty = ir_types.I32Type
        elif form == 5:
            ty = ir_types.I64Type
        elif form == 6:
            ty = ir_types.F32Type
        elif form == 7:
            ty = ir_types.F64Type
        elif form == 8:
            # CLASS_TYPE
            packageIndex = self.readVbn()
            defnIndex = self.readVbn()
            if packageIndex == ids.BUILTIN_PACKAGE_INDEX:
                clas = builtins.getBuiltinClassById(defnIndex)
            elif packageIndex == ids.LOCAL_PACKAGE_INDEX:
                clas = self.package.classes[defnIndex]
            elif self.isLinked:
                clas = self.package.dependencies[packageIndex].linkedClasses[
                    defnIndex]
            else:
                clas = self.package.dependencies[packageIndex].externClasses[
                    defnIndex]
            typeArgs = tuple(self.readList(self.readType))
            ty = ir_types.ClassType(clas, typeArgs, flags)
        elif form == 9:
            # TRAIT_TYPE
            packageIndex = self.readVbn()
            defnIndex = self.readVbn()
            if packageIndex == ids.BUILTIN_PACKAGE_INDEX:
                trait = builtins.getBuiltinTraitById(defnIndex)
            elif packageIndex == ids.LOCAL_PACKAGE_INDEX:
                trait = self.package.traits[defnIndex]
            elif self.isLinked:
                trait = self.package.dependencies[packageIndex].linkedTraits[
                    defnIndex]
            else:
                trait = self.package.dependencies[packageIndex].externTraits[
                    defnIndex]
            typeArgs = tuple(self.readList(self.readType))
            ty = ir_types.ClassType(trait, typeArgs, flags)
        elif form == 10:
            # VARIABLE_TYPE
            index = self.readVbn()
            assert 0 <= index and index < len(self.typeParameters)
            param = self.typeParameters[index]
            ty = ir_types.VariableType(param, flags)
        elif form == 11:
            # EXISTENTIAL_TYPE
            if flagBits != 0:
                raise IOError("flags must not be set for existential type")
            typeParameterCount = len(self.typeParameters)
            variables = self.readList(self.readTypeParameter)
            innerType = self.readType()
            del self.typeParameters[typeParameterCount:]
            ty = ir_types.ExistentialType(variables, innerType)
        else:
            raise IOError("invalid type flags")

        if ty.isPrimitive() and flagBits != 0:
            raise IOError("invalid type flags")

        return ty
예제 #10
0
    def testRewriteForeignClass(self):
        # "Compile" a foreign package with a class we'll depend on.
        otherPackage = ir.Package(id=ids.TARGET_PACKAGE_ID, name=Name(["foo", "bar"]))
        otherPackage.buildNameIndex()
        rootType = ir_types.getRootClassType()
        trait = otherPackage.addTrait(Name(["Tr"]), typeParameters=[],
                                      supertypes=[rootType], flags=frozenset([PUBLIC]))
        traitType = ir_types.ClassType(trait)
        traitMethod = otherPackage.addFunction(Name(["Tr", "m"]),
                                               returnType=rootType,
                                               typeParameters=[],
                                               parameterTypes=[traitType],
                                               flags=frozenset([PUBLIC, METHOD, ABSTRACT]))
        trait.methods = [traitMethod]

        clas = otherPackage.addClass(Name(["C"]), typeParameters=[], supertypes=[],
                                     elementType=ir_types.I8Type,
                                     flags=frozenset([PUBLIC, ARRAY, FINAL]))
        T = otherPackage.addTypeParameter(clas, Name(["C", "T"]),
                                          upperBound=ir_types.getRootClassType(),
                                          lowerBound=ir_types.getNothingClassType(),
                                          flags=frozenset([PUBLIC, STATIC]))
        classType = ir_types.ClassType(clas, (ir_types.VariableType(T),))
        init = otherPackage.addFunction(Name(["C", CLASS_INIT_SUFFIX]),
                                        returnType=ir_types.UnitType,
                                        typeParameters=[T], parameterTypes=[classType],
                                        flags=frozenset([PRIVATE, METHOD, NATIVE]))
        clas.initializer = init
        ctor = otherPackage.addFunction(Name(["C", CONSTRUCTOR_SUFFIX]),
                                        returnType=ir_types.UnitType,
                                        typeParameters=[T], parameterTypes=[classType],
                                        flags=frozenset([PUBLIC, CONSTRUCTOR, METHOD, NATIVE]))
        clas.constructors = [ctor]
        method1 = otherPackage.addFunction(Name(["C", "m"]),
                                           returnType=ir_types.VariableType(T),
                                           typeParameters=[T], parameterTypes=[classType],
                                           flags=frozenset([PUBLIC, METHOD, ABSTRACT]))

        method2 = otherPackage.addFunction(Name(["C", "n"]),
                                           returnType=ir_types.I32Type,
                                           typeParameters=[T], parameterTypes=[classType],
                                           flags=frozenset([PUBLIC, STATIC, METHOD, NATIVE]))
        clas.methods = [method1, method2]
        field = otherPackage.newField(Name(["C", "x"]), type=ir_types.VariableType(T),
                                      flags=frozenset([PUBLIC, LET]))
        clas.fields = [field]

        # "Compile" a package that depends on the foreign class.
        externPackage = self.copyPackage(otherPackage)
        foreignClass = externPackage.findClass(name=clas.name)
        package = ir.Package(ids.TARGET_PACKAGE_ID)
        package.buildNameIndex()
        externLoader = utils_test.FakePackageLoader([externPackage])
        info = CompileInfo(None, package, externLoader)
        externClass = externalizeDefn(info, foreignClass)

        # Serialize and deserialize the package.
        self.ser.package = package
        self.ser.serialize()
        loadedPackage = self.copyPackage(otherPackage)
        desLoader = utils_test.FakePackageLoader([loadedPackage])
        self.des = serialize.Deserializer(self.file, desLoader)
        self.des.deserialize()
        rewrittenPackage = self.des.package
        rewrittenClass = rewrittenPackage.dependencies[0].externClasses[0]

        # Compare properties which are safe to compare. Anything that refers back to the class
        # (e.g., receiver types of constructors and methods) is not safe to compare.
        self.assertEquals(externClass.name, rewrittenClass.name)
        self.assertEquals(externClass.typeParameters, rewrittenClass.typeParameters)
        self.assertEquals(externClass.supertypes, rewrittenClass.supertypes)
        self.assertIsNone(rewrittenClass.initializer)
        self.assertEquals(len(externClass.constructors), len(rewrittenClass.constructors))
        self.assertEquals(len(externClass.fields), len(rewrittenClass.fields))
        self.assertEquals(len(externClass.methods), len(rewrittenClass.methods))
        self.assertEquals(externClass.elementType, rewrittenClass.elementType)
        self.assertEquals(externClass.flags, rewrittenClass.flags)
예제 #11
0
 def testRewriteSimpleTraitType(self):
     package = ir.Package(id=ids.TARGET_PACKAGE_ID)
     Tr = package.addTrait(name=Name(["Tr"]))
     self.checkType(ir_types.ClassType(Tr), package)
예제 #12
0
 def testRewriteNullableClassType(self):
     package = ir.Package(id=ids.TARGET_PACKAGE_ID)
     C = package.addClass(name=Name(["C"]))
     ty = ir_types.ClassType(C, (), frozenset([ir_types.NULLABLE_TYPE_FLAG]))
     self.checkType(ty, package)
예제 #13
0
 def testRewriteSimpleClassType(self):
     package = ir.Package(id=ids.TARGET_PACKAGE_ID)
     C = package.addClass(name=Name(["C"]))
     self.checkType(ir_types.ClassType(C), package)