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)
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)
def testRewriteTraitTypeWithArgs(self): package = ir.Package(id=ids.TARGET_PACKAGE_ID) Tr = package.addTrait(Name(["Tr"]), typeParameters=[]) S = package.addTypeParameter(Tr, Name(["Tr", "S"])) T = package.addTypeParameter(Tr, Name(["Tr", "T"])) self.des.typeParameters = [S, T] self.checkType(ir_types.ClassType.forReceiver(Tr), package)
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)
def testRewriteClassTypeWithArgs(self): package = ir.Package(id=ids.TARGET_PACKAGE_ID) C = package.addClass(Name(["C"]), typeParameters=[]) S = package.addTypeParameter(C, Name(["C", "S"])) T = package.addTypeParameter(C, Name(["C", "T"])) self.des.typeParameters = [S, T] self.checkType(ir_types.ClassType.forReceiver(C), package)
def testMangleFunctionNameExistential(self): package = ir.Package(ids.TARGET_PACKAGE_ID) C = package.addClass(Name(["C"]), typeParameters=[]) S = package.addTypeParameter(C, Name(["S"]), upperBound=getRootClassType(), lowerBound=getNothingClassType()) T = package.addTypeParameter(C, Name(["T"]), upperBound=getRootClassType(), lowerBound=getNothingClassType()) P = package.addTypeParameter(None, Name(["P"]), upperBound=getRootClassType(), lowerBound=getNothingClassType()) PType = VariableType(P) X = package.addTypeParameter(None, Name(["X"]), upperBound=getRootClassType(), lowerBound=getNothingClassType()) XType = VariableType(X) eXType = ExistentialType((X, ), ClassType(C, (PType, XType))) f = package.addFunction(Name(["foo"]), typeParameters=[P], parameterTypes=[eXType]) expected = "foo[<C::Object>C::Nothing](E[<C::Object>C::Nothing]C:C[V0,V1])" self.assertEquals(expected, ir.mangleFunctionShortName(f, package))
def testRewriteForeignMethodId(self): package = ir.Package(ids.TARGET_PACKAGE_ID) package.buildNameIndex() otherPackage = ir.Package() method = otherPackage.addFunction(Name(["foo"]), returnType=ir_types.UnitType, typeParameters=[], parameterTypes=[], flags=frozenset([PUBLIC, METHOD])) loader = utils_test.FakePackageLoader([otherPackage]) info = CompileInfo(None, package, loader) externMethod = externalizeDefn(info, method) self.ser.package = package self.ser.writeMethodId(externMethod) self.des.package = package outMethod = self.des.readMethodId() self.assertIs(externMethod, outMethod)
def testRewriteForeignTrait(self): # "Compile" a foreign package with a trait 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])) T = otherPackage.addTypeParameter(trait, Name(["Tr", "T"]), upperBound=rootType, lowerBound=ir_types.getNothingClassType(), flags=frozenset([PUBLIC, STATIC])) traitType = ir_types.ClassType.forReceiver(trait) traitMethod = otherPackage.addFunction(Name(["Tr", "m"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[traitType], flags=frozenset([PUBLIC, METHOD, ABSTRACT])) trait.methods = [traitMethod] # "Compile" a package that depends on the foreign trait. externPackage = self.copyPackage(otherPackage) foreignTrait = externPackage.findTrait(name=trait.name) package = ir.Package(ids.TARGET_PACKAGE_ID) package.buildNameIndex() externLoader = utils_test.FakePackageLoader([externPackage]) info = CompileInfo(None, package, externLoader) externTrait = externalizeDefn(info, foreignTrait) # 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 rewrittenTrait = rewrittenPackage.dependencies[0].externTraits[0] # Compare properties which are safe to compare. Anything that refers back to the trait # (e.g., receiver types of constructors and methods) is not safe to compare. self.assertEquals(externTrait.name, rewrittenTrait.name) self.assertEquals(externTrait.typeParameters, rewrittenTrait.typeParameters) self.assertEquals(externTrait.supertypes, rewrittenTrait.supertypes) self.assertEquals(len(externTrait.methods), len(rewrittenTrait.methods)) self.assertEquals(externTrait.flags, rewrittenTrait.flags)
def __init__(self, inFile, packageLoader): self.inFile = inFile self.packageLoader = packageLoader self.package = ir.Package() self.isLinked = False self.entryFunctionIndex = None self.initFunctionIndex = None self.typeParameters = []
def testRewriteLocalMethodId(self): package = ir.Package(ids.TARGET_PACKAGE_ID) method = package.addFunction(Name(["foo"]), returnType=ir_types.UnitType, typeParameters=[], parameterTypes=[], flags=frozenset([METHOD])) self.ser.package = package self.ser.writeMethodId(method) self.des.package = package outMethod = self.des.readMethodId() self.assertIs(method, outMethod)
def testMangleFunctionNameSimple(self): package = ir.Package(ids.TARGET_PACKAGE_ID) f = self.makeFunction(Name(["foo", "bar", "baz"]), returnType=UnitType, typeParameters=[], parameterTypes=[ UnitType, BooleanType, I8Type, I16Type, I32Type, I64Type, F32Type, F64Type ]) expected = Name(["foo", "bar", "baz(U,Z,B,S,I,L,F,D)"]) self.assertEquals(expected, ir.mangleFunctionName(f, package))
def testRewriteGlobal(self): package = ir.Package() package.buildNameIndex() globl = package.addGlobal(Name(["g"]), sourceName="g", type=ir_types.I64Type, flags=frozenset([PUBLIC, LET])) self.ser.package = package self.ser.writeGlobal(globl) self.des.package = package outGlobal = ir.Global(None, globl.id) self.des.readGlobal(outGlobal) self.assertEquals(globl, outGlobal)
def testRewriteTypeParameter(self): package = ir.Package(ids.TARGET_PACKAGE_ID) package.buildNameIndex() typeParam = package.addTypeParameter(None, Name(["T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType(), flags=frozenset([STATIC]), index=0) self.ser.package = package self.ser.writeTypeParameter(typeParam) self.des.package = package outTypeParam = self.des.readTypeParameter() self.assertEquals(typeParam, outTypeParam)
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)
def testMangleFunctionNameClasses(self): package = ir.Package(ids.TARGET_PACKAGE_ID) Local = package.addClass(Name(["local", "Local"]), typeParameters=[]) P = package.addTypeParameter(Local, Name(["P"])) Q = package.addTypeParameter(Local, Name(["Q"])) otherPackage = ir.Package(name=Name(["foo", "bar", "baz"])) otherPackage.id.index = 0 Foreign = otherPackage.addClass(Name(["foreign", "Foreign"]), typeParameters=[]) Foreign.id.packageId = otherPackage.id S = otherPackage.addTypeParameter(Foreign, Name(["S"])) T = otherPackage.addTypeParameter(Foreign, Name(["T"])) package.dependencies = [ ir.PackageDependency(otherPackage.name, None, None) ] X = package.addTypeParameter(None, Name(["X"]), upperBound=getRootClassType(), lowerBound=getNothingClassType(), flags=frozenset([STATIC])) XType = VariableType(X) Y = package.addTypeParameter(None, Name(["Y"]), upperBound=getRootClassType(), lowerBound=getNothingClassType()) YType = VariableType(Y, frozenset([NULLABLE_TYPE_FLAG])) LocalType = ClassType(Local, (XType, YType)) ForeignType = ClassType(Foreign, (YType, XType), frozenset([NULLABLE_TYPE_FLAG])) BuiltinType = getRootClassType() f = package.addFunction( Name(["quux"]), typeParameters=[X, Y], parameterTypes=[LocalType, ForeignType, BuiltinType]) expected = "quux[s<C::Object>C::Nothing,<C::Object>C::Nothing](C:local.Local[V0,V1?],Cfoo.bar.baz:foreign.Foreign[V1?,V0]?,C::Object)" self.assertEquals(expected, ir.mangleFunctionShortName(f, package))
def testRewriteField(self): package = ir.Package() package.buildNameIndex() field = package.newField(Name(["C", "foo"]), type=ir_types.I64Type, flags=frozenset([PUBLIC, LET])) self.ser.package = package self.ser.writeField(field) self.des.package = package clas = package.addClass(Name(["C"])) outField = self.des.readField(clas, 2) self.assertEquals(field, outField) self.assertIs(clas, outField.definingClass) self.assertEquals(2, outField.index)
def testRewriteName(self): package = ir.Package() package.buildNameIndex() foobar = Name(["foo", "bar"]) bazquux = Name(["baz", "quux"]) package.findOrAddName(foobar) package.findOrAddName(bazquux) self.ser.package = package self.ser.writeName(foobar) self.ser.writeName(bazquux) self.des.package = package self.assertEquals(foobar, self.des.readName()) self.assertEquals(bazquux, self.des.readName())
def testRewriteTrait(self): package = ir.Package(ids.TARGET_PACKAGE_ID) package.buildNameIndex() rootType = ir_types.getRootClassType() trait = package.addTrait(Name(["Tr"]), typeParameters=[], supertypes=[rootType], flags=frozenset([PUBLIC])) typeParam = package.addTypeParameter(trait, Name(["Tr", "T"]), upperBound=rootType, lowerBound=ir_types.getNothingClassType(), flags=frozenset([STATIC])) traitType = ir_types.ClassType.forReceiver(trait) traitMethod = package.addFunction(Name(["Tr", "m"]), returnType=ir_types.UnitType, typeParameters=[typeParam], parameterTypes=[traitType], flags=frozenset([PUBLIC, METHOD, ABSTRACT])) trait.methods = [traitMethod] self.ser.package = package self.ser.writeTrait(trait) self.des.package = package outTrait = ir.Trait(None, trait.id) self.des.readTrait(outTrait) self.assertEquals(trait, outTrait)
def testRewriteSimpleClassType(self): package = ir.Package(id=ids.TARGET_PACKAGE_ID) C = package.addClass(name=Name(["C"])) self.checkType(ir_types.ClassType(C), package)
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)
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)
def testRewriteSimpleTraitType(self): package = ir.Package(id=ids.TARGET_PACKAGE_ID) Tr = package.addTrait(name=Name(["Tr"])) self.checkType(ir_types.ClassType(Tr), package)
def testRewriteVariableType(self): package = ir.Package(id=ids.TARGET_PACKAGE_ID) T = package.addTypeParameter(None, Name(["T"]), index=4) self.des.typeParameters = [None, None, None, None, T] self.checkType(ir_types.VariableType(T), package)