summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/resources/webidl2/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/resources/webidl2/README.md')
-rw-r--r--testing/web-platform/tests/resources/webidl2/README.md760
1 files changed, 760 insertions, 0 deletions
diff --git a/testing/web-platform/tests/resources/webidl2/README.md b/testing/web-platform/tests/resources/webidl2/README.md
new file mode 100644
index 000000000..f7d03fcde
--- /dev/null
+++ b/testing/web-platform/tests/resources/webidl2/README.md
@@ -0,0 +1,760 @@
+
+# WebIDL 2
+
+[![NPM version](https://badge.fury.io/js/webidl2.png)](http://badge.fury.io/js/webidl2)
+
+Purpose
+=======
+
+This is a parser for the [WebIDL](http://dev.w3.org/2006/webapi/WebIDL/) language. If
+you don't know what that is, then you probably don't need it. It is meant to be used
+both in Node and in the browser (the parser likely works in other JS environments, but
+not the test suite).
+
+What of v1?
+-----------
+There was a previous incarnation of this project. I had written it in the most quick
+and dirty manner that was handy because I required it as a dependency in an experiment.
+As these things tend to happen, some people started using that, which then had to be
+maintained. But since it was not built on solid foundations, it was painful to keep
+up to date with the specification, which is a bit of a moving target.
+
+So I started from scratch. Compared to the previous version (which used a parser generator)
+this one is about 6x less code (which translates to 4x smaller minified or 2x smaller
+minizipped) and 4x faster. The test suite is reasonably complete (95% coverage), much more
+than previously. This version is up to date with WebIDL, rather than a couple years' behind.
+It also has *far* better error reporting.
+
+The AST you get from parsing is very similar to the one you got in v1, but some adjustments
+have been made in order to be more systematic, and to map better to what's actually in the spec
+now. If you used v1, you will need to tweak your code but the result ought to be simpler and
+you ought to be able to be a fair bit less defensive against irregularities in the way
+information is represented.
+
+Installation
+============
+
+Just the usual. For Node:
+
+ npm install webidl2
+
+In the browser:
+
+ <script src='webidl2.js'></script>
+
+Documentation
+=============
+
+The API to WebIDL2 is trivial: you parse a string of WebIDL and it returns a syntax tree.
+
+Parsing
+-------
+In Node, that happens with:
+
+ var WebIDL2 = require("webidl2");
+ var tree = WebIDL2.parse("string of WebIDL");
+
+In the browser:
+
+ <script src='webidl2.js'></script>
+ <script>
+ var tree = WebIDL2.parse("string of WebIDL");
+ </script>
+
+Advanced Parsing
+----------------
+
+`parse()` can optionally accept a second parameter, an options object, which can be used to
+modify parsing behavior.
+
+The following options are recognized:
+```javascript
+{
+ allowNestedTypedefs: false #
+}
+```
+And their meanings are as follows:
+
+* `allowNestedTypedefs`: Boolean indicating whether the parser should accept `typedef`s as valid members of `interface`s. This is non-standard syntax and therefore the default is `false`.
+
+Errors
+------
+When there is a syntax error in the WebIDL, it throws an exception object with the following
+properties:
+
+* `message`: the error message
+* `line`: the line at which the error occurred.
+* `input`: a short peek at the text at the point where the error happened
+* `tokens`: the five tokens at the point of error, as understood by the tokeniser
+ (this is the same content as `input`, but seen from the tokeniser's point of view)
+
+The exception also has a `toString()` method that hopefully should produce a decent
+error message.
+
+AST (Abstract Syntax Tree)
+--------------------------
+The `parse()` method returns a tree object representing the parse tree of the IDL.
+Comment and white space are not represented in the AST.
+
+The root of this object is always an array of definitions (where definitions are
+any of interfaces, exceptions, callbacks, etc. — anything that can occur at the root
+of the IDL).
+
+### IDL Type
+
+This structure is used in many other places (operation return types, argument types, etc.).
+It captures a WebIDL type with a number of options. Types look like this and are typically
+attached to a field called `idlType`:
+
+ {
+ "sequence": false,
+ "generic": null,
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": "void"
+ }
+
+Where the fields are as follows:
+
+* `sequence`: Boolean indicating whether this is a sequence or not. Deprecated. Use
+ `generic` instead.
+* `generic`: String indicating the generic type (e.g. "Promise", "sequence"). `null`
+ otherwise.
+* `nullable`: Boolean indicating whether this is nullable or not.
+* `array`: Either `false` to indicate that it is not an array, or a number for the level of
+ array nesting.
+* `union`: Boolean indicating whether this is a union type or not.
+* `idlType`: Can be different things depending on context. In most cases, this will just
+ be a string with the type name. But the reason this field isn't called "typeName" is
+ because it can take more complex values. If the type is a union, then this contains an
+ array of the types it unites. If it is a generic type, it contains the IDL type
+ description for the type in the sequence, the eventual value of the promise, etc.
+
+#### Interactions between `nullable` and `array`
+
+A more complex data model for our AST would likely represent `Foo[][][]` as a series of
+nested types four levels deep with three anonymous array types eventually containing a
+`Foo` type. But experience shows that such structures are cumbersome to use, and so we
+have a simpler model in which the depth of the array is specified with the `array` field.
+
+This is all fine and well, and in the vast majority of cases is actually simpler. But it
+does run afoul of cases in which it is necessary to distinguish between `Foo[][][]?`,
+`Foo?[][][]`, `Foo[][]?[]`, or even `Foo?[]?[]?[]?`.
+
+For this, when a type is an array type an additional `nullableArray` field is made available
+that captures which of the arrays contain nullable elements. It contains booleans that are
+true if the given array depth contains nullable elements, and false otherwise (mapping that to
+the syntax, and item is true if there is a `?` preceding the `[]`). These examples ought to
+clarify the model:
+
+ Foo[][][]?
+ -> nullable: true
+ -> nullableArray: [false, false, false]
+ Foo?[][][]
+ -> nullable: false
+ -> nullableArray: [true, false, false]
+ Foo[][]?[]
+ -> nullable: false
+ -> nullableArray: [false, false, true]
+ Foo?[]?[]?[]?
+ -> nullable: true
+ -> nullableArray: [true, true, true]
+
+Of particular importance, please note that the overall type is only `nullable` if there is
+a `?` at the end.
+
+### Interface
+Interfaces look like this:
+
+ {
+ "type": "interface",
+ "name": "Animal",
+ "partial": false,
+ "members": [...],
+ "inheritance": null,
+ "extAttrs": [...]
+ },
+ {
+ "type": "interface",
+ "name": "Human",
+ "partial": false,
+ "members": [...],
+ "inheritance": "Animal",
+ "extAttrs": [...]
+ }
+
+The fields are as follows:
+
+* `type`: Always "interface".
+* `name`: The name of the interface
+* `partial`: A boolean indicating whether it's a partial interface.
+* `members`: An array of interface members (attributes, operations, etc.). Empty if there are none.
+* `inheritance`: A string giving the name of an interface this one inherits from, `null` otherwise.
+ **NOTE**: In v1 this was an array, but multiple inheritance is no longer supported so this didn't make
+ sense.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+### Callback Interfaces
+
+These are captured by the same structure as [Interfaces](#interface) except that
+their `type` field is "callback interface".
+
+### Callback
+
+A callback looks like this:
+
+ {
+ "type": "callback",
+ "name": "AsyncOperationCallback",
+ "idlType": {
+ "sequence": false,
+ "generic": null,
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": "void"
+ },
+ "arguments": [...],
+ "extAttrs": []
+ }
+
+The fields are as follows:
+
+* `type`: Always "callback".
+* `name`: The name of the callback.
+* `idlType`: An [IDL Type](#idl-type) describing what the callback returns.
+* `arguments`: A list of [arguments](#arguments), as in function paramters.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+### Dictionary
+
+A dictionary looks like this:
+
+ {
+ "type": "dictionary",
+ "name": "PaintOptions",
+ "partial": false,
+ "members": [
+ {
+ "type": "field",
+ "name": "fillPattern",
+ "required": false,
+ "idlType": {
+ "sequence": false,
+ "generic": null,
+ "nullable": true,
+ "array": false,
+ "union": false,
+ "idlType": "DOMString"
+ },
+ "extAttrs": [],
+ "default": {
+ "type": "string",
+ "value": "black"
+ }
+ }
+ ],
+ "inheritance": null,
+ "extAttrs": []
+ }
+
+The fields are as follows:
+
+* `type`: Always "dictionary".
+* `name`: The dictionary name.
+* `partial`: Boolean indicating whether it's a partial dictionary.
+* `members`: An array of members (see below).
+* `inheritance`: A string indicating which dictionary is being inherited from, `null` otherwise.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+All the members are fields as follows:
+
+* `type`: Always "field".
+* `name`: The name of the field.
+* `required`: Boolean indicating whether this is a [required](https://heycam.github.io/webidl/#required-dictionary-member) field.
+* `idlType`: An [IDL Type](#idl-type) describing what field's type.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+* `default`: A [default value](#default-and-const-values), absent if there is none.
+
+### Exception
+
+An exception looks like this:
+
+ {
+ "type": "exception",
+ "name": "HierarchyRequestError",
+ "members": [
+ {
+ "type": "field",
+ "name": "code",
+ "idlType": {
+ "sequence": false,
+ "generic": null,
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": "unsigned short"
+ },
+ "extAttrs": []
+ }
+ ],
+ "inheritance": "DOMException",
+ "extAttrs": []
+ }
+
+The fields are as follows:
+
+* `type`: Always "exception".
+* `name`: The exception name.
+* `members`: An array of members (constants or fields, where fields are described below).
+* `inheritance`: A string indicating which exception is being inherited from, `null` otherwise.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+Members that aren't [constants](#constants) have the following fields:
+
+* `type`: Always "field".
+* `name`: The field's name.
+* `idlType`: An [IDL Type](#idl-type) describing what field's type.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+### Enum
+
+An enum looks like this:
+
+ {
+ "type": "enum",
+ "name": "MealType",
+ "values": [
+ "rice",
+ "noodles",
+ "other"
+ ],
+ "extAttrs": []
+ }
+
+The fields are as follows:
+
+* `type`: Always "enum".
+* `name`: The enum's name.
+* `value`: An array of values (strings).
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+### Typedef
+
+A typedef looks like this:
+
+ {
+ "type": "typedef",
+ "typeExtAttrs": [],
+ "idlType": {
+ "sequence": true,
+ "generic": "sequence",
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": {
+ "sequence": false,
+ "generic": null,
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": "Point"
+ }
+ },
+ "name": "PointSequence",
+ "extAttrs": []
+ }
+
+The fields are as follows:
+
+* `type`: Always "typedef".
+* `name`: The typedef's name.
+* `idlType`: An [IDL Type](#idl-type) describing what typedef's type.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+* `typeExtAttrs`: A list of [extended attributes](#extended-attributes) that apply to the
+type rather than to the typedef as a whole.
+
+### Implements
+
+An implements definition looks like this:
+
+ {
+ "type": "implements",
+ "target": "Node",
+ "implements": "EventTarget",
+ "extAttrs": []
+ }
+
+The fields are as follows:
+
+* `type`: Always "implements".
+* `target`: The interface that implements another.
+* `implements`: The interface that is being implemented by the target.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+### Operation Member
+
+An operation looks like this:
+
+ {
+ "type": "operation",
+ "getter": false,
+ "setter": false,
+ "creator": false,
+ "deleter": false,
+ "legacycaller": false,
+ "static": false,
+ "stringifier": false,
+ "idlType": {
+ "sequence": false,
+ "generic": null,
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": "void"
+ },
+ "name": "intersection",
+ "arguments": [
+ {
+ "optional": false,
+ "variadic": true,
+ "extAttrs": [],
+ "idlType": {
+ "sequence": false,
+ "generic": null,
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": "long"
+ },
+ "name": "ints"
+ }
+ ],
+ "extAttrs": []
+ }
+
+The fields are as follows:
+
+* `type`: Always "operation".
+* `getter`: True if a getter operation.
+* `setter`: True if a setter operation.
+* `creator`: True if a creator operation.
+* `deleter`: True if a deleter operation.
+* `legacycaller`: True if a legacycaller operation.
+* `static`: True if a static operation.
+* `stringifier`: True if a stringifier operation.
+* `idlType`: An [IDL Type](#idl-type) of what the operation returns. If a stringifier, may be absent.
+* `name`: The name of the operation. If a stringifier, may be `null`.
+* `arguments`: An array of [arguments](#arguments) for the operation.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+### Attribute Member
+
+An attribute member looks like this:
+
+ {
+ "type": "attribute",
+ "static": false,
+ "stringifier": false,
+ "inherit": false,
+ "readonly": false,
+ "idlType": {
+ "sequence": false,
+ "generic": null,
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": "RegExp"
+ },
+ "name": "regexp",
+ "extAttrs": []
+ }
+
+The fields are as follows:
+
+* `type`: Always "attribute".
+* `name`: The attribute's name.
+* `static`: True if it's a static attribute.
+* `stringifier`: True if it's a stringifier attribute.
+* `inherit`: True if it's an inherit attribute.
+* `readonly`: True if it's a read-only attribute.
+* `idlType`: An [IDL Type](#idl-type) for the attribute.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+### Constant Member
+
+A constant member looks like this:
+
+ {
+ "type": "const",
+ "nullable": false,
+ "idlType": "boolean",
+ "name": "DEBUG",
+ "value": {
+ "type": "boolean",
+ "value": false
+ },
+ "extAttrs": []
+ }
+
+The fields are as follows:
+
+* `type`: Always "const".
+* `nullable`: Whether its type is nullable.
+* `idlType`: The type of the constant (a simple type, the type name).
+* `name`: The name of the constant.
+* `value`: The constant value as described by [Const Values](#default-and-const-values)
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+### Serializer Member
+
+Serializers come in many shapes, which are best understood by looking at the
+examples below that map the IDL to the produced AST.
+
+ // serializer;
+ {
+ "type": "serializer",
+ "extAttrs": []
+ }
+
+ // serializer DOMString serialize();
+ {
+ "type": "serializer",
+ "idlType": {
+ "sequence": false,
+ "generic": null,
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": "DOMString"
+ },
+ "operation": {
+ "name": "serialize",
+ "arguments": []
+ },
+ "extAttrs": []
+ }
+
+ // serializer = { from, to, amount, description };
+ {
+ "type": "serializer",
+ "patternMap": true,
+ "names": [
+ "from",
+ "to",
+ "amount",
+ "description"
+ ],
+ "extAttrs": []
+ }
+
+ // serializer = number;
+ {
+ "type": "serializer",
+ "name": "number",
+ "extAttrs": []
+ }
+
+ // serializer = [ name, number ];
+ {
+ "type": "serializer",
+ "patternList": true,
+ "names": [
+ "name",
+ "number"
+ ],
+ "extAttrs": []
+ }
+
+The common fields are as follows:
+
+* `type`: Always "serializer".
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+For a simple serializer, that's all there is. If the serializer is an operation, it will
+have:
+
+* `idlType`: An [IDL Type](#idl-type) describing what the serializer returns.
+* `operation`: An object with the following fields:
+ * `name`: The name of the operation.
+ * `arguments`: An array of [arguments](#arguments) for the operation.
+
+If the serializer is a pattern map:
+
+* `patternMap`: Always true.
+* `names`: An array of names in the pattern map.
+
+If the serializer is a pattern list:
+
+* `patternList`: Always true.
+* `names`: An array of names in the pattern list.
+
+Finally, if the serializer is a named serializer:
+
+* `name`: The serializer's name.
+
+### Iterator Member
+
+Iterator members look like this
+
+ {
+ "type": "iterator",
+ "getter": false,
+ "setter": false,
+ "creator": false,
+ "deleter": false,
+ "legacycaller": false,
+ "static": false,
+ "stringifier": false,
+ "idlType": {
+ "sequence": false,
+ "generic": null,
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": "Session2"
+ },
+ "iteratorObject": "SessionIterator",
+ "extAttrs": []
+ }
+
+* `type`: Always "iterator".
+* `iteratorObject`: The string on the right-hand side; absent if there isn't one.
+* the rest: same as on [operations](#operation-member).
+
+### Arguments
+
+The arguments (e.g. for an operation) look like this:
+
+ "arguments": [
+ {
+ "optional": false,
+ "variadic": true,
+ "extAttrs": [],
+ "idlType": {
+ "sequence": false,
+ "generic": null,
+ "nullable": false,
+ "array": false,
+ "union": false,
+ "idlType": "long"
+ },
+ "name": "ints"
+ }
+ ]
+
+The fields are as follows:
+
+* `optional`: True if the argument is optional.
+* `variadic`: True if the argument is variadic.
+* `idlType`: An [IDL Type](#idl-type) describing the type of the argument.
+* `name`: The argument's name.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+### Extended Attributes
+
+Extended attributes are arrays of items that look like this:
+
+ "extAttrs": [
+ {
+ "name": "TreatNullAs",
+ "arguments": null,
+ "rhs": {
+ "type": "identifier",
+ "value": "EmptyString"
+ }
+ }
+ ]
+
+The fields are as follows:
+
+* `name`: The extended attribute's name.
+* `arguments`: If the extended attribute takes arguments (e.g. `[Foo()]`) or if
+ its right-hand side does (e.g. `[NamedConstructor=Name(DOMString blah)]`) they
+ are listed here. Note that an empty arguments list will produce an empty array,
+ whereas the lack thereof will yield a `null`. If there is an `rhs` field then
+ they are the right-hand side's arguments, otherwise they apply to the extended
+ attribute directly.
+* `rhs`: If there is a right-hand side, this will capture its `type` (which can be
+ "identifier" or "identifier-list") and its `value`.
+* `typePair`: If the extended attribute is a `MapClass` this will capture the
+ map's key type and value type respectively.
+
+### Default and Const Values
+
+Dictionary fields and operation arguments can take default values, and constants take
+values, all of which have the following fields:
+
+* `type`: One of string, number, boolean, null, Infinity, NaN, or sequence.
+
+For string, number, boolean, and sequence:
+
+* `value`: The value of the given type. For sequence, the only possible value is `[]`.
+
+For Infinity:
+
+* `negative`: Boolean indicating whether this is negative Infinity or not.
+
+### `iterable<>`, `legacyiterable<>`, `maplike<>`, `setlike<>` declarations
+
+These appear as members of interfaces that look like this:
+
+ {
+ "type": "maplike", // or "legacyiterable" / "iterable" / "setlike"
+ "idlType": /* One or two types */,
+ "readonly": false, // only for maplike and setlike
+ "extAttrs": []
+ }
+
+The fields are as follows:
+
+* `type`: Always one of "iterable", "legacyiterable", "maplike" or "setlike".
+* `idlType`: An [IDL Type](#idl-type) (or an array of two types) representing the declared type arguments.
+* `readonly`: Whether the maplike or setlike is declared as read only.
+* `extAttrs`: A list of [extended attributes](#extended-attributes).
+
+
+Testing
+=======
+
+In order to run the tests you need to ensure that the widlproc submodule inside `test` is
+initialised and up to date:
+
+ git submodule init
+ git submodule update
+
+Running
+-------
+The test runs with mocha and expect.js. Normally, running mocha in the root directory
+should be enough once you're set up.
+
+Coverage
+--------
+Current test coverage, as documented in `coverage.html`, is 95%. You can run your own
+coverage analysis with:
+
+ jscoverage lib lib-cov
+
+That will create the lib-cov directory with instrumented code; the test suite knows
+to use that if needed. You can then run the tests with:
+
+ JSCOV=1 mocha --reporter html-cov > coverage.html
+
+Note that I've been getting weirdly overescaped results from the html-cov reporter,
+so you might wish to try this instead:
+
+ JSCOV=1 mocha --reporter html-cov | sed "s/&lt;/</g" | sed "s/&gt;/>/g" | sed "s/&quot;/\"/g" > coverage.html
+
+Browser tests
+-------------
+In order to test in the browser, get inside `test/web` and run `make-web-tests.js`. This
+will generate a `browser-tests.html` file that you can open in a browser. As of this
+writing tests pass in the latest Firefox, Chrome, Opera, and Safari. Testing on IE
+and older versions will happen progressively.
+
+TODO
+====
+
+* add some tests to address coverage limitations
+* add a push API for processors that need to process things like comments