aboutsummaryrefslogtreecommitdiffstats
path: root/third_party/WebIDL/like-as-iterable.patch
blob: 4ba3c3628ed759360a60bdc0b179a41a81f7ead5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
diff --git a/third_party/WebIDL/WebIDL.py b/third_party/WebIDL/WebIDL.py
index 2366e3f702..e1d973f5fe 100644
--- a/third_party/WebIDL/WebIDL.py
+++ b/third_party/WebIDL/WebIDL.py
@@ -9022,6 +9022,67 @@ class Parser(Tokenizer):
                     itr_iface.asyncIterableInterface = iface
                 self._productions.append(itr_iface)
                 iterable.iteratorType = IDLWrapperType(iface.location, itr_iface)
+            if not iterable:
+                # We haven't run finish() on the interface yet, so we don't know
+                # whether our interface is maplike/setlike/iterable or not. This
+                # means we have to loop through the members to see if we have an
+                # iterable member.
+                for m in iface.members:
+                    if isinstance(m, IDLMaplikeOrSetlike):
+                        iterable = m
+                        break
+                if iterable and (iterable.isSetlike() or iterable.isMaplike()):
+
+                    def simpleExtendedAttr(str):
+                        return IDLExtendedAttribute(iface.location, (str,))
+
+                    if isinstance(iterable, IDLAsyncIterable):
+                        nextReturnType = IDLPromiseType(
+                            iterable.location, BuiltinTypes[IDLBuiltinType.Types.any]
+                        )
+                    else:
+                        nextReturnType = BuiltinTypes[IDLBuiltinType.Types.object]
+                    nextMethod = IDLMethod(
+                        iterable.location,
+                        IDLUnresolvedIdentifier(iterable.location, "next"),
+                        nextReturnType,
+                        [],
+                    )
+                    nextMethod.addExtendedAttributes([simpleExtendedAttr("Throws")])
+
+                    methods = [nextMethod]
+
+                    if iterable.isSetlike():
+                        itr_suffix = "Setlike"
+                    else:
+                        itr_suffix = "Maplike"
+                    itr_ident = IDLUnresolvedIdentifier(
+                        iface.location, iface.identifier.name + itr_suffix
+                    )
+                    classNameOverride = iface.identifier.name + " " + itr_suffix
+                    itr_iface = IDLInterface(
+                        iface.location,
+                        self.globalScope(),
+                        itr_ident,
+                        None,
+                        methods,
+                        isKnownNonPartial=True,
+                        classNameOverride=classNameOverride,
+                    )
+                    itr_iface.addExtendedAttributes(
+                        [simpleExtendedAttr("LegacyNoInterfaceObject")]
+                    )
+                    # Make sure the exposure set for the iterator interface is the
+                    # same as the exposure set for the iterable interface, because
+                    # we're going to generate methods on the iterable that return
+                    # instances of the iterator.
+                    itr_iface._exposureGlobalNames = set(iface._exposureGlobalNames)
+                    # Always append generated iterable interfaces after the
+                    # interface they're a member of, otherwise nativeType generation
+                    # won't work correctly.
+                    itr_iface.iterableInterface = iface
+                    self._productions.append(itr_iface)
+                    iterable.iteratorType = IDLWrapperType(iface.location, itr_iface)
 
         # Make sure we finish IDLIncludesStatements before we finish the
         # IDLInterfaces.