Skip to content

Commit 67ccd4e

Browse files
authored
feat(productions/attribute): validate (#558)
* feat(productions/attribute): validate This still needs to check generics inside unions but probably as a followup. This is needed for Gecko since it still uses `attribute sequence<>`. * docs
1 parent 637875a commit 67ccd4e

File tree

7 files changed

+54
-10
lines changed

7 files changed

+54
-10
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ properties:
186186
* `sourceName`: the source name you passed to `parse()`.
187187
* `level`: `"error"` by default, can be `"warning"` for some validations for e.g. potential future deprecations.
188188
* `ruleName`: Only for validations. Currently the followings are supported:
189+
* `attr-invalid-type`: Attributes cannot have sequences, records, nor dictionaries.
189190
* `dict-arg-default`: Optional dictionary type arguments must have a default value of `{}`.
190191
* `dict-arg-optional`: Dictionary type arguments must be optional if the type does not include a required field.
191192
* `no-nullable-dict-arg`: Dictionary arguments cannot be nullable.

lib/productions/attribute.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { validationError } from "../error.js";
2+
import { idlTypeIncludesDictionary } from "../validators/helpers.js";
13
import { Base } from "./base.js";
24
import { type_with_extended_attributes, unescape, autoParenter } from "./helpers.js";
35

@@ -25,10 +27,6 @@ export class Attribute extends Base {
2527
return;
2628
}
2729
ret.idlType = type_with_extended_attributes(tokeniser, "attribute-type") || tokeniser.error("Attribute lacks a type");
28-
switch (ret.idlType.generic) {
29-
case "sequence":
30-
case "record": tokeniser.error(`Attributes cannot accept ${ret.idlType.generic} types`);
31-
}
3230
tokens.name = tokeniser.consume("identifier", "async", "required") || tokeniser.error("Attribute lacks a name");
3331
tokens.termination = tokeniser.consume(";") || tokeniser.error("Unterminated attribute, expected `;`");
3432
return ret.this;
@@ -53,5 +51,22 @@ export class Attribute extends Base {
5351
*validate(defs) {
5452
yield* this.extAttrs.validate(defs);
5553
yield* this.idlType.validate(defs);
54+
55+
switch (this.idlType.generic) {
56+
case "sequence":
57+
case "record": {
58+
const message = `Attributes cannot accept ${this.idlType.generic} types.`;
59+
yield validationError(this.tokens.name, this, "attr-invalid-type", message);
60+
break;
61+
}
62+
default: {
63+
const { reference } = idlTypeIncludesDictionary(this.idlType, defs) || {};
64+
if (reference) {
65+
const targetToken = (this.union ? reference : this).tokens.base;
66+
const message = "Attributes cannot accept dictionary types.";
67+
yield validationError(targetToken, this, "attr-invalid-type", message);
68+
}
69+
}
70+
}
5671
}
5772
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(attr-invalid-type) Validation error at line 3 in invalid-attribute.webidl, inside `interface sequenceAsAttribute -> attribute invalid`:
2+
attribute sequence<short> invalid;
3+
^ Attributes cannot accept sequence types.
4+
(attr-invalid-type) Validation error at line 9 in invalid-attribute.webidl, inside `interface recordAsAttribute -> attribute invalid`:
5+
<DOMString, DOMString> invalid;
6+
^ Attributes cannot accept record types.
7+
(attr-invalid-type) Validation error at line 17 in invalid-attribute.webidl, inside `interface dictionaryAsAttribute -> attribute dict`:
8+
attribute Dict dict;
9+
^ Attributes cannot accept dictionary types.
10+
(attr-invalid-type) Validation error at line 18 in invalid-attribute.webidl, inside `interface dictionaryAsAttribute -> attribute dictUnion`:
11+
attribute (Dict or boolean
12+
^ Attributes cannot accept dictionary types.

test/invalid/baseline/nullable-union-dictionary.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ boolean or Dict)? arg);
2828
(no-nullable-union-dict) Validation error at line 21 in nullable-union-dictionary.webidl:
2929
attribute (boolean or Dict)? attr;
3030
^ Nullable union cannot include a dictionary type.
31+
(attr-invalid-type) Validation error at line 21 in nullable-union-dictionary.webidl, inside `interface Interface -> attribute attr`:
32+
attribute (boolean or Dict
33+
^ Attributes cannot accept dictionary types.
3134
(no-nullable-union-dict) Validation error at line 23 in nullable-union-dictionary.webidl:
3235
iterable<(boolean or Dict)?>;
3336
^ Nullable union cannot include a dictionary type.

test/invalid/baseline/sequenceAsAttribute.txt

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[Exposed=Window]
2+
interface sequenceAsAttribute {
3+
attribute sequence<short> invalid;
4+
attribute (sequence<short> or boolean) invalidUnion; // TODO
5+
};
6+
7+
[Exposed=Window]
8+
interface recordAsAttribute {
9+
attribute record<DOMString, DOMString> invalid;
10+
attribute (record<DOMString, DOMString> or boolean) invalidUnion; // TODO
11+
};
12+
13+
dictionary Dict {};
14+
15+
[Exposed=Window]
16+
interface dictionaryAsAttribute {
17+
attribute Dict dict;
18+
attribute (Dict or boolean) dictUnion;
19+
};

test/invalid/idl/sequenceAsAttribute.webidl

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)