зеркало из https://github.com/mozilla/pjs.git
bug 654448 - remove xpt.py's Typelib.merge, move all the logic into xpt_link (also make it a lot faster). r=khuey
This commit is contained in:
Родитель
df74054797
Коммит
ad83523c70
|
@ -378,7 +378,7 @@ class TestInterfaceCmp(unittest.TestCase):
|
||||||
methods=[m])
|
methods=[m])
|
||||||
self.assert_(i2 == i1)
|
self.assert_(i2 == i1)
|
||||||
|
|
||||||
class TestTypelibMerge(unittest.TestCase):
|
class TestXPTLink(unittest.TestCase):
|
||||||
def test_mergeDifferent(self):
|
def test_mergeDifferent(self):
|
||||||
"""
|
"""
|
||||||
Test that merging two typelibs with completely different interfaces
|
Test that merging two typelibs with completely different interfaces
|
||||||
|
@ -391,12 +391,12 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
t2 = xpt.Typelib()
|
t2 = xpt.Typelib()
|
||||||
# add an unresolved interface
|
# add an unresolved interface
|
||||||
t2.interfaces.append(xpt.Interface("IBar"))
|
t2.interfaces.append(xpt.Interface("IBar"))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(2, len(t1.interfaces))
|
self.assertEqual(2, len(t3.interfaces))
|
||||||
# Interfaces should wind up sorted
|
# Interfaces should wind up sorted
|
||||||
self.assertEqual("IBar", t1.interfaces[0].name)
|
self.assertEqual("IBar", t3.interfaces[0].name)
|
||||||
self.assertEqual("IFoo", t1.interfaces[1].name)
|
self.assertEqual("IFoo", t3.interfaces[1].name)
|
||||||
|
|
||||||
# Add some IID values
|
# Add some IID values
|
||||||
t1 = xpt.Typelib()
|
t1 = xpt.Typelib()
|
||||||
|
@ -405,12 +405,12 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
t2 = xpt.Typelib()
|
t2 = xpt.Typelib()
|
||||||
# add an unresolved interface
|
# add an unresolved interface
|
||||||
t2.interfaces.append(xpt.Interface("IBar", iid="44332211-6655-8877-0099-aabbccddeeff"))
|
t2.interfaces.append(xpt.Interface("IBar", iid="44332211-6655-8877-0099-aabbccddeeff"))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(2, len(t1.interfaces))
|
self.assertEqual(2, len(t3.interfaces))
|
||||||
# Interfaces should wind up sorted
|
# Interfaces should wind up sorted
|
||||||
self.assertEqual("IFoo", t1.interfaces[0].name)
|
self.assertEqual("IFoo", t3.interfaces[0].name)
|
||||||
self.assertEqual("IBar", t1.interfaces[1].name)
|
self.assertEqual("IBar", t3.interfaces[1].name)
|
||||||
|
|
||||||
def test_mergeConflict(self):
|
def test_mergeConflict(self):
|
||||||
"""
|
"""
|
||||||
|
@ -425,7 +425,7 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
t2 = xpt.Typelib()
|
t2 = xpt.Typelib()
|
||||||
# add an unresolved interface, same name different IID
|
# add an unresolved interface, same name different IID
|
||||||
t2.interfaces.append(xpt.Interface("IFoo", iid="44332211-6655-8877-0099-aabbccddeeff"))
|
t2.interfaces.append(xpt.Interface("IFoo", iid="44332211-6655-8877-0099-aabbccddeeff"))
|
||||||
self.assertRaises(xpt.DataError, t1.merge, t2)
|
self.assertRaises(xpt.DataError, xpt.xpt_link, [t1, t2])
|
||||||
|
|
||||||
# Same IIDs, different names
|
# Same IIDs, different names
|
||||||
t1 = xpt.Typelib()
|
t1 = xpt.Typelib()
|
||||||
|
@ -434,7 +434,7 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
t2 = xpt.Typelib()
|
t2 = xpt.Typelib()
|
||||||
# add an unresolved interface, same IID different name
|
# add an unresolved interface, same IID different name
|
||||||
t2.interfaces.append(xpt.Interface("IBar", iid="11223344-5566-7788-9900-aabbccddeeff"))
|
t2.interfaces.append(xpt.Interface("IBar", iid="11223344-5566-7788-9900-aabbccddeeff"))
|
||||||
self.assertRaises(xpt.DataError, t1.merge, t2)
|
self.assertRaises(xpt.DataError, xpt.xpt_link, [t1, t2])
|
||||||
|
|
||||||
def test_mergeUnresolvedIID(self):
|
def test_mergeUnresolvedIID(self):
|
||||||
"""
|
"""
|
||||||
|
@ -450,11 +450,11 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
t2 = xpt.Typelib()
|
t2 = xpt.Typelib()
|
||||||
# add an unresolved interface, no IID
|
# add an unresolved interface, no IID
|
||||||
t2.interfaces.append(xpt.Interface("IFoo"))
|
t2.interfaces.append(xpt.Interface("IFoo"))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(1, len(t1.interfaces))
|
self.assertEqual(1, len(t3.interfaces))
|
||||||
self.assertEqual("IFoo", t1.interfaces[0].name)
|
self.assertEqual("IFoo", t3.interfaces[0].name)
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[0].iid)
|
||||||
# Unresolved in both, but t2 has an IID value
|
# Unresolved in both, but t2 has an IID value
|
||||||
t1 = xpt.Typelib()
|
t1 = xpt.Typelib()
|
||||||
# add an unresolved interface, no IID
|
# add an unresolved interface, no IID
|
||||||
|
@ -462,11 +462,11 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
t2 = xpt.Typelib()
|
t2 = xpt.Typelib()
|
||||||
# add an unresolved interface with a valid IID
|
# add an unresolved interface with a valid IID
|
||||||
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
|
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(1, len(t1.interfaces))
|
self.assertEqual(1, len(t3.interfaces))
|
||||||
self.assertEqual("IFoo", t1.interfaces[0].name)
|
self.assertEqual("IFoo", t3.interfaces[0].name)
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[0].iid)
|
||||||
|
|
||||||
def test_mergeResolvedUnresolved(self):
|
def test_mergeResolvedUnresolved(self):
|
||||||
"""
|
"""
|
||||||
|
@ -486,14 +486,14 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
m = xpt.Method("Bar", p)
|
m = xpt.Method("Bar", p)
|
||||||
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
|
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
|
||||||
methods=[m]))
|
methods=[m]))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(1, len(t1.interfaces))
|
self.assertEqual(1, len(t3.interfaces))
|
||||||
self.assertEqual("IFoo", t1.interfaces[0].name)
|
self.assertEqual("IFoo", t3.interfaces[0].name)
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[0].iid)
|
||||||
self.assert_(t1.interfaces[0].resolved)
|
self.assert_(t3.interfaces[0].resolved)
|
||||||
self.assertEqual(1, len(t1.interfaces[0].methods))
|
self.assertEqual(1, len(t3.interfaces[0].methods))
|
||||||
self.assertEqual("Bar", t1.interfaces[0].methods[0].name)
|
self.assertEqual("Bar", t3.interfaces[0].methods[0].name)
|
||||||
|
|
||||||
# t1 has a resolved interface, t2 has an unresolved version
|
# t1 has a resolved interface, t2 has an unresolved version
|
||||||
t1 = xpt.Typelib()
|
t1 = xpt.Typelib()
|
||||||
|
@ -505,14 +505,14 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
t2 = xpt.Typelib()
|
t2 = xpt.Typelib()
|
||||||
# add an unresolved interface
|
# add an unresolved interface
|
||||||
t2.interfaces.append(xpt.Interface("IFoo"))
|
t2.interfaces.append(xpt.Interface("IFoo"))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(1, len(t1.interfaces))
|
self.assertEqual(1, len(t3.interfaces))
|
||||||
self.assertEqual("IFoo", t1.interfaces[0].name)
|
self.assertEqual("IFoo", t3.interfaces[0].name)
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[0].iid)
|
||||||
self.assert_(t1.interfaces[0].resolved)
|
self.assert_(t3.interfaces[0].resolved)
|
||||||
self.assertEqual(1, len(t1.interfaces[0].methods))
|
self.assertEqual(1, len(t3.interfaces[0].methods))
|
||||||
self.assertEqual("Bar", t1.interfaces[0].methods[0].name)
|
self.assertEqual("Bar", t3.interfaces[0].methods[0].name)
|
||||||
|
|
||||||
def test_mergeReplaceParents(self):
|
def test_mergeReplaceParents(self):
|
||||||
"""
|
"""
|
||||||
|
@ -536,17 +536,17 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
m = xpt.Method("Bar", p)
|
m = xpt.Method("Bar", p)
|
||||||
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
|
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
|
||||||
methods=[m]))
|
methods=[m]))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(2, len(t1.interfaces))
|
self.assertEqual(2, len(t3.interfaces))
|
||||||
self.assertEqual("IChild", t1.interfaces[0].name)
|
self.assertEqual("IChild", t3.interfaces[0].name)
|
||||||
self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
|
self.assertEqual("11111111-1111-1111-1111-111111111111", t3.interfaces[0].iid)
|
||||||
self.assertEqual("IFoo", t1.interfaces[1].name)
|
self.assertEqual("IFoo", t3.interfaces[1].name)
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[1].iid)
|
||||||
self.assert_(t1.interfaces[0].resolved)
|
self.assert_(t3.interfaces[0].resolved)
|
||||||
# Ensure that IChild's parent has been updated
|
# Ensure that IChild's parent has been updated
|
||||||
self.assertEqual(t1.interfaces[1], t1.interfaces[0].parent)
|
self.assertEqual(t3.interfaces[1], t3.interfaces[0].parent)
|
||||||
self.assert_(t1.interfaces[0].parent.resolved)
|
self.assert_(t3.interfaces[0].parent.resolved)
|
||||||
|
|
||||||
# t1 has a resolved interface, t2 has an unresolved version,
|
# t1 has a resolved interface, t2 has an unresolved version,
|
||||||
# but t2 also has another interface whose parent is the unresolved
|
# but t2 also has another interface whose parent is the unresolved
|
||||||
|
@ -564,17 +564,17 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
# add a child of the unresolved interface
|
# add a child of the unresolved interface
|
||||||
t2.interfaces.append(xpt.Interface("IChild", iid="11111111-1111-1111-1111-111111111111",
|
t2.interfaces.append(xpt.Interface("IChild", iid="11111111-1111-1111-1111-111111111111",
|
||||||
resolved=True, parent=pi))
|
resolved=True, parent=pi))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(2, len(t1.interfaces))
|
self.assertEqual(2, len(t3.interfaces))
|
||||||
self.assertEqual("IChild", t1.interfaces[0].name)
|
self.assertEqual("IChild", t3.interfaces[0].name)
|
||||||
self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
|
self.assertEqual("11111111-1111-1111-1111-111111111111", t3.interfaces[0].iid)
|
||||||
self.assertEqual("IFoo", t1.interfaces[1].name)
|
self.assertEqual("IFoo", t3.interfaces[1].name)
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[1].iid)
|
||||||
self.assert_(t1.interfaces[0].resolved)
|
self.assert_(t3.interfaces[0].resolved)
|
||||||
# Ensure that IChild's parent has been updated
|
# Ensure that IChild's parent has been updated
|
||||||
self.assertEqual(t1.interfaces[1], t1.interfaces[0].parent)
|
self.assertEqual(t3.interfaces[1], t3.interfaces[0].parent)
|
||||||
self.assert_(t1.interfaces[0].parent.resolved)
|
self.assert_(t3.interfaces[0].parent.resolved)
|
||||||
|
|
||||||
def test_mergeReplaceRetval(self):
|
def test_mergeReplaceRetval(self):
|
||||||
"""
|
"""
|
||||||
|
@ -601,19 +601,19 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
m = xpt.Method("Bar", p)
|
m = xpt.Method("Bar", p)
|
||||||
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
|
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
|
||||||
methods=[m]))
|
methods=[m]))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(2, len(t1.interfaces))
|
self.assertEqual(2, len(t3.interfaces))
|
||||||
self.assertEqual("IRetval", t1.interfaces[0].name)
|
self.assertEqual("IRetval", t3.interfaces[0].name)
|
||||||
self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
|
self.assertEqual("11111111-1111-1111-1111-111111111111", t3.interfaces[0].iid)
|
||||||
self.assertEqual("IFoo", t1.interfaces[1].name)
|
self.assertEqual("IFoo", t3.interfaces[1].name)
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[1].iid)
|
||||||
self.assert_(t1.interfaces[1].resolved)
|
self.assert_(t3.interfaces[1].resolved)
|
||||||
# Ensure that IRetval's method's return value type has been updated.
|
# Ensure that IRetval's method's return value type has been updated.
|
||||||
self.assertEqual(1, len(t1.interfaces[0].methods))
|
self.assertEqual(1, len(t3.interfaces[0].methods))
|
||||||
self.assert_(t1.interfaces[0].methods[0].result.type.iface.resolved)
|
self.assert_(t3.interfaces[0].methods[0].result.type.iface.resolved)
|
||||||
self.assertEqual(t1.interfaces[1],
|
self.assertEqual(t3.interfaces[1],
|
||||||
t1.interfaces[0].methods[0].result.type.iface)
|
t3.interfaces[0].methods[0].result.type.iface)
|
||||||
|
|
||||||
# t1 has a resolved interface. t2 has an unresolved version and
|
# t1 has a resolved interface. t2 has an unresolved version and
|
||||||
# an interface that uses the unresolved interface as a return value
|
# an interface that uses the unresolved interface as a return value
|
||||||
|
@ -634,19 +634,19 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
m = xpt.Method("ReturnIface", p)
|
m = xpt.Method("ReturnIface", p)
|
||||||
t2.interfaces.append(xpt.Interface("IRetval", iid="11111111-1111-1111-1111-111111111111",
|
t2.interfaces.append(xpt.Interface("IRetval", iid="11111111-1111-1111-1111-111111111111",
|
||||||
methods=[m]))
|
methods=[m]))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(2, len(t1.interfaces))
|
self.assertEqual(2, len(t3.interfaces))
|
||||||
self.assertEqual("IRetval", t1.interfaces[0].name)
|
self.assertEqual("IRetval", t3.interfaces[0].name)
|
||||||
self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
|
self.assertEqual("11111111-1111-1111-1111-111111111111", t3.interfaces[0].iid)
|
||||||
self.assertEqual("IFoo", t1.interfaces[1].name)
|
self.assertEqual("IFoo", t3.interfaces[1].name)
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[1].iid)
|
||||||
self.assert_(t1.interfaces[1].resolved)
|
self.assert_(t3.interfaces[1].resolved)
|
||||||
# Ensure that IRetval's method's return value type has been updated.
|
# Ensure that IRetval's method's return value type has been updated.
|
||||||
self.assertEqual(1, len(t1.interfaces[0].methods))
|
self.assertEqual(1, len(t3.interfaces[0].methods))
|
||||||
self.assert_(t1.interfaces[0].methods[0].result.type.iface.resolved)
|
self.assert_(t3.interfaces[0].methods[0].result.type.iface.resolved)
|
||||||
self.assertEqual(t1.interfaces[1],
|
self.assertEqual(t3.interfaces[1],
|
||||||
t1.interfaces[0].methods[0].result.type.iface)
|
t3.interfaces[0].methods[0].result.type.iface)
|
||||||
|
|
||||||
def test_mergeReplaceParams(self):
|
def test_mergeReplaceParams(self):
|
||||||
"""
|
"""
|
||||||
|
@ -673,19 +673,19 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
m = xpt.Method("Bar", vp)
|
m = xpt.Method("Bar", vp)
|
||||||
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
|
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
|
||||||
methods=[m]))
|
methods=[m]))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(2, len(t1.interfaces))
|
self.assertEqual(2, len(t3.interfaces))
|
||||||
self.assertEqual("IParam", t1.interfaces[0].name)
|
self.assertEqual("IParam", t3.interfaces[0].name)
|
||||||
self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
|
self.assertEqual("11111111-1111-1111-1111-111111111111", t3.interfaces[0].iid)
|
||||||
self.assertEqual("IFoo", t1.interfaces[1].name)
|
self.assertEqual("IFoo", t3.interfaces[1].name)
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[1].iid)
|
||||||
self.assert_(t1.interfaces[1].resolved)
|
self.assert_(t3.interfaces[1].resolved)
|
||||||
# Ensure that IRetval's method's param type has been updated.
|
# Ensure that IRetval's method's param type has been updated.
|
||||||
self.assertEqual(1, len(t1.interfaces[0].methods))
|
self.assertEqual(1, len(t3.interfaces[0].methods))
|
||||||
self.assert_(t1.interfaces[0].methods[0].params[0].type.iface.resolved)
|
self.assert_(t3.interfaces[0].methods[0].params[0].type.iface.resolved)
|
||||||
self.assertEqual(t1.interfaces[1],
|
self.assertEqual(t3.interfaces[1],
|
||||||
t1.interfaces[0].methods[0].params[0].type.iface)
|
t3.interfaces[0].methods[0].params[0].type.iface)
|
||||||
|
|
||||||
# t1 has a resolved interface. t2 has an unresolved version
|
# t1 has a resolved interface. t2 has an unresolved version
|
||||||
# and an interface that uses the unresolved interface as a
|
# and an interface that uses the unresolved interface as a
|
||||||
|
@ -706,19 +706,19 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
m = xpt.Method("IfaceParam", vp, params=[p])
|
m = xpt.Method("IfaceParam", vp, params=[p])
|
||||||
t2.interfaces.append(xpt.Interface("IParam", iid="11111111-1111-1111-1111-111111111111",
|
t2.interfaces.append(xpt.Interface("IParam", iid="11111111-1111-1111-1111-111111111111",
|
||||||
methods=[m]))
|
methods=[m]))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(2, len(t1.interfaces))
|
self.assertEqual(2, len(t3.interfaces))
|
||||||
self.assertEqual("IParam", t1.interfaces[0].name)
|
self.assertEqual("IParam", t3.interfaces[0].name)
|
||||||
self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
|
self.assertEqual("11111111-1111-1111-1111-111111111111", t3.interfaces[0].iid)
|
||||||
self.assertEqual("IFoo", t1.interfaces[1].name)
|
self.assertEqual("IFoo", t3.interfaces[1].name)
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[1].iid)
|
||||||
self.assert_(t1.interfaces[1].resolved)
|
self.assert_(t3.interfaces[1].resolved)
|
||||||
# Ensure that IRetval's method's param type has been updated.
|
# Ensure that IRetval's method's param type has been updated.
|
||||||
self.assertEqual(1, len(t1.interfaces[0].methods))
|
self.assertEqual(1, len(t3.interfaces[0].methods))
|
||||||
self.assert_(t1.interfaces[0].methods[0].params[0].type.iface.resolved)
|
self.assert_(t3.interfaces[0].methods[0].params[0].type.iface.resolved)
|
||||||
self.assertEqual(t1.interfaces[1],
|
self.assertEqual(t3.interfaces[1],
|
||||||
t1.interfaces[0].methods[0].params[0].type.iface)
|
t3.interfaces[0].methods[0].params[0].type.iface)
|
||||||
|
|
||||||
|
|
||||||
def test_mergeReplaceArrayTypeParams(self):
|
def test_mergeReplaceArrayTypeParams(self):
|
||||||
|
@ -748,74 +748,19 @@ class TestTypelibMerge(unittest.TestCase):
|
||||||
m = xpt.Method("Bar", vp)
|
m = xpt.Method("Bar", vp)
|
||||||
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
|
t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
|
||||||
methods=[m]))
|
methods=[m]))
|
||||||
t1.merge(t2)
|
t3 = xpt.xpt_link([t1, t2])
|
||||||
|
|
||||||
self.assertEqual(2, len(t1.interfaces))
|
|
||||||
self.assertEqual("IParam", t1.interfaces[0].name)
|
|
||||||
self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
|
|
||||||
self.assertEqual("IFoo", t1.interfaces[1].name)
|
|
||||||
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
|
|
||||||
self.assert_(t1.interfaces[1].resolved)
|
|
||||||
# Ensure that IRetval's method's param type has been updated.
|
|
||||||
self.assertEqual(1, len(t1.interfaces[0].methods))
|
|
||||||
self.assert_(t1.interfaces[0].methods[0].params[0].type.element_type.iface.resolved)
|
|
||||||
self.assertEqual(t1.interfaces[1],
|
|
||||||
t1.interfaces[0].methods[0].params[0].type.element_type.iface)
|
|
||||||
|
|
||||||
class TestXPTLink(unittest.TestCase):
|
|
||||||
def test_xpt_link(self):
|
|
||||||
"""
|
|
||||||
Test the xpt_link method.
|
|
||||||
|
|
||||||
"""
|
|
||||||
t1 = xpt.Typelib()
|
|
||||||
# add an unresolved interface
|
|
||||||
t1.interfaces.append(xpt.Interface("IFoo"))
|
|
||||||
f1 = StringIO()
|
|
||||||
t1.write(f1)
|
|
||||||
f1.seek(0)
|
|
||||||
|
|
||||||
t2 = xpt.Typelib()
|
|
||||||
# add an unresolved interface
|
|
||||||
t2.interfaces.append(xpt.Interface("IBar"))
|
|
||||||
f2 = StringIO()
|
|
||||||
t2.write(f2)
|
|
||||||
f2.seek(0)
|
|
||||||
|
|
||||||
f3 = StringIO()
|
|
||||||
xpt.xpt_link(f3, [f1, f2])
|
|
||||||
f3.seek(0)
|
|
||||||
t3 = xpt.Typelib.read(f3)
|
|
||||||
|
|
||||||
self.assertEqual(2, len(t3.interfaces))
|
self.assertEqual(2, len(t3.interfaces))
|
||||||
# Interfaces should wind up sorted
|
self.assertEqual("IParam", t3.interfaces[0].name)
|
||||||
self.assertEqual("IBar", t3.interfaces[0].name)
|
self.assertEqual("11111111-1111-1111-1111-111111111111", t3.interfaces[0].iid)
|
||||||
self.assertEqual("IFoo", t3.interfaces[1].name)
|
self.assertEqual("IFoo", t3.interfaces[1].name)
|
||||||
|
self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t3.interfaces[1].iid)
|
||||||
# Add some IID values
|
self.assert_(t3.interfaces[1].resolved)
|
||||||
t1 = xpt.Typelib()
|
# Ensure that IRetval's method's param type has been updated.
|
||||||
# add an unresolved interface
|
self.assertEqual(1, len(t3.interfaces[0].methods))
|
||||||
t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
|
self.assert_(t3.interfaces[0].methods[0].params[0].type.element_type.iface.resolved)
|
||||||
f1 = StringIO()
|
self.assertEqual(t3.interfaces[1],
|
||||||
t1.write(f1)
|
t3.interfaces[0].methods[0].params[0].type.element_type.iface)
|
||||||
f1.seek(0)
|
|
||||||
|
|
||||||
t2 = xpt.Typelib()
|
|
||||||
# add an unresolved interface
|
|
||||||
t2.interfaces.append(xpt.Interface("IBar", iid="44332211-6655-8877-0099-aabbccddeeff"))
|
|
||||||
f2 = StringIO()
|
|
||||||
t2.write(f2)
|
|
||||||
f2.seek(0)
|
|
||||||
|
|
||||||
f3 = StringIO()
|
|
||||||
xpt.xpt_link(f3, [f1, f2])
|
|
||||||
f3.seek(0)
|
|
||||||
t3 = xpt.Typelib.read(f3)
|
|
||||||
|
|
||||||
self.assertEqual(2, len(t3.interfaces))
|
|
||||||
# Interfaces should wind up sorted
|
|
||||||
self.assertEqual("IFoo", t3.interfaces[0].name)
|
|
||||||
self.assertEqual("IBar", t3.interfaces[1].name)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -68,6 +68,7 @@ InterfaceType() - construct a new object representing a type that
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
import os, sys
|
import os, sys
|
||||||
import struct
|
import struct
|
||||||
|
import operator
|
||||||
|
|
||||||
# header magic
|
# header magic
|
||||||
XPT_MAGIC = "XPCOM\nTypeLib\r\n\x1a"
|
XPT_MAGIC = "XPCOM\nTypeLib\r\n\x1a"
|
||||||
|
@ -878,6 +879,9 @@ class Interface(object):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Interface(name='%s', iid='%s')" % (self.name, self.iid)
|
return "Interface(name='%s', iid='%s')" % (self.name, self.iid)
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash((self.name, self.iid))
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
c = cmp(self.iid, other.iid)
|
c = cmp(self.iid, other.iid)
|
||||||
if c != 0:
|
if c != 0:
|
||||||
|
@ -1186,94 +1190,6 @@ class Typelib(object):
|
||||||
else:
|
else:
|
||||||
self.writefd(output_file)
|
self.writefd(output_file)
|
||||||
|
|
||||||
def merge(self, other, sanitycheck=True):
|
|
||||||
"""
|
|
||||||
Merge the contents of Typelib |other| into this typelib.
|
|
||||||
If |sanitycheck| is False, don't sort the interface table
|
|
||||||
after merging.
|
|
||||||
|
|
||||||
"""
|
|
||||||
# This will be a list of (replaced interface, replaced with)
|
|
||||||
# containing interfaces that were replaced with interfaces from
|
|
||||||
# another typelib, and the interface that replaced them.
|
|
||||||
merged_interfaces = []
|
|
||||||
for i in other.interfaces:
|
|
||||||
if i in self.interfaces:
|
|
||||||
continue
|
|
||||||
# See if there's a copy of this interface with different
|
|
||||||
# resolved status or IID value.
|
|
||||||
merged = False
|
|
||||||
for j in self.interfaces:
|
|
||||||
if i.name == j.name:
|
|
||||||
if i.resolved != j.resolved:
|
|
||||||
# prefer resolved interfaces over unresolved
|
|
||||||
if j.resolved:
|
|
||||||
# keep j
|
|
||||||
merged_interfaces.append((i, j))
|
|
||||||
merged = True
|
|
||||||
# Fixup will happen after processing all interfaces.
|
|
||||||
else:
|
|
||||||
# replace j with i
|
|
||||||
merged_interfaces.append((j, i))
|
|
||||||
merged = True
|
|
||||||
self.interfaces[self.interfaces.index(j)] = i
|
|
||||||
elif i.iid != j.iid:
|
|
||||||
# Prefer unresolved interfaces with valid IIDs
|
|
||||||
if j.iid == Interface.UNRESOLVED_IID:
|
|
||||||
# replace j with i
|
|
||||||
merged_interfaces.append((j, i))
|
|
||||||
merged = True
|
|
||||||
self.interfaces[self.interfaces.index(j)] = i
|
|
||||||
elif i.iid == Interface.UNRESOLVED_IID:
|
|
||||||
# keep j
|
|
||||||
merged_interfaces.append((i, j))
|
|
||||||
merged = True
|
|
||||||
# Fixup will happen after processing all interfaces.
|
|
||||||
else:
|
|
||||||
# Same name but different IIDs: raise an exception.
|
|
||||||
# self.* is the (target) Typelib being merged into,
|
|
||||||
# not the one which j.iid was from.
|
|
||||||
raise DataError, \
|
|
||||||
"Typelibs contain definitions of interface %s" \
|
|
||||||
" with different IIDs (%s (%s) vs %s (%s))!" % \
|
|
||||||
(i.name, i.iid, i.xpt_filename or other.filename, \
|
|
||||||
j.iid, j.xpt_filename or self.filename)
|
|
||||||
elif i.iid == j.iid and i.iid != Interface.UNRESOLVED_IID:
|
|
||||||
# Same IID but different names: raise an exception.
|
|
||||||
# self.* is the (target) Typelib being merged into,
|
|
||||||
# not the one which j.name was from.
|
|
||||||
raise DataError, \
|
|
||||||
"Typelibs contain definitions of interface %s" \
|
|
||||||
" with different names (%s (%s) vs %s (%s))!" % \
|
|
||||||
(i.iid, i.name, i.xpt_filename or other.filename, \
|
|
||||||
j.name, j.xpt_filename or self.filename)
|
|
||||||
if not merged:
|
|
||||||
# No partially matching interfaces, so just take this interface
|
|
||||||
self.interfaces.append(i)
|
|
||||||
|
|
||||||
# Now fixup any merged interfaces
|
|
||||||
def checkType(t, replaced_from, replaced_to):
|
|
||||||
if isinstance(t, InterfaceType) and t.iface == replaced_from:
|
|
||||||
t.iface = replaced_to
|
|
||||||
elif isinstance(t, ArrayType) and \
|
|
||||||
isinstance(t.element_type, InterfaceType) and \
|
|
||||||
t.element_type.iface == replaced_from:
|
|
||||||
t.element_type.iface = replaced_to
|
|
||||||
|
|
||||||
for replaced_from, replaced_to in merged_interfaces:
|
|
||||||
for i in self.interfaces:
|
|
||||||
# Replace parent references
|
|
||||||
if i.parent is not None and i.parent == replaced_from:
|
|
||||||
i.parent = replaced_to
|
|
||||||
for m in i.methods:
|
|
||||||
# Replace InterfaceType params and return values
|
|
||||||
checkType(m.result.type, replaced_from, replaced_to)
|
|
||||||
for p in m.params:
|
|
||||||
checkType(p.type, replaced_from, replaced_to)
|
|
||||||
if sanitycheck:
|
|
||||||
self._sanityCheck()
|
|
||||||
#TODO: do we care about annotations? probably not
|
|
||||||
|
|
||||||
def dump(self, out):
|
def dump(self, out):
|
||||||
"""
|
"""
|
||||||
Print a human-readable listing of the contents of this typelib
|
Print a human-readable listing of the contents of this typelib
|
||||||
|
@ -1335,21 +1251,126 @@ def xpt_dump(file):
|
||||||
t = Typelib.read(file)
|
t = Typelib.read(file)
|
||||||
t.dump(sys.stdout)
|
t.dump(sys.stdout)
|
||||||
|
|
||||||
def xpt_link(dest, inputs):
|
def xpt_link(inputs):
|
||||||
"""
|
"""
|
||||||
Link all of the xpt files in |inputs| together and write the
|
Link all of the xpt files in |inputs| together and return the result
|
||||||
result to |dest|. All parameters may be filenames or file-like objects.
|
as a Typelib object. All entries in inputs may be filenames or
|
||||||
|
file-like objects.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
def read_input(i):
|
||||||
|
if isinstance(i, Typelib):
|
||||||
|
return i
|
||||||
|
return Typelib.read(i)
|
||||||
|
|
||||||
if not inputs:
|
if not inputs:
|
||||||
print >>sys.stderr, "Usage: xpt_link <destination file> <input files>"
|
print >>sys.stderr, "Usage: xpt_link <destination file> <input files>"
|
||||||
return
|
return None
|
||||||
t1 = Typelib.read(inputs[0])
|
# This is the aggregate list of interfaces.
|
||||||
for f in inputs[1:]:
|
interfaces = []
|
||||||
t2 = Typelib.read(f)
|
# This will be a dict of replaced interface -> replaced with
|
||||||
# write will call sanitycheck, so skip it here.
|
# containing interfaces that were replaced with interfaces from
|
||||||
t1.merge(t2, sanitycheck=False)
|
# another typelib, and the interface that replaced them.
|
||||||
t1.write(dest)
|
merged_interfaces = {}
|
||||||
|
for f in inputs:
|
||||||
|
t = read_input(f)
|
||||||
|
interfaces.extend(t.interfaces)
|
||||||
|
# Sort interfaces by name so we can merge adjacent duplicates
|
||||||
|
interfaces.sort(key=operator.attrgetter('name'))
|
||||||
|
|
||||||
|
Result = enum('Equal', # Interfaces the same, doesn't matter
|
||||||
|
'NotEqual', # Interfaces differ, keep both
|
||||||
|
'KeepFirst', # Replace second interface with first
|
||||||
|
'KeepSecond')# Replace first interface with second
|
||||||
|
|
||||||
|
def compare(i, j):
|
||||||
|
"""
|
||||||
|
Compare two interfaces, determine if they're equal or
|
||||||
|
completely different, or should be merged (and indicate which
|
||||||
|
one to keep in that case).
|
||||||
|
|
||||||
|
"""
|
||||||
|
if i == j:
|
||||||
|
# Arbitrary, just pick one
|
||||||
|
return Result.Equal
|
||||||
|
if i.name != j.name:
|
||||||
|
if i.iid == j.iid and i.iid != Interface.UNRESOLVED_IID:
|
||||||
|
# Same IID but different names: raise an exception.
|
||||||
|
raise DataError, \
|
||||||
|
"Typelibs contain definitions of interface %s" \
|
||||||
|
" with different names (%s (%s) vs %s (%s))!" % \
|
||||||
|
(i.iid, i.name, i.xpt_filename, j.name, j.xpt_filename)
|
||||||
|
# Otherwise just different interfaces.
|
||||||
|
return Result.NotEqual
|
||||||
|
# Interfaces have the same name, so either they need to be merged
|
||||||
|
# or there's a data error. Sort out which one to keep
|
||||||
|
if i.resolved != j.resolved:
|
||||||
|
# prefer resolved interfaces over unresolved
|
||||||
|
if j.resolved:
|
||||||
|
assert i.iid == j.iid or i.iid == Interface.UNRESOLVED_IID
|
||||||
|
# keep j
|
||||||
|
return Result.KeepSecond
|
||||||
|
else:
|
||||||
|
assert i.iid == j.iid or j.iid == Interface.UNRESOLVED_IID
|
||||||
|
# replace j with i
|
||||||
|
return Result.KeepFirst
|
||||||
|
elif i.iid != j.iid:
|
||||||
|
# Prefer unresolved interfaces with valid IIDs
|
||||||
|
if j.iid == Interface.UNRESOLVED_IID:
|
||||||
|
# replace j with i
|
||||||
|
assert not j.resolved
|
||||||
|
return Result.KeepFirst
|
||||||
|
elif i.iid == Interface.UNRESOLVED_IID:
|
||||||
|
# keep j
|
||||||
|
assert not i.resolved
|
||||||
|
return Result.KeepSecond
|
||||||
|
else:
|
||||||
|
# Same name but different IIDs: raise an exception.
|
||||||
|
raise DataError, \
|
||||||
|
"Typelibs contain definitions of interface %s" \
|
||||||
|
" with different IIDs (%s (%s) vs %s (%s))!" % \
|
||||||
|
(i.name, i.iid, i.xpt_filename, \
|
||||||
|
j.iid, j.xpt_filename)
|
||||||
|
raise DataError, "No idea what happened here: %s:%s (%s), %s:%s (%s)" % \
|
||||||
|
(i.name, i.iid, i.xpt_filename, j.name, j.iid, j.xpt_filename)
|
||||||
|
|
||||||
|
# Compare interfaces pairwise to find duplicates that should be merged.
|
||||||
|
i = 1
|
||||||
|
while i < len(interfaces):
|
||||||
|
res = compare(interfaces[i-1], interfaces[i])
|
||||||
|
if res == Result.NotEqual:
|
||||||
|
i += 1
|
||||||
|
elif res == Result.Equal:
|
||||||
|
# Need to drop one but it doesn't matter which
|
||||||
|
del interfaces[i]
|
||||||
|
elif res == Result.KeepFirst:
|
||||||
|
merged_interfaces[interfaces[i]] = interfaces[i-1]
|
||||||
|
del interfaces[i]
|
||||||
|
elif res == Result.KeepSecond:
|
||||||
|
merged_interfaces[interfaces[i-1]] = interfaces[i]
|
||||||
|
del interfaces[i-1]
|
||||||
|
|
||||||
|
# Now fixup any merged interfaces
|
||||||
|
def checkType(t):
|
||||||
|
if isinstance(t, InterfaceType) and t.iface in merged_interfaces:
|
||||||
|
t.iface = merged_interfaces[t.iface]
|
||||||
|
elif isinstance(t, ArrayType) and \
|
||||||
|
isinstance(t.element_type, InterfaceType) and \
|
||||||
|
t.element_type.iface in merged_interfaces:
|
||||||
|
t.element_type.iface = merged_interfaces[t.element_type.iface]
|
||||||
|
|
||||||
|
for i in interfaces:
|
||||||
|
# Replace parent references
|
||||||
|
if i.parent in merged_interfaces:
|
||||||
|
i.parent = merged_interfaces[i.parent]
|
||||||
|
for m in i.methods:
|
||||||
|
# Replace InterfaceType params and return values
|
||||||
|
checkType(m.result.type)
|
||||||
|
for p in m.params:
|
||||||
|
checkType(p.type)
|
||||||
|
# Re-sort interfaces (by IID)
|
||||||
|
interfaces.sort()
|
||||||
|
return Typelib(interfaces=interfaces)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if len(sys.argv) < 3:
|
if len(sys.argv) < 3:
|
||||||
|
@ -1358,4 +1379,5 @@ if __name__ == '__main__':
|
||||||
if sys.argv[1] == 'dump':
|
if sys.argv[1] == 'dump':
|
||||||
xpt_dump(sys.argv[2])
|
xpt_dump(sys.argv[2])
|
||||||
elif sys.argv[1] == 'link':
|
elif sys.argv[1] == 'link':
|
||||||
xpt_link(sys.argv[2], sys.argv[3:])
|
xpt_link(sys.argv[3:]).write(sys.argv[2])
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче