WebIDL

WebIDL describes interfaces web browsers are supposed to implement.

The interaction between WebIDL and the build system is somewhat complex. This document will attempt to explain how it all works.

Overview

.webidl files throughout the tree define interfaces the browser implements. Since Gecko/Firefox is implemented in C++, there is a mechanism to convert these interfaces and associated metadata to C++ code. That’s where the build system comes into play.

All the code for interacting with .webidl files lives under dom/bindings. There is code in the build system to deal with WebIDLs explicitly.

WebIDL source file flavors

Not all .webidl files are created equal! There are several flavors, each represented by a separate symbol from mozbuild Sandbox Symbols.

WEBIDL_FILES

Refers to regular/static .webidl files. Most WebIDL interfaces are defined this way.

GENERATED_EVENTS_WEBIDL_FILES

In addition to generating a binding, these .webidl files also generate a source file implementing the event object in C++

PREPROCESSED_WEBIDL_FILES

The .webidl files are generated by preprocessing an input file. They otherwise behave like WEBIDL_FILES.

TEST_WEBIDL_FILES

Like WEBIDL_FILES but the interfaces are for testing only and aren’t shipped with the browser.

PREPROCESSED_TEST_WEBIDL_FILES

Like TEST_WEBIDL_FILES except the .webidl is obtained via preprocessing, much like PREPROCESSED_WEBIDL_FILES.

GENERATED_WEBIDL_FILES

The .webidl for these is obtained through an external mechanism. Typically there are custom build rules for producing these files.

Producing C++ code

The most complicated part about WebIDLs is the process by which .webidl files are converted into C++.

This process is handled by code in the mozwebidlcodegen package. mozwebidlcodegen.WebIDLCodegenManager is specifically where you want to look for how code generation is performed. This includes complex dependency management.

Requirements

This section aims to document the build and developer workflow requirements for WebIDL.

Parser unit tests

There are parser tests provided by dom/bindings/parser/runtests.py that should run as part of make check. There must be a mechanism to run the tests in human mode so they output friendly error messages.

The current mechanism for this is mach webidl-parser-test.

Mochitests

There are various mochitests under dom/bindings/test. They should be runnable through the standard mechanisms.

Working with test interfaces

TestExampleGenBinding.cpp calls into methods from the TestExampleInterface, TestExampleProxyInterface, TestExampleThrowingConstructorInterface, and TestExampleWorkerInterface interfaces. These interfaces need to be generated as part of the build. These interfaces should not be exported or packaged.

There is a compiletests make target in dom/bindings that isn’t part of the build that facilitates turnkey code generation and test file compilation.

Minimal rebuilds

Reprocessing every output for every change is expensive. So we don’t inconvenience people changing .webidl files, the build system should only perform a minimal rebuild when sources change.

This logic is mostly all handled in mozwebidlcodegen.WebIDLCodegenManager. The unit tests for that Python code should adequately test typical rebuild scenarios.

Bug 940469 tracks making the existing implementation better.

Explicit method for performing codegen

There needs to be an explicit method for invoking code generation. It needs to cover regular and test files.

This is implemented via make export in dom/bindings.

No-op binding generation should be fast

So developers touching .webidl files are not inconvenienced, no-op binding generation should be fast. Watch out for the build system processing large dependency files it doesn’t need in order to perform code generation.

Ability to generate example files

Any interface can have example .h/.cpp files generated. There must be a mechanism to facilitate this.

This is currently facilitated through mach webidl-example. e.g. mach webidl-example HTMLStyleElement.