def testTraitInheritTraitMultipleTimesDirectlySameTypes(self): source = "trait Foo[static T]\n" + \ "class Bar <: Foo[Object]\n" + \ "trait Baz <: Bar, Foo[Object]" info = self.analyzeFromSource(source) Foo = info.package.findTrait(name="Foo") Bar = info.package.findClass(name="Bar") Baz = info.package.findTrait(name="Baz") fooType = ClassType(Foo, (getRootClassType(),)) self.assertEquals([ClassType(Bar), getRootClassType(), fooType], Baz.supertypes)
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 testExternalizeLocalClassTypeWithForeignArg(self): T = self.otherPackage.addTypeParameter(ir.Name(["T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType()) S = self.package.addTypeParameter(ir.Name(["S"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType()) C = self.package.addClass(ir.Name(["C"]), typeParameters=[S], supertypes=[ir_types.getRootClassType()], constructors=[], fields=[], methods=[]) self.externalizer.externalizeType(ir_types.ClassType(C, (ir_types.VariableType(T),))) self.assertIsNotNone(T.id.externIndex)
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)
def testInheritForeignTypeInForeignTypeInSamePackage(self): package = Package(name=Name(["foo"])) barClass = package.addClass(Name(["Bar"]), sourceName="Bar", typeParameters=[], supertypes=[getRootClassType()], constructors=[], fields=[], methods=[], flags=frozenset([PUBLIC])) bazClass = package.addClass(Name(["Baz"]), sourceName="Baz", typeParameters=[], supertypes=[ClassType(barClass), getRootClassType()], constructors=[], fields=[], methods=[], flags=frozenset([PUBLIC])) loader = FakePackageLoader([package]) info = self.analyzeFromSource("class Quux <: foo.Baz", packageLoader=loader) quuxClass = info.package.findClass(name="Quux") self.assertEquals([ClassType(bazClass), ClassType(barClass), getRootClassType()], quuxClass.supertypes)
def testInheritFromForeignType(self): package = Package(name=Name(["foo"])) foreignClass = package.addClass(Name(["Bar"]), sourceName="Bar", typeParameters=[], supertypes=[getRootClassType()], constructors=[], fields=[], methods=[], flags=frozenset([PUBLIC])) field = package.newField(Name(["Bar", "x"]), sourceName="x", flags=frozenset([PUBLIC])) foreignClass.fields = [field] loader = FakePackageLoader([package]) source = "class Baz <: foo.Bar" info = self.analyzeFromSource(source, packageLoader=loader) bazClass = info.package.findClass(name="Baz") self.assertEquals([ClassType(foreignClass), getRootClassType()], bazClass.supertypes) bazScope = info.getScope(bazClass) self.assertTrue(bazScope.isBound("x"))
def testClassInheritFromTraitWithHigherClass(self): source = "trait Tr\n" + \ "class Foo <: Tr" info = self.analyzeFromSource(source) Tr = info.package.findTrait(name="Tr") Foo = info.package.findClass(name="Foo") self.assertEquals([getRootClassType(), ClassType(Tr)], Foo.supertypes)
def testExternalizeCyclicTypeParameters(self): S = self.package.addTypeParameter(None, Name(["S"]), upperBound=ir_types.getRootClassType()) T = self.package.addTypeParameter(None, Name(["T"]), upperBound=ir_types.VariableType(S)) S.lowerBound = ir_types.VariableType(T) externalizeTypeParameter(self.info, S)
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 setUp(self): super(TestExternalization, self).setUp() self.package = ir.Package(ids.TARGET_PACKAGE_ID) self.rootClassType = ir_types.getRootClassType() self.nothingClassType = ir_types.getNothingClassType() self.otherPackage = ir.Package() self.packageLoader = utils_test.FakePackageLoader([self.otherPackage]) self.externalizer = externalization.Externalizer(self.package, self.packageLoader) field = self.otherPackage.newField(ir.Name(["x"]), type=ir_types.I64Type, flags=frozenset([flags.PUBLIC])) self.clas = self.otherPackage.addClass(ir.Name(["Foo"]), typeParameters=[], supertypes=[self.rootClassType], constructors=[], fields=[field], methods=[], flags=frozenset([flags.PUBLIC])) self.classTy = ir_types.ClassType(self.clas) ctor = self.otherPackage.addFunction(ir.Name([ir.CONSTRUCTOR_SUFFIX]), None, ir_types.UnitType, [], [], None, None, frozenset([flags.PUBLIC, flags.METHOD])) self.clas.constructors = [ctor] method = self.otherPackage.addFunction(ir.Name(["m"]), None, ir_types.UnitType, [], [], None, None, frozenset([flags.PUBLIC, flags.METHOD])) self.clas.methods = [method] self.param = self.otherPackage.addTypeParameter(ir.Name(["T"]), upperBound=self.rootClassType, lowerBound=self.nothingClassType, flags=frozenset([flags.STATIC])) self.dep = self.package.ensureDependency(self.otherPackage) self.externParam = self.externalizer.externalizeDefn(self.param) self.varTy = ir_types.VariableType(self.param)
def testExternalizeTrait(self): trait = self.otherPackage.addTrait(Name(["Tr"]), typeParameters=[], supertypes=[self.rootClassType], methods=[], flags=frozenset([PUBLIC])) T = self.otherPackage.addTypeParameter(trait, Name(["Tr", "T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType()) traitType = ir_types.ClassType.forReceiver(trait) method = self.otherPackage.addFunction(Name(["Tr", "f"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[traitType], flags=frozenset([PUBLIC, METHOD])) privateMethod = self.otherPackage.addFunction(Name(["Tr", "g"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[traitType], flags=frozenset([PRIVATE, METHOD])) trait.methods = [method, privateMethod] externTrait = externalizeDefn(self.info, trait) expected = ir.Trait(Name(["Tr"]), trait.id, typeParameters=[T], supertypes=[self.rootClassType], flags=frozenset([PUBLIC, EXTERN])) expectedMethod = ir.Function(Name(["Tr", "f"]), method.id, returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[traitType], flags=frozenset([EXTERN, PUBLIC, METHOD])) expected.methods = [expectedMethod] self.assertEquals(expected, externTrait)
def testTraitInheritFromTrait(self): source = "trait Foo\n" + \ "trait Bar <: Foo" info = self.analyzeFromSource(source) Foo = info.package.findTrait(name="Foo") Bar = info.package.findTrait(name="Bar") self.assertEquals([getRootClassType(), ClassType(Foo)], Bar.supertypes)
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 testExternalizeExistentialType(self): X = self.otherPackage.addTypeParameter(ir.Name(["X"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType()) ty = ir_types.ExistentialType((X,), ir_types.VariableType(X)) self.externalizer.externalizeType(ty) self.assertIsNotNone(X.id.externIndex)
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 testExternalizeClassType(self): C = self.otherPackage.addClass(ir.Name(["C"]), typeParameters=[], supertypes=[ir_types.getRootClassType()], constructors=[], fields=[], methods=[]) self.externalizer.externalizeType(ir_types.ClassType(C)) self.assertIsNotNone(C.id.externIndex)
def testWithBaseClass(self): source = "class Foo\n" + \ "class Bar <: Foo" info = self.analyzeFromSource(source) ast = info.ast fooClass = info.package.findClass(name="Foo") barClass = info.package.findClass(name="Bar") self.assertEquals([ClassType(fooClass), getRootClassType()], barClass.supertypes)
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)
def testInheritForeignTypeInForeignTypeInDifferentPackage(self): fooPackage = Package(name=Name(["foo"])) barClass = fooPackage.addClass(Name(["Bar"]), sourceName="Bar", typeParameters=[], supertypes=[getRootClassType()], constructors=[], fields=[], methods=[], flags=frozenset([PUBLIC])) bazPackage = Package(name=Name(["baz"])) loader = FakePackageLoader([fooPackage, bazPackage]) bazPackage.dependencies.append(PackageDependency.fromPackage(fooPackage)) quuxClass = bazPackage.addClass(Name(["Quux"]), sourceName="Quux", typeParameters=[], supertypes=[ClassType(barClass), getRootClassType()], constructors=[], fields=[], methods=[], flags=frozenset([PUBLIC])) info = self.analyzeFromSource("class Zzyzx <: baz.Quux", packageLoader=loader) zzyzxClass = info.package.findClass(name="Zzyzx") self.assertEquals([ClassType(quuxClass), ClassType(barClass), getRootClassType()], zzyzxClass.supertypes)
def testExternalizeCyclicTypeParameters(self): S = self.package.addTypeParameter( None, Name(["S"]), upperBound=ir_types.getRootClassType()) T = self.package.addTypeParameter(None, Name(["T"]), upperBound=ir_types.VariableType(S)) S.lowerBound = ir_types.VariableType(T) externalizeTypeParameter(self.info, S)
def makeTypeParameter(self, name, **args): import builtins defaultValues = {"astDefn": None, "upperBound": getRootClassType(), "lowerBound": getNothingClassType(), "flags": frozenset()} self.fillDefaultValues(args, defaultValues) args["id"] = self.typeParameterCounter() return TypeParameter(name, **args)
def testTraitInheritFromClassAndSameTrait(self): source = "class Foo\n" + \ "trait Bar <: Foo\n" + \ "trait Baz <: Foo, Bar" info = self.analyzeFromSource(source) Foo = info.package.findClass(name="Foo") Bar = info.package.findTrait(name="Bar") Baz = info.package.findTrait(name="Baz") self.assertEquals([ClassType(Foo), getRootClassType(), ClassType(Bar)], Baz.supertypes)
def testClassInheritTraitMultipleTimesIndirectlySameType(self): source = "trait Foo\n" + \ "trait Bar <: Foo\n" + \ "class Baz <: Foo, Bar" info = self.analyzeFromSource(source) Foo = info.package.findTrait(name="Foo") Bar = info.package.findTrait(name="Bar") Baz = info.package.findClass(name="Baz") self.assertEquals([getRootClassType(), ClassType(Foo), ClassType(Bar)], Baz.supertypes)
def testTypeParameterCycleForeign(self): package = Package(name=Name(["foo"])) barClass = package.addClass(Name(["Bar"]), sourceName="Bar", typeParameters=[], supertypes=[getRootClassType()], constructors=[], fields=[], methods=[], flags=frozenset([PUBLIC])) loader = FakePackageLoader([package]) source = "class Baz <: foo.Bar\n" + \ "def f[static T <: Baz >: foo.Bar] = ()" self.assertRaises(InheritanceException, self.analyzeFromSource, source, packageLoader=loader)
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)
def testRewriteTypeParameter(self): package = ir.Package(ids.TARGET_PACKAGE_ID) typeParam = package.addTypeParameter(ir.Name(["T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType(), flags=frozenset([flags.STATIC])) self.ser.package = package self.ser.writeTypeParameter(typeParam) outTypeParam = ir.TypeParameter(None, typeParam.id) self.des.package = package self.des.readTypeParameter(outTypeParam) self.assertEquals(typeParam, outTypeParam)
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 testRewriteClass(self): package = ir.Package(ids.TARGET_PACKAGE_ID) typeParam = package.addTypeParameter(ir.Name(["Foo", "T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType(), flags=frozenset([flags.STATIC])) supertype = ir_types.getRootClassType() field = package.newField(ir.Name(["Foo", "x"]), type=ir_types.I64Type, flags=frozenset([flags.PRIVATE])) clas = package.addClass(ir.Name(["Foo"]), typeParameters=[typeParam], supertypes=[supertype], constructors=[], fields=[field], methods=[], elementType=ir_types.VariableType(typeParam), flags=frozenset([flags.PUBLIC, flags.FINAL, flags.ARRAY])) ty = ir_types.ClassType(clas) constructor = package.addFunction(ir.Name(["Foo", ir.CONSTRUCTOR_SUFFIX]), None, ir_types.UnitType, [], [ty], None, None, frozenset([flags.PUBLIC, flags.METHOD])) clas.constructors = [constructor] localMethod = package.addFunction(ir.Name(["Foo", "m"]), None, ir_types.I64Type, [], [ty], None, None, frozenset([flags.PUBLIC, flags.METHOD])) otherPackage = ir.Package() loader = utils_test.FakePackageLoader([otherPackage]) otherMethod = otherPackage.addFunction(ir.Name(["Foo", "o"]), None, ir_types.I64Type, [], [ir_types.getRootClassType()], None, None, frozenset([flags.PUBLIC, flags.METHOD])) externalizer = externalization.Externalizer(package, loader) externMethod = externalizer.externalizeDefn(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 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)
def testExternalizeClass(self): clas = self.otherPackage.addClass(ir.Name(["C"]), typeParameters=[self.param], supertypes=[self.rootClassType], constructors=[], fields=[], methods=[], elementType=self.varTy, flags=frozenset([flags.ARRAY, flags.FINAL, flags.PUBLIC])) clasTy = ir_types.ClassType(clas, (self.varTy,)) ctor = self.otherPackage.addFunction(ir.Name(["C", ir.CONSTRUCTOR_SUFFIX]), None, ir_types.UnitType, [self.param], [clasTy], None, None, frozenset([flags.PUBLIC, flags.METHOD])) clas.constructors = [ctor] field = self.otherPackage.newField(ir.Name(["C", "x"]), type=clasTy, flags=frozenset([flags.PUBLIC])) clas.fields = [field] method = self.otherPackage.addFunction(ir.Name(["C", "f"]), None, ir_types.UnitType, [self.param], [clasTy], None, None, frozenset([flags.PUBLIC, flags.METHOD])) builtinMethod = \ builtins.getBuiltinFunctionById(bytecode.BUILTIN_ROOT_CLASS_TO_STRING_ID) clas.methods = [method, builtinMethod] externClass = self.externalizer.externalizeDefn(clas) expected = ir.Class(ir.Name(["C"]), clas.id, typeParameters=[self.externParam], supertypes=[self.rootClassType], elementType=self.varTy, flags=frozenset([flags.ARRAY, flags.FINAL, flags.PUBLIC, flags.EXTERN])) expectedCtor = ir.Function(ir.Name(["C", ir.CONSTRUCTOR_SUFFIX]), ctor.id, returnType=ir_types.UnitType, typeParameters=[self.externParam], parameterTypes=[clasTy], flags=frozenset([flags.PUBLIC, flags.METHOD, flags.EXTERN])) expected.constructors = [expectedCtor] expectedField = ir.Field(ir.Name(["C", "x"]), type=clasTy, flags=frozenset([flags.PUBLIC])) expected.fields = [expectedField] expectedMethod = ir.Function(ir.Name(["C", "f"]), method.id, returnType=ir_types.UnitType, typeParameters=[self.externParam], parameterTypes=[clasTy], flags=frozenset([flags.PUBLIC, flags.METHOD, flags.EXTERN])) externBuiltinMethod = ir.Function(ir.Name(["Object", "to-string"]), builtinMethod.id, returnType=ir_types.getStringType(), typeParameters=[], parameterTypes=[ir_types.getRootClassType()], flags=frozenset([flags.EXTERN, flags.PUBLIC, flags.METHOD])) expected.methods = [expectedMethod, externBuiltinMethod] self.assertEquals(expected, externClass)
def testInheritFromImportedClass(self): foo = Package(name=Name(["foo"])) Bar = foo.addClass(Name(["Bar"]), sourceName="Bar", typeParameters=[], supertypes=[getRootClassType()], constructors=[], fields=[], methods=[], flags=frozenset([PUBLIC])) x = foo.newField(Name(["Bar", "x"]), sourceName="x", flags=frozenset([PUBLIC, LET])) Bar.fields.append(x) source = "import foo.Bar\n" + \ "class Baz <: Bar" info = self.analyzeFromSource(source, packageLoader=FakePackageLoader([foo])) bazScope = info.getScope(info.ast.modules[0].definitions[1]) self.assertTrue(bazScope.isBound("x"))
def testRewriteForeignTypeParameter(self): package = ir.Package(ids.TARGET_PACKAGE_ID) otherPackage = ir.Package() typeParam = otherPackage.addTypeParameter(ir.Name(["T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType(), flags=frozenset([flags.STATIC])) loader = utils_test.FakePackageLoader([otherPackage]) externalizer = externalization.Externalizer(package, loader) foreignTypeParam = externalizer.externalizeDefn(typeParam) self.ser.package = package self.ser.writeTypeParameter(foreignTypeParam) outTypeParam = ir.TypeParameter(None, foreignTypeParam.id) self.des.package = package self.des.readTypeParameter(outTypeParam) self.assertEquals(foreignTypeParam, outTypeParam)
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 visitAstClassDefinition(self, node): irClass = self.info.getDefnInfo(node).irDefn if irClass.supertypes is not None: return for param in node.typeParameters: self.visit(param) if node.supertype is None: irClass.supertypes = [ir_t.getRootClassType()] else: supertype = self.visit(node.supertype) if supertype.isNullable(): raise TypeException(node.location, "%s: supertype may not be nullable" % node.name) irClass.supertypes = [supertype] for member in node.members: self.visit(member)
def testExternalizeFunction(self): function = self.otherPackage.addFunction(Name(["f"]), returnType=self.classTy, typeParameters=[], parameterTypes=[None], flags=frozenset([PUBLIC])) T = self.otherPackage.addTypeParameter(function, Name(["f.T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType(), flags=frozenset([STATIC])) TTy = ir_types.VariableType(T) function.parameterTypes[0] = TTy externFunction = externalizeDefn(self.info, function) expected = ir.Function(Name(["f"]), function.id, returnType=self.classTy, typeParameters=[T], parameterTypes=[TTy], flags=frozenset([PUBLIC, EXTERN])) self.assertEquals(expected, externFunction)
def visitAstTypeParameter(self, node): irParam = self.info.getDefnInfo(node).irDefn if irParam.upperBound is not None: return def visitBound(bound, default): if bound is None: return default else: ty = self.visit(bound) if ty.isNullable(): raise TypeException(bound.location, "%s: bound may not be nullable" % node.name) return ty self.scope().define(node.name) irParam.upperBound = visitBound(node.upperBound, ir_t.getRootClassType()) irParam.lowerBound = visitBound(node.lowerBound, ir_t.getNothingClassType()) if not irParam.lowerBound.isSubtypeOf(irParam.upperBound): raise TypeException(node.location, "%s: lower bound is not subtype of upper bound" % node.name)
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 testExternalizeFunction(self): function = self.otherPackage.addFunction(Name(["f"]), returnType=self.classTy, typeParameters=[], parameterTypes=[None], flags=frozenset([PUBLIC])) T = self.otherPackage.addTypeParameter( function, Name(["f.T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType(), flags=frozenset([STATIC])) TTy = ir_types.VariableType(T) function.parameterTypes[0] = TTy externFunction = externalizeDefn(self.info, function) expected = ir.Function(Name(["f"]), function.id, returnType=self.classTy, typeParameters=[T], parameterTypes=[TTy], flags=frozenset([PUBLIC, EXTERN])) self.assertEquals(expected, externFunction)
def testExternalizeTrait(self): trait = self.otherPackage.addTrait(Name(["Tr"]), typeParameters=[], supertypes=[self.rootClassType], methods=[], flags=frozenset([PUBLIC])) T = self.otherPackage.addTypeParameter( trait, Name(["Tr", "T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType()) traitType = ir_types.ClassType.forReceiver(trait) method = self.otherPackage.addFunction(Name(["Tr", "f"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[traitType], flags=frozenset( [PUBLIC, METHOD])) privateMethod = self.otherPackage.addFunction( Name(["Tr", "g"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[traitType], flags=frozenset([PRIVATE, METHOD])) trait.methods = [method, privateMethod] externTrait = externalizeDefn(self.info, trait) expected = ir.Trait(Name(["Tr"]), trait.id, typeParameters=[T], supertypes=[self.rootClassType], flags=frozenset([PUBLIC, EXTERN])) expectedMethod = ir.Function(Name(["Tr", "f"]), method.id, returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[traitType], flags=frozenset([EXTERN, PUBLIC, METHOD])) expected.methods = [expectedMethod] self.assertEquals(expected, externTrait)
def testRewriteExternClassType(self): package = ir.Package(id=ids.TARGET_PACKAGE_ID) depPackage = ir.Package() loader = utils_test.FakePackageLoader([depPackage]) depClass = depPackage.addClass(ir.Name(["C"]), typeParameters=[], supertypes=[ir_types.getRootClassType()], constructors=[], fields=[], methods=[], flags=frozenset([flags.PUBLIC])) externalizer = externalization.Externalizer(package, loader) externClass = externalizer.externalizeDefn(depClass) self.assertIn(flags.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 package.externTypes = [] outType = self.des.readType() self.assertEquals(externClassType, outType) self.assertEquals([externClassType], package.externTypes)
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 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 testInheritFromException(self): source = "class Foo <: Exception" info = self.analyzeFromSource(source) clas = info.package.findClass(name="Foo") self.assertEquals([getExceptionClassType(), getRootClassType()], clas.supertypes)
def testTraitNoSupertypes(self): source = "trait Foo" info = self.analyzeFromSource(source) trait = info.package.findTrait(name="Foo") self.assertEquals([getRootClassType()], trait.supertypes)
def testNoBaseClass(self): source = "class Foo" info = self.analyzeFromSource(source) clas = info.package.findClass(name="Foo") self.assertEquals([getRootClassType()], clas.supertypes)
def testExternalizeClass(self): clas = self.otherPackage.addClass(Name(["C"]), typeParameters=[], supertypes=[self.rootClassType], constructors=[], fields=[], methods=[], elementType=None, flags=frozenset([ARRAY, FINAL, PUBLIC])) T = self.otherPackage.addTypeParameter(clas, Name(["C", "T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType(), flags=frozenset([STATIC])) TTy = ir_types.VariableType(T) clas.elementType = TTy clasTy = ir_types.ClassType.forReceiver(clas) ctor = self.otherPackage.addFunction(Name(["C", CONSTRUCTOR_SUFFIX]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PUBLIC, METHOD, CONSTRUCTOR])) privateCtor = self.otherPackage.addFunction(Name(["C", CONSTRUCTOR_SUFFIX]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PRIVATE, METHOD, CONSTRUCTOR])) clas.constructors = [ctor, privateCtor] field = self.otherPackage.newField(Name(["C", "x"]), type=clasTy, flags=frozenset([PUBLIC])) privateField = self.otherPackage.newField(Name(["C", "y"]), type=clasTy, flags=frozenset([PRIVATE])) clas.fields = [field, privateField] method = self.otherPackage.addFunction(Name(["C", "f"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PUBLIC, METHOD])) privateMethod = self.otherPackage.addFunction(Name(["C", "g"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PRIVATE, METHOD])) builtinMethod = \ builtins.getBuiltinFunctionById(bytecode.BUILTIN_ROOT_CLASS_TO_STRING_ID) clas.methods = [method, privateMethod, builtinMethod] externClass = externalizeDefn(self.info, clas) expected = ir.Class(Name(["C"]), clas.id, typeParameters=[T], supertypes=[self.rootClassType], elementType=TTy, flags=frozenset([ARRAY, FINAL, PUBLIC, EXTERN])) expectedCtor = ir.Function(Name(["C", CONSTRUCTOR_SUFFIX]), ctor.id, returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PUBLIC, METHOD, CONSTRUCTOR, EXTERN])) expected.constructors = [expectedCtor] expectedField = ir.Field(Name(["C", "x"]), type=clasTy, flags=frozenset([PUBLIC])) expected.fields = [expectedField] expectedMethod = ir.Function(Name(["C", "f"]), method.id, returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PUBLIC, METHOD, EXTERN])) externBuiltinMethod = ir.Function(Name(["Object", "to-string"]), builtinMethod.id, returnType=ir_types.getStringType(), typeParameters=[], parameterTypes=[ir_types.getRootClassType()], flags=frozenset([EXTERN, PUBLIC, METHOD])) expected.methods = [expectedMethod, externBuiltinMethod] self.assertEquals(expected, externClass)
def buildFullTypeLists(info, inheritanceGraph): """Builds full `supertypes` lists for each class and trait in the package being compiled. Each class and trait has a `supertypes` list, which contains exactly one type for each definition it inherits from, transitively. The types are ordered by visiting definitions in depth-first pre-order from left to right. This list is used in `Type.isSubtypeOf` among other things. Returns: ({DefnId: [DefnId]}): a list of direct base definitions for each class or trait. Redundant inheritances are removed. For example, if Foo inherits Bar and Baz, but Bar already inherits Baz, the list for Foo will just contain Bar. """ topologicalIds = inheritanceGraph.topologicalSort() bases = {} for id in topologicalIds: if not id.isLocal(): continue irDefn = info.package.getDefn(id) bases[id] = [] # This maps class and trait ids to inherited types. It's possible to inherit a class or # trait through multiple paths (diamond inheritance). This is used to make sure the # types that are inherited are the same along all paths. inheritedTypeMap = {} # This will be the full list of inherited types. Types are added in depth-first # pre-order, but since each base has been processed earlier, we don't need to do a # full graph traversal to build this. inheritedTypes = [] # Check that we don't explicitly inherit the same definition more than once. explicitInheritedIds = set() for supertype in irDefn.supertypes: if supertype.clas.id in explicitInheritedIds: raise InheritanceException.fromDefn( irDefn, "inherited same definition more than once: %s" % supertype.clas.getSourceName()) explicitInheritedIds.add(supertype.clas.id) # Ensure that the first inherited type is from a class. This need not be explicit in # source code. For classes, if the first supertype in source code is a trait, the # real first supertype is the root type. For traits, the real first supertype will be # the first supertype of the first inherited trait. supertypes = [] assert len(irDefn.supertypes) > 0 if isinstance(irDefn.supertypes[0].clas, ir.Trait): if isinstance(irDefn, ir.Class): baseClassType = getRootClassType() else: baseClassType = irDefn.supertypes[0].clas.supertypes[ 0].substitute(irDefn.supertypes[0].clas.typeParameters, irDefn.supertypes[0].typeArguments) supertypes = [baseClassType] + irDefn.supertypes else: baseClassType = irDefn.supertypes[0] supertypes = irDefn.supertypes assert isinstance(baseClassType.clas, ir.Class) # Inherit supertypes. isFirstSupertype = True for supertype in supertypes: irSuperDefn = supertype.clas # Perform some basic checks. if FINAL in irSuperDefn.flags: raise InheritanceException.fromDefn( irDefn, "cannot inherit from final class: %s" % irSuperDefn.getSourceName()) if not isFirstSupertype and isinstance(irSuperDefn, ir.Class): raise InheritanceException.fromDefn( irDefn, "only first supertype may be a class") irSuperClass = irSuperDefn \ if isinstance(irSuperDefn, ir.Class) \ else irSuperDefn.supertypes[0].clas if not baseClassType.clas.isDerivedFrom(irSuperClass): raise InheritanceException.fromDefn( irDefn, "base class %s of supertype %s not a superclass of base class %s" % (irSuperClass.getSourceName(), supertype, baseClassType.clas.getSourceName())) isFirstSupertype = False if irSuperDefn.id in inheritedTypeMap: # We have already inherited this type along a different path. We do not need # to copy bindings. if inheritedTypeMap[irSuperDefn.id] != supertype: raise InheritanceException.fromDefn( irDefn, "inherited %s multiple times with different types" % irSuperDefn.getSourceName()) else: # We have not inherited this type yet. inheritedTypeMap[irSuperDefn.id] = supertype inheritedTypes.append(supertype) bases[id].append(irSuperDefn.id) # Inherit types from the supertype ("ubertypes"). We don't need to do this # recursively we processed the supertype in a previous iteration. Its supertypes # list already contains everything it inherits from. for ubertype in irSuperDefn.supertypes: irUberDefn = ubertype.clas substitutedUbertype = supertype.substituteForBase( irUberDefn) if irUberDefn.id in inheritedTypeMap: # We have already inherited this definition along a different path. if inheritedTypeMap[ irUberDefn.id] != substitutedUbertype: raise InheritanceException.fromDefn( irDefn, "inherited %s multiple times with different types" % irUberDefn.getSourceName()) else: # We have not inherited this definition yet. inheritedTypeMap[irUberDefn.id] = substitutedUbertype inheritedTypes.append(substitutedUbertype) irDefn.supertypes = inheritedTypes return bases
def testExternalizeClass(self): clas = self.otherPackage.addClass(Name(["C"]), typeParameters=[], supertypes=[self.rootClassType], constructors=[], fields=[], methods=[], elementType=None, flags=frozenset( [ARRAY, FINAL, PUBLIC])) T = self.otherPackage.addTypeParameter( clas, Name(["C", "T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType(), flags=frozenset([STATIC])) TTy = ir_types.VariableType(T) clas.elementType = TTy clasTy = ir_types.ClassType.forReceiver(clas) ctor = self.otherPackage.addFunction( Name(["C", CONSTRUCTOR_SUFFIX]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PUBLIC, METHOD, CONSTRUCTOR])) privateCtor = self.otherPackage.addFunction( Name(["C", CONSTRUCTOR_SUFFIX]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PRIVATE, METHOD, CONSTRUCTOR])) clas.constructors = [ctor, privateCtor] field = self.otherPackage.newField(Name(["C", "x"]), type=clasTy, flags=frozenset([PUBLIC])) privateField = self.otherPackage.newField(Name(["C", "y"]), type=clasTy, flags=frozenset([PRIVATE])) clas.fields = [field, privateField] method = self.otherPackage.addFunction(Name(["C", "f"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset( [PUBLIC, METHOD])) privateMethod = self.otherPackage.addFunction( Name(["C", "g"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PRIVATE, METHOD])) builtinMethod = \ builtins.getBuiltinFunctionById(bytecode.BUILTIN_ROOT_CLASS_TO_STRING_ID) clas.methods = [method, privateMethod, builtinMethod] externClass = externalizeDefn(self.info, clas) expected = ir.Class(Name(["C"]), clas.id, typeParameters=[T], supertypes=[self.rootClassType], elementType=TTy, flags=frozenset([ARRAY, FINAL, PUBLIC, EXTERN])) expectedCtor = ir.Function(Name(["C", CONSTRUCTOR_SUFFIX]), ctor.id, returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset( [PUBLIC, METHOD, CONSTRUCTOR, EXTERN])) expected.constructors = [expectedCtor] expectedField = ir.Field(Name(["C", "x"]), type=clasTy, flags=frozenset([PUBLIC])) expected.fields = [expectedField] expectedMethod = ir.Function(Name(["C", "f"]), method.id, returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PUBLIC, METHOD, EXTERN])) externBuiltinMethod = ir.Function( Name(["Object", "to-string"]), builtinMethod.id, returnType=ir_types.getStringType(), typeParameters=[], parameterTypes=[ir_types.getRootClassType()], flags=frozenset([EXTERN, PUBLIC, METHOD])) expected.methods = [expectedMethod, externBuiltinMethod] self.assertEquals(expected, externClass)