WebIDL

WebIDL 描述了 Web 浏览器应该实现的接口。

WebIDL 和构建系统之间的交互相当复杂。本文档将尝试解释其工作原理。

概述

树中的 .webidl 文件定义了浏览器实现的接口。由于 Gecko/Firefox 是用 C++ 实现的,因此存在一种机制可以将这些接口和关联的元数据转换为 C++ 代码。这就是构建系统发挥作用的地方。

.webidl 文件交互的所有代码都位于 dom/bindings 下。构建系统中有代码专门处理 WebIDL。

WebIDL 源文件类型

并非所有 .webidl 文件都相同!有几种类型,每种类型都由 mozbuild 沙盒符号 中的单独符号表示。

WEBIDL_FILES

指的是常规/静态 .webidl 文件。大多数 WebIDL 接口都是这样定义的。

GENERATED_EVENTS_WEBIDL_FILES

除了生成绑定外,这些 .webidl 文件还会生成一个用 C++ 实现事件对象的源文件。

PREPROCESSED_WEBIDL_FILES

这些 .webidl 文件是通过预处理输入文件生成的。除此之外,它们的行为类似于 WEBIDL_FILES

TEST_WEBIDL_FILES

WEBIDL_FILES 类似,但这些接口仅用于测试,不会与浏览器一起发布。

PREPROCESSED_TEST_WEBIDL_FILES

TEST_WEBIDL_FILES 类似,但 .webidl 是通过预处理获得的,与 PREPROCESSED_WEBIDL_FILES 非常相似。

GENERATED_WEBIDL_FILES

这些文件的 .webidl 是通过 外部 机制获得的。通常,存在用于生成这些文件的自定义构建规则。

生成 C++ 代码

关于 WebIDL 最复杂的部分是如何将 .webidl 文件转换为 C++。

此过程由 mozwebidlcodegen 包中的代码处理。 mozwebidlcodegen.WebIDLCodegenManager 是您想要查找如何执行代码生成的地方。这包括复杂的依赖项管理。

需求

本节旨在记录 WebIDL 的构建和开发者工作流程需求。

解析器单元测试

dom/bindings/parser/runtests.py 提供了解析器测试,这些测试应该作为 make check 的一部分运行。必须有一种机制以 人工 模式运行测试,以便它们输出友好的错误消息。

当前的机制是 mach webidl-parser-test

Mochitests

dom/bindings/test 下有各种 mochitests。它们应该可以通过标准机制运行。

使用测试接口

TestExampleGenBinding.cpp 调用 TestExampleInterfaceTestExampleProxyInterfaceTestExampleThrowingConstructorInterfaceTestExampleWorkerInterface 接口中的方法。这些接口需要作为构建的一部分生成。这些接口不应导出或打包。

dom/bindings 中有一个 compiletests make 目标,它不是构建的一部分,它有助于一键式代码生成和测试文件编译。

最小化重建

为每次更改重新处理每个输出成本很高。因此,为了不给修改 .webidl 文件的人带来不便,构建系统在源代码更改时只应执行最小化重建。

此逻辑主要由 mozwebidlcodegen.WebIDLCodegenManager 处理。该 Python 代码的单元测试应充分测试典型的重建场景。

Bug 940469 跟踪改进现有实现。

执行代码生成的明确方法

需要一种明确的方法来调用代码生成。它需要涵盖常规文件和测试文件。

这是通过 dom/bindings 中的 make export 实现的。

无操作绑定生成应该很快

为了不给修改 .webidl 文件的开发者带来不便,无操作绑定生成应该很快。注意构建系统是否处理了它不需要的大型依赖文件来执行代码生成。

生成示例文件的能力

任何 接口都可以生成示例 .h/.cpp 文件。必须有一种机制来促进这一点。

这目前通过 mach webidl-example 促进。例如 mach webidl-example HTMLStyleElement