From 38246c449e653f9bdc8651b5a47aae52b931a2c3 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 3 Apr 2013 22:22:15 -0400 Subject: [PATCH] Bug 852219 part 1. Don't mark JS-implemented interfaces with descendant interfaces as final. r=khuey,mccr8 --- dom/bindings/Codegen.py | 23 ++++++++++++++++++----- dom/bindings/parser/WebIDL.py | 6 ++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 7acd957a872a..7a07e33a7d62 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -5546,7 +5546,7 @@ ${className}::${className}(${args})${initializationList} class ClassDestructor(ClassItem): """ - Used for adding a constructor to a CGClass. + Used for adding a destructor to a CGClass. inline should be True if the destructor should be marked inline. @@ -5556,17 +5556,22 @@ class ClassDestructor(ClassItem): visibility determines the visibility of the destructor (public, protected, private), defaults to private. - body contains a string with the code for the destructor, defaults to None. + body contains a string with the code for the destructor, defaults to empty. + + virtual determines whether the destructor is virtual, defaults to False. """ def __init__(self, inline=False, bodyInHeader=False, - visibility="private", body=None): + visibility="private", body='', virtual=False): self.inline = inline or bodyInHeader self.bodyInHeader = bodyInHeader self.body = body + self.virtual = virtual ClassItem.__init__(self, None, visibility) def getDecorators(self, declaring): decorators = [] + if self.virtual and declaring: + decorators.append('virtual') if self.inline and declaring: decorators.append('inline') if decorators: @@ -5574,7 +5579,6 @@ class ClassDestructor(ClassItem): return '' def getBody(self): - assert self.body is not None return self.body def declare(self, cgClass): @@ -8105,6 +8109,14 @@ class CGJSImplClass(CGBindingImplClass): " NS_INTERFACE_MAP_ENTRY(nsISupports)\n" "NS_INTERFACE_MAP_END\n").substitute({ "ifaceName": self.descriptor.name }) + if descriptor.interface.hasChildInterfaces(): + decorators = "" + # We need a public virtual destructor our subclasses can use + destructor = ClassDestructor(virtual=True, visibility="public") + else: + decorators = "MOZ_FINAL" + destructor = None + CGClass.__init__(self, descriptor.name, bases=[ClassBase("nsISupports"), ClassBase("nsWrapperCache")], @@ -8114,8 +8126,9 @@ class CGJSImplClass(CGBindingImplClass): baseConstructors=["mImpl(aImpl)", "mParent(aParent)"], body="SetIsDOMBinding();")], + destructor=destructor, methods=self.methodDecls, - decorators="MOZ_FINAL", + decorators=decorators, extradeclarations=extradeclarations, extradefinitions=extradefinitions) diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 0e2177749630..c307116ab98c 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -506,6 +506,7 @@ class IDLInterface(IDLObjectWithScope): # self.interfacesImplementingSelf is the set of interfaces that directly # have self as a consequential interface self.interfacesImplementingSelf = set() + self._hasChildInterfaces = False IDLObjectWithScope.__init__(self, location, parentScope, name) @@ -567,6 +568,8 @@ class IDLInterface(IDLObjectWithScope): if self.parent: self.parent.finish(scope) + self.parent._hasChildInterfaces = True + # Callbacks must not inherit from non-callbacks or inherit from # anything that has consequential interfaces. # XXXbz Can non-callbacks inherit from callbacks? Spec issue pending. @@ -977,6 +980,9 @@ class IDLInterface(IDLObjectWithScope): def isJSImplemented(self): return bool(self.getJSImplementation()) + def hasChildInterfaces(self): + return self._hasChildInterfaces + def _getDependentObjects(self): deps = set(self.members) deps.union(self.implementedInterfaces)