Browse Source

refactor: declare gin::Wrapper subclasses as final (#43565)

As per the gin docs: "Wrappable<T> explicitly does not support further
subclassing of T. Subclasses of Wrappable<T> should be declared final."

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <[email protected]>
trop[bot] 7 months ago
parent
commit
e92eb210bb
35 changed files with 106 additions and 103 deletions
  1. 6 6
      shell/browser/api/electron_api_app.h
  2. 4 4
      shell/browser/api/electron_api_auto_updater.h
  3. 2 2
      shell/browser/api/electron_api_cookies.h
  4. 1 1
      shell/browser/api/electron_api_data_pipe_holder.h
  5. 4 4
      shell/browser/api/electron_api_debugger.h
  6. 3 3
      shell/browser/api/electron_api_desktop_capturer.h
  7. 4 4
      shell/browser/api/electron_api_download_item.h
  8. 3 2
      shell/browser/api/electron_api_global_shortcut.h
  9. 3 3
      shell/browser/api/electron_api_in_app_purchase.h
  10. 3 3
      shell/browser/api/electron_api_native_theme.h
  11. 1 1
      shell/browser/api/electron_api_net_log.h
  12. 5 5
      shell/browser/api/electron_api_notification.h
  13. 6 6
      shell/browser/api/electron_api_power_monitor.h
  14. 1 1
      shell/browser/api/electron_api_power_save_blocker.h
  15. 2 2
      shell/browser/api/electron_api_protocol.h
  16. 1 1
      shell/browser/api/electron_api_push_notifications.h
  17. 3 3
      shell/browser/api/electron_api_screen.h
  18. 1 1
      shell/browser/api/electron_api_service_worker_context.h
  19. 8 8
      shell/browser/api/electron_api_session.h
  20. 1 1
      shell/browser/api/electron_api_system_preferences.h
  21. 6 6
      shell/browser/api/electron_api_tray.h
  22. 1 1
      shell/browser/api/electron_api_utility_process.h
  23. 1 1
      shell/browser/api/electron_api_web_contents.cc
  24. 13 13
      shell/browser/api/electron_api_web_contents.h
  25. 4 4
      shell/browser/api/electron_api_web_frame_main.h
  26. 2 1
      shell/browser/api/electron_api_web_request.h
  27. 3 3
      shell/browser/api/message_port.h
  28. 1 1
      shell/common/api/electron_api_native_image.h
  29. 3 2
      shell/common/api/electron_api_url_loader.cc
  30. 1 1
      shell/common/api/electron_api_url_loader.h
  31. 1 1
      shell/common/gin_converters/net_converter.cc
  32. 2 2
      shell/common/gin_helper/event.h
  33. 2 2
      shell/renderer/api/electron_api_ipc_renderer.cc
  34. 2 2
      shell/renderer/api/electron_api_web_frame.cc
  35. 2 2
      shell/services/node/parent_port.h

+ 6 - 6
shell/browser/api/electron_api_app.h

@@ -57,12 +57,12 @@ enum class JumpListResult : int;
 
 namespace api {
 
-class App : public ElectronBrowserClient::Delegate,
-            public gin::Wrappable<App>,
-            public gin_helper::EventEmitterMixin<App>,
-            private BrowserObserver,
-            private content::GpuDataManagerObserver,
-            private content::BrowserChildProcessObserver {
+class App final : public ElectronBrowserClient::Delegate,
+                  public gin::Wrappable<App>,
+                  public gin_helper::EventEmitterMixin<App>,
+                  private BrowserObserver,
+                  private content::GpuDataManagerObserver,
+                  private content::BrowserChildProcessObserver {
  public:
   using FileIconCallback =
       base::RepeatingCallback<void(v8::Local<v8::Value>, const gfx::Image&)>;

+ 4 - 4
shell/browser/api/electron_api_auto_updater.h

@@ -19,10 +19,10 @@ class Handle;
 
 namespace electron::api {
 
-class AutoUpdater : public gin::Wrappable<AutoUpdater>,
-                    public gin_helper::EventEmitterMixin<AutoUpdater>,
-                    public auto_updater::Delegate,
-                    private WindowListObserver {
+class AutoUpdater final : public gin::Wrappable<AutoUpdater>,
+                          public gin_helper::EventEmitterMixin<AutoUpdater>,
+                          public auto_updater::Delegate,
+                          private WindowListObserver {
  public:
   static gin::Handle<AutoUpdater> Create(v8::Isolate* isolate);
 

+ 2 - 2
shell/browser/api/electron_api_cookies.h

@@ -31,8 +31,8 @@ class ElectronBrowserContext;
 
 namespace api {
 
-class Cookies : public gin::Wrappable<Cookies>,
-                public gin_helper::EventEmitterMixin<Cookies> {
+class Cookies final : public gin::Wrappable<Cookies>,
+                      public gin_helper::EventEmitterMixin<Cookies> {
  public:
   static gin::Handle<Cookies> Create(v8::Isolate* isolate,
                                      ElectronBrowserContext* browser_context);

+ 1 - 1
shell/browser/api/electron_api_data_pipe_holder.h

@@ -20,7 +20,7 @@ class Handle;
 namespace electron::api {
 
 // Retains reference to the data pipe.
-class DataPipeHolder : public gin::Wrappable<DataPipeHolder> {
+class DataPipeHolder final : public gin::Wrappable<DataPipeHolder> {
  public:
   // gin::Wrappable
   static gin::WrapperInfo kWrapperInfo;

+ 4 - 4
shell/browser/api/electron_api_debugger.h

@@ -32,10 +32,10 @@ class Promise;
 
 namespace electron::api {
 
-class Debugger : public gin::Wrappable<Debugger>,
-                 public gin_helper::EventEmitterMixin<Debugger>,
-                 public content::DevToolsAgentHostClient,
-                 private content::WebContentsObserver {
+class Debugger final : public gin::Wrappable<Debugger>,
+                       public gin_helper::EventEmitterMixin<Debugger>,
+                       public content::DevToolsAgentHostClient,
+                       private content::WebContentsObserver {
  public:
   static gin::Handle<Debugger> Create(v8::Isolate* isolate,
                                       content::WebContents* web_contents);

+ 3 - 3
shell/browser/api/electron_api_desktop_capturer.h

@@ -21,9 +21,9 @@ class Handle;
 
 namespace electron::api {
 
-class DesktopCapturer : public gin::Wrappable<DesktopCapturer>,
-                        public gin_helper::Pinnable<DesktopCapturer>,
-                        private DesktopMediaListObserver {
+class DesktopCapturer final : public gin::Wrappable<DesktopCapturer>,
+                              public gin_helper::Pinnable<DesktopCapturer>,
+                              private DesktopMediaListObserver {
  public:
   struct Source {
     DesktopMediaList::Source media_list_source;

+ 4 - 4
shell/browser/api/electron_api_download_item.h

@@ -25,10 +25,10 @@ class Handle;
 
 namespace electron::api {
 
-class DownloadItem : public gin::Wrappable<DownloadItem>,
-                     public gin_helper::Pinnable<DownloadItem>,
-                     public gin_helper::EventEmitterMixin<DownloadItem>,
-                     private download::DownloadItem::Observer {
+class DownloadItem final : public gin::Wrappable<DownloadItem>,
+                           public gin_helper::Pinnable<DownloadItem>,
+                           public gin_helper::EventEmitterMixin<DownloadItem>,
+                           private download::DownloadItem::Observer {
  public:
   static gin::Handle<DownloadItem> FromOrCreate(v8::Isolate* isolate,
                                                 download::DownloadItem* item);

+ 3 - 2
shell/browser/api/electron_api_global_shortcut.h

@@ -20,8 +20,9 @@ class Handle;
 
 namespace electron::api {
 
-class GlobalShortcut : private extensions::GlobalShortcutListener::Observer,
-                       public gin::Wrappable<GlobalShortcut> {
+class GlobalShortcut final
+    : private extensions::GlobalShortcutListener::Observer,
+      public gin::Wrappable<GlobalShortcut> {
  public:
   static gin::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
 

+ 3 - 3
shell/browser/api/electron_api_in_app_purchase.h

@@ -22,9 +22,9 @@ class Handle;
 
 namespace electron::api {
 
-class InAppPurchase : public gin::Wrappable<InAppPurchase>,
-                      public gin_helper::EventEmitterMixin<InAppPurchase>,
-                      private in_app_purchase::TransactionObserver {
+class InAppPurchase final : public gin::Wrappable<InAppPurchase>,
+                            public gin_helper::EventEmitterMixin<InAppPurchase>,
+                            private in_app_purchase::TransactionObserver {
  public:
   static gin::Handle<InAppPurchase> Create(v8::Isolate* isolate);
 

+ 3 - 3
shell/browser/api/electron_api_native_theme.h

@@ -18,9 +18,9 @@ class handle;
 
 namespace electron::api {
 
-class NativeTheme : public gin::Wrappable<NativeTheme>,
-                    public gin_helper::EventEmitterMixin<NativeTheme>,
-                    private ui::NativeThemeObserver {
+class NativeTheme final : public gin::Wrappable<NativeTheme>,
+                          public gin_helper::EventEmitterMixin<NativeTheme>,
+                          private ui::NativeThemeObserver {
  public:
   static gin::Handle<NativeTheme> Create(v8::Isolate* isolate);
 

+ 1 - 1
shell/browser/api/electron_api_net_log.h

@@ -35,7 +35,7 @@ class ElectronBrowserContext;
 namespace api {
 
 // The code is referenced from the net_log::NetExportFileWriter class.
-class NetLog : public gin::Wrappable<NetLog> {
+class NetLog final : public gin::Wrappable<NetLog> {
  public:
   static gin::Handle<NetLog> Create(v8::Isolate* isolate,
                                     ElectronBrowserContext* browser_context);

+ 5 - 5
shell/browser/api/electron_api_notification.h

@@ -30,11 +30,11 @@ class ErrorThrower;
 
 namespace electron::api {
 
-class Notification : public gin::Wrappable<Notification>,
-                     public gin_helper::EventEmitterMixin<Notification>,
-                     public gin_helper::Constructible<Notification>,
-                     public gin_helper::CleanedUpAtExit,
-                     public NotificationDelegate {
+class Notification final : public gin::Wrappable<Notification>,
+                           public gin_helper::EventEmitterMixin<Notification>,
+                           public gin_helper::Constructible<Notification>,
+                           public gin_helper::CleanedUpAtExit,
+                           public NotificationDelegate {
  public:
   static bool IsSupported();
 

+ 6 - 6
shell/browser/api/electron_api_power_monitor.h

@@ -17,12 +17,12 @@
 
 namespace electron::api {
 
-class PowerMonitor : public gin::Wrappable<PowerMonitor>,
-                     public gin_helper::EventEmitterMixin<PowerMonitor>,
-                     public gin_helper::Pinnable<PowerMonitor>,
-                     private base::PowerStateObserver,
-                     private base::PowerSuspendObserver,
-                     private base::PowerThermalObserver {
+class PowerMonitor final : public gin::Wrappable<PowerMonitor>,
+                           public gin_helper::EventEmitterMixin<PowerMonitor>,
+                           public gin_helper::Pinnable<PowerMonitor>,
+                           private base::PowerStateObserver,
+                           private base::PowerSuspendObserver,
+                           private base::PowerThermalObserver {
  public:
   static v8::Local<v8::Value> Create(v8::Isolate* isolate);
 

+ 1 - 1
shell/browser/api/electron_api_power_save_blocker.h

@@ -19,7 +19,7 @@ class Handle;
 
 namespace electron::api {
 
-class PowerSaveBlocker : public gin::Wrappable<PowerSaveBlocker> {
+class PowerSaveBlocker final : public gin::Wrappable<PowerSaveBlocker> {
  public:
   static gin::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
 

+ 2 - 2
shell/browser/api/electron_api_protocol.h

@@ -45,8 +45,8 @@ enum class ProtocolError {
 };
 
 // Protocol implementation based on network services.
-class Protocol : public gin::Wrappable<Protocol>,
-                 public gin_helper::Constructible<Protocol> {
+class Protocol final : public gin::Wrappable<Protocol>,
+                       public gin_helper::Constructible<Protocol> {
  public:
   static gin::Handle<Protocol> Create(v8::Isolate* isolate,
                                       ElectronBrowserContext* browser_context);

+ 1 - 1
shell/browser/api/electron_api_push_notifications.h

@@ -21,7 +21,7 @@ class Handle;
 
 namespace electron::api {
 
-class PushNotifications
+class PushNotifications final
     : public ElectronBrowserClient::Delegate,
       public gin::Wrappable<PushNotifications>,
       public gin_helper::EventEmitterMixin<PushNotifications>,

+ 3 - 3
shell/browser/api/electron_api_screen.h

@@ -25,9 +25,9 @@ class ErrorThrower;
 
 namespace electron::api {
 
-class Screen : public gin::Wrappable<Screen>,
-               public gin_helper::EventEmitterMixin<Screen>,
-               private display::DisplayObserver {
+class Screen final : public gin::Wrappable<Screen>,
+                     public gin_helper::EventEmitterMixin<Screen>,
+                     private display::DisplayObserver {
  public:
   static v8::Local<v8::Value> Create(gin_helper::ErrorThrower error_thrower);
 

+ 1 - 1
shell/browser/api/electron_api_service_worker_context.h

@@ -22,7 +22,7 @@ class ElectronBrowserContext;
 
 namespace api {
 
-class ServiceWorkerContext
+class ServiceWorkerContext final
     : public gin::Wrappable<ServiceWorkerContext>,
       public gin_helper::EventEmitterMixin<ServiceWorkerContext>,
       private content::ServiceWorkerContextObserver {

+ 8 - 8
shell/browser/api/electron_api_session.h

@@ -60,18 +60,18 @@ class ElectronBrowserContext;
 
 namespace api {
 
-class Session : public gin::Wrappable<Session>,
-                public gin_helper::Pinnable<Session>,
-                public gin_helper::Constructible<Session>,
-                public gin_helper::EventEmitterMixin<Session>,
-                public gin_helper::CleanedUpAtExit,
+class Session final : public gin::Wrappable<Session>,
+                      public gin_helper::Pinnable<Session>,
+                      public gin_helper::Constructible<Session>,
+                      public gin_helper::EventEmitterMixin<Session>,
+                      public gin_helper::CleanedUpAtExit,
 #if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
-                private SpellcheckHunspellDictionary::Observer,
+                      private SpellcheckHunspellDictionary::Observer,
 #endif
 #if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
-                private extensions::ExtensionRegistryObserver,
+                      private extensions::ExtensionRegistryObserver,
 #endif
-                private content::DownloadManager::Observer {
+                      private content::DownloadManager::Observer {
  public:
   // Gets or creates Session from the |browser_context|.
   static gin::Handle<Session> CreateFrom(

+ 1 - 1
shell/browser/api/electron_api_system_preferences.h

@@ -37,7 +37,7 @@ enum class NotificationCenterKind {
 };
 #endif
 
-class SystemPreferences
+class SystemPreferences final
     : public gin::Wrappable<SystemPreferences>,
       public gin_helper::EventEmitterMixin<SystemPreferences>
 #if BUILDFLAG(IS_WIN)

+ 6 - 6
shell/browser/api/electron_api_tray.h

@@ -38,12 +38,12 @@ namespace electron::api {
 
 class Menu;
 
-class Tray : public gin::Wrappable<Tray>,
-             public gin_helper::EventEmitterMixin<Tray>,
-             public gin_helper::Constructible<Tray>,
-             public gin_helper::CleanedUpAtExit,
-             public gin_helper::Pinnable<Tray>,
-             private TrayIconObserver {
+class Tray final : public gin::Wrappable<Tray>,
+                   public gin_helper::EventEmitterMixin<Tray>,
+                   public gin_helper::Constructible<Tray>,
+                   public gin_helper::CleanedUpAtExit,
+                   public gin_helper::Pinnable<Tray>,
+                   private TrayIconObserver {
  public:
   // gin_helper::Constructible
   static gin::Handle<Tray> New(gin_helper::ErrorThrower thrower,

+ 1 - 1
shell/browser/api/electron_api_utility_process.h

@@ -39,7 +39,7 @@ class Connector;
 
 namespace electron::api {
 
-class UtilityProcessWrapper
+class UtilityProcessWrapper final
     : public gin::Wrappable<UtilityProcessWrapper>,
       public gin_helper::Pinnable<UtilityProcessWrapper>,
       public gin_helper::EventEmitterMixin<UtilityProcessWrapper>,

+ 1 - 1
shell/browser/api/electron_api_web_contents.cc

@@ -1887,7 +1887,7 @@ namespace {
 // This object wraps the InvokeCallback so that if it gets GC'd by V8, we can
 // still call the callback and send an error. Not doing so causes a Mojo DCHECK,
 // since Mojo requires callbacks to be called before they are destroyed.
-class ReplyChannel : public gin::Wrappable<ReplyChannel> {
+class ReplyChannel final : public gin::Wrappable<ReplyChannel> {
  public:
   using InvokeCallback = electron::mojom::ElectronApiIPC::InvokeCallback;
   static gin::Handle<ReplyChannel> Create(v8::Isolate* isolate,

+ 13 - 13
shell/browser/api/electron_api_web_contents.h

@@ -109,19 +109,19 @@ class BaseWindow;
 class FrameSubscriber;
 
 // Wrapper around the content::WebContents.
-class WebContents : public ExclusiveAccessContext,
-                    public gin::Wrappable<WebContents>,
-                    public gin_helper::EventEmitterMixin<WebContents>,
-                    public gin_helper::Constructible<WebContents>,
-                    public gin_helper::Pinnable<WebContents>,
-                    public gin_helper::CleanedUpAtExit,
-                    public content::WebContentsObserver,
-                    public content::WebContentsDelegate,
-                    private content::RenderWidgetHost::InputEventObserver,
-                    public content::JavaScriptDialogManager,
-                    public InspectableWebContentsDelegate,
-                    public InspectableWebContentsViewDelegate,
-                    public BackgroundThrottlingSource {
+class WebContents final : public ExclusiveAccessContext,
+                          public gin::Wrappable<WebContents>,
+                          public gin_helper::EventEmitterMixin<WebContents>,
+                          public gin_helper::Constructible<WebContents>,
+                          public gin_helper::Pinnable<WebContents>,
+                          public gin_helper::CleanedUpAtExit,
+                          public content::WebContentsObserver,
+                          public content::WebContentsDelegate,
+                          private content::RenderWidgetHost::InputEventObserver,
+                          public content::JavaScriptDialogManager,
+                          public InspectableWebContentsDelegate,
+                          public InspectableWebContentsViewDelegate,
+                          public BackgroundThrottlingSource {
  public:
   enum class Type {
     kBackgroundPage,  // An extension background page.

+ 4 - 4
shell/browser/api/electron_api_web_frame_main.h

@@ -38,10 +38,10 @@ namespace electron::api {
 class WebContents;
 
 // Bindings for accessing frames from the main process.
-class WebFrameMain : public gin::Wrappable<WebFrameMain>,
-                     public gin_helper::EventEmitterMixin<WebFrameMain>,
-                     public gin_helper::Pinnable<WebFrameMain>,
-                     public gin_helper::Constructible<WebFrameMain> {
+class WebFrameMain final : public gin::Wrappable<WebFrameMain>,
+                           public gin_helper::EventEmitterMixin<WebFrameMain>,
+                           public gin_helper::Pinnable<WebFrameMain>,
+                           public gin_helper::Constructible<WebFrameMain> {
  public:
   // Create a new WebFrameMain and return the V8 wrapper of it.
   static gin::Handle<WebFrameMain> New(v8::Isolate* isolate);

+ 2 - 1
shell/browser/api/electron_api_web_request.h

@@ -31,7 +31,8 @@ class Handle;
 
 namespace electron::api {
 
-class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
+class WebRequest final : public gin::Wrappable<WebRequest>,
+                         public WebRequestAPI {
  public:
   // Return the WebRequest object attached to |browser_context|, create if there
   // is no one.

+ 3 - 3
shell/browser/api/message_port.h

@@ -27,9 +27,9 @@ class Connector;
 namespace electron {
 
 // A non-blink version of blink::MessagePort.
-class MessagePort : public gin::Wrappable<MessagePort>,
-                    public gin_helper::CleanedUpAtExit,
-                    public mojo::MessageReceiver {
+class MessagePort final : public gin::Wrappable<MessagePort>,
+                          public gin_helper::CleanedUpAtExit,
+                          public mojo::MessageReceiver {
  public:
   ~MessagePort() override;
   static gin::Handle<MessagePort> Create(v8::Isolate* isolate);

+ 1 - 1
shell/common/api/electron_api_native_image.h

@@ -45,7 +45,7 @@ class ErrorThrower;
 
 namespace electron::api {
 
-class NativeImage : public gin::Wrappable<NativeImage> {
+class NativeImage final : public gin::Wrappable<NativeImage> {
  public:
   NativeImage(v8::Isolate* isolate, const gfx::Image& image);
 #if BUILDFLAG(IS_WIN)

+ 3 - 2
shell/common/api/electron_api_url_loader.cc

@@ -162,8 +162,9 @@ class BufferDataSource : public mojo::DataPipeProducer::DataSource {
   std::vector<char> buffer_;
 };
 
-class JSChunkedDataPipeGetter : public gin::Wrappable<JSChunkedDataPipeGetter>,
-                                public network::mojom::ChunkedDataPipeGetter {
+class JSChunkedDataPipeGetter final
+    : public gin::Wrappable<JSChunkedDataPipeGetter>,
+      public network::mojom::ChunkedDataPipeGetter {
  public:
   static gin::Handle<JSChunkedDataPipeGetter> Create(
       v8::Isolate* isolate,

+ 1 - 1
shell/common/api/electron_api_url_loader.h

@@ -47,7 +47,7 @@ class ElectronBrowserContext;
 namespace electron::api {
 
 /** Wraps a SimpleURLLoader to make it usable from JavaScript */
-class SimpleURLLoaderWrapper
+class SimpleURLLoaderWrapper final
     : public gin::Wrappable<SimpleURLLoaderWrapper>,
       public gin_helper::EventEmitterMixin<SimpleURLLoaderWrapper>,
       private network::SimpleURLLoaderStreamConsumer,

+ 1 - 1
shell/common/gin_converters/net_converter.cc

@@ -253,7 +253,7 @@ bool Converter<net::HttpRequestHeaders>::FromV8(v8::Isolate* isolate,
 
 namespace {
 
-class ChunkedDataPipeReadableStream
+class ChunkedDataPipeReadableStream final
     : public gin::Wrappable<ChunkedDataPipeReadableStream> {
  public:
   static gin::Handle<ChunkedDataPipeReadableStream> Create(

+ 2 - 2
shell/common/gin_helper/event.h

@@ -23,8 +23,8 @@ class ObjectTemplate;
 
 namespace gin_helper::internal {
 
-class Event : public gin::Wrappable<Event>,
-              public gin_helper::Constructible<Event> {
+class Event final : public gin::Wrappable<Event>,
+                    public gin_helper::Constructible<Event> {
  public:
   // gin_helper::Constructible
   static gin::Handle<Event> New(v8::Isolate* isolate);

+ 2 - 2
shell/renderer/api/electron_api_ipc_renderer.cc

@@ -40,8 +40,8 @@ RenderFrame* GetCurrentRenderFrame() {
   return RenderFrame::FromWebFrame(frame);
 }
 
-class IPCRenderer : public gin::Wrappable<IPCRenderer>,
-                    private content::RenderFrameObserver {
+class IPCRenderer final : public gin::Wrappable<IPCRenderer>,
+                          private content::RenderFrameObserver {
  public:
   static gin::WrapperInfo kWrapperInfo;
 

+ 2 - 2
shell/renderer/api/electron_api_web_frame.cc

@@ -326,8 +326,8 @@ class SpellCheckerHolder final : private content::RenderFrameObserver {
   std::unique_ptr<SpellCheckClient> spell_check_client_;
 };
 
-class WebFrameRenderer : public gin::Wrappable<WebFrameRenderer>,
-                         private content::RenderFrameObserver {
+class WebFrameRenderer final : public gin::Wrappable<WebFrameRenderer>,
+                               private content::RenderFrameObserver {
  public:
   static gin::WrapperInfo kWrapperInfo;
 

+ 2 - 2
shell/services/node/parent_port.h

@@ -30,8 +30,8 @@ namespace electron {
 // There is only a single instance of this class
 // for the lifetime of a Utility Process which
 // also means that GC lifecycle is ignored by this class.
-class ParentPort : public gin::Wrappable<ParentPort>,
-                   public mojo::MessageReceiver {
+class ParentPort final : public gin::Wrappable<ParentPort>,
+                         public mojo::MessageReceiver {
  public:
   static ParentPort* GetInstance();
   static gin::Handle<ParentPort> Create(v8::Isolate* isolate);