[idlharness.js] Let get_reverse_inheritance_stack() do the reversing (#28688)

As suggested by Ms2ger in https://github.com/web-platform-tests/wpt/pull/28650#discussion_r620065161
diff --git a/resources/idlharness.js b/resources/idlharness.js
index 3422d6e..eda7325 100644
--- a/resources/idlharness.js
+++ b/resources/idlharness.js
@@ -581,13 +581,11 @@
 
            //  dictionaries where all of their members are JSON types
            if (thing instanceof IdlDictionary) {
-               var stack = thing.get_inheritance_stack();
-               var map = new Map();
-               while (stack.length)
-               {
-                   stack.pop().members.forEach(function(m) {
-                       map.set(m.name, m.idlType)
-                   });
+               const map = new Map();
+               for (const dict of thing.get_reverse_inheritance_stack()) {
+                   for (const m of dict.members) {
+                       map.set(m.name, m.idlType);
+                   }
                }
                return Array.from(map.values()).every(this.is_json_type, this);
            }
@@ -715,7 +713,7 @@
             if (!rhs_is_interface) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is not an interface.`);
         }
         // Check for circular dependencies.
-        member.get_inheritance_stack();
+        member.get_reverse_inheritance_stack();
     }
 
     Object.getOwnPropertyNames(this.members).forEach(function(memberName) {
@@ -1176,8 +1174,8 @@
 
 IdlDictionary.prototype = Object.create(IdlObject.prototype);
 
-IdlDictionary.prototype.get_inheritance_stack = function() {
-    return IdlInterface.prototype.get_inheritance_stack.call(this);
+IdlDictionary.prototype.get_reverse_inheritance_stack = function() {
+    return IdlInterface.prototype.get_reverse_inheritance_stack.call(this);
 };
 
 /// IdlInterface ///
@@ -1319,39 +1317,39 @@
     });
 };
 
-IdlInterface.prototype.get_inheritance_stack = function() {
-    /**
-     * See https://heycam.github.io/webidl/#create-an-inheritance-stack
-     *
-     * Returns an array of IdlInterface objects which contains itself
-     * and all of its inherited interfaces.
-     *
-     * So given:
-     *
-     *   A : B {};
-     *   B : C {};
-     *   C {};
-     *
-     * then A.get_inheritance_stack() should return [A, B, C],
-     * and B.get_inheritance_stack() should return [B, C].
-     *
-     * Note: as dictionary inheritance is expressed identically by the AST,
-     * this works just as well for getting a stack of inherited dictionaries.
-     */
-
-    var stack = [this];
-    var idl_interface = this;
+/**
+ * Implementation of https://heycam.github.io/webidl/#create-an-inheritance-stack
+ * with the order reversed.
+ *
+ * The order is reversed so that the base class comes first in the list, because
+ * this is what all call sites need.
+ *
+ * So given:
+ *
+ *   A : B {};
+ *   B : C {};
+ *   C {};
+ *
+ * then A.get_reverse_inheritance_stack() returns [C, B, A],
+ * and B.get_reverse_inheritance_stack() returns [C, B].
+ *
+ * Note: as dictionary inheritance is expressed identically by the AST,
+ * this works just as well for getting a stack of inherited dictionaries.
+ */
+IdlInterface.prototype.get_reverse_inheritance_stack = function() {
+    const stack = [this];
+    let idl_interface = this;
     while (idl_interface.base) {
-        var base = this.array.members[idl_interface.base];
+        const base = this.array.members[idl_interface.base];
         if (!base) {
             throw new Error(idl_interface.type + " " + idl_interface.base + " not found (inherited by " + idl_interface.name + ")");
         } else if (stack.indexOf(base) > -1) {
-            stack.push(base);
-            let dep_chain = stack.map(i => i.name).join(',');
+            stack.unshift(base);
+            const dep_chain = stack.map(i => i.name).join(',');
             throw new IdlHarnessError(`${this.name} has a circular dependency: ${dep_chain}`);
         }
         idl_interface = base;
-        stack.push(idl_interface);
+        stack.unshift(idl_interface);
     }
     return stack;
 };
@@ -1366,19 +1364,20 @@
  * comparison with actual value
  */
 IdlInterface.prototype.default_to_json_operation = function() {
-    var map = new Map(), isDefault = false;
-    this.get_inheritance_stack().reverse().forEach(function(I) {
+    const map = new Map()
+    let isDefault = false;
+    for (const I of this.get_reverse_inheritance_stack()) {
         if (I.has_default_to_json_regular_operation()) {
             isDefault = true;
-            I.members.forEach(function(m) {
+            for (const m of I.members) {
                 if (m.special !== "static" && m.type == "attribute" && I.array.is_json_type(m.idlType)) {
                     map.set(m.name, m.idlType);
                 }
-            });
+            }
         } else if (I.has_to_json_regular_operation()) {
             isDefault = false;
         }
-    });
+    }
     return isDefault ? map : null;
 };
 
diff --git a/resources/test/tests/unit/IdlDictionary/get_inheritance_stack.html b/resources/test/tests/unit/IdlDictionary/get_reverse_inheritance_stack.html
similarity index 77%
rename from resources/test/tests/unit/IdlDictionary/get_inheritance_stack.html
rename to resources/test/tests/unit/IdlDictionary/get_reverse_inheritance_stack.html
index 052592d..418bcde 100644
--- a/resources/test/tests/unit/IdlDictionary/get_inheritance_stack.html
+++ b/resources/test/tests/unit/IdlDictionary/get_reverse_inheritance_stack.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML>
 <html>
 <head>
-<title>IdlDictionary.prototype.get_inheritance_stack()</title>
+<title>IdlDictionary.prototype.get_reverse_inheritance_stack()</title>
 </head>
 <body>
 <div id="log"></div>
@@ -13,13 +13,13 @@
 <script>
     "use strict";
     test(function() {
-        var stack = dictionaryFrom('dictionary A { };').get_inheritance_stack();
+        var stack = dictionaryFrom('dictionary A { };').get_reverse_inheritance_stack();
         assert_array_equals(stack.map(d => d.name), ["A"]);
     }, 'should return an array that includes itself.');
 
     test(function() {
         var d = dictionaryFrom('dictionary A : B { };');
-        assert_throws_js(Error, _ => d.get_inheritance_stack());
+        assert_throws_js(Error, _ => d.get_reverse_inheritance_stack());
     }, "should throw for dictionaries which inherit from another dictionary which wasn't added to the IdlArray");
 
     test(function() {
@@ -27,8 +27,8 @@
         idl.add_idls('dictionary A : B { };');
         idl.add_untested_idls('dictionary B : C { }; dictionary C { };');
         var A = idl.members["A"];
-        assert_array_equals(A.get_inheritance_stack().map(d => d.name), ["A", "B", "C"]);
-    }, 'should return an array of inherited dictionaries in order of inheritance, starting with itself.');
+        assert_array_equals(A.get_reverse_inheritance_stack().map(d => d.name), ["C", "B", "A"]);
+    }, 'should return an array of dictionaries in order of inheritance, starting with the base dictionary');
 
     test(function () {
       let i = new IdlArray();
diff --git a/resources/test/tests/unit/IdlInterface/get_inheritance_stack.html b/resources/test/tests/unit/IdlInterface/get_reverse_inheritance_stack.html
similarity index 77%
rename from resources/test/tests/unit/IdlInterface/get_inheritance_stack.html
rename to resources/test/tests/unit/IdlInterface/get_reverse_inheritance_stack.html
index 7e9188c..0c066ba 100644
--- a/resources/test/tests/unit/IdlInterface/get_inheritance_stack.html
+++ b/resources/test/tests/unit/IdlInterface/get_reverse_inheritance_stack.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML>
 <html>
 <head>
-<title>IdlInterface.prototype.get_inheritance_stack()</title>
+<title>IdlInterface.prototype.get_reverse_inheritance_stack()</title>
 </head>
 <body>
 <div id="log"></div>
@@ -13,13 +13,13 @@
 <script>
     "use strict";
     test(function() {
-        var stack = interfaceFrom('interface A { };').get_inheritance_stack();
+        var stack = interfaceFrom('interface A { };').get_reverse_inheritance_stack();
         assert_array_equals(stack.map(i => i.name), ["A"]);
     }, 'should return an array that includes itself.');
 
     test(function() {
         var i = interfaceFrom('interface A : B { };');
-        assert_throws_js(Error, _ => i.get_inheritance_stack());
+        assert_throws_js(Error, _ => i.get_reverse_inheritance_stack());
     }, "should throw for interfaces which inherit from another interface which wasn't added to the IdlArray");
 
     test(function() {
@@ -27,8 +27,8 @@
         idl.add_idls('interface A : B { };');
         idl.add_untested_idls('interface B : C { }; interface C { };');
         var A = idl.members["A"];
-        assert_array_equals(A.get_inheritance_stack().map(i => i.name), ["A", "B", "C"]);
-    }, 'should return an array of inherited interfaces in order of inheritance, starting with itself.');
+        assert_array_equals(A.get_reverse_inheritance_stack().map(i => i.name), ["C", "B", "A"]);
+    }, 'should return an array of interfaces in order of inheritance, starting with the base interface');
 
     test(function () {
         var idl = new IdlArray();