Bug 1451021 - Migrate PropertyIteratorActor to protocol.js; r=ochameau. draft
authorNicolas Chevobbe <nchevobbe@mozilla.com>
Tue, 10 Apr 2018 09:44:38 +0200
changeset 783780 0822c4d3033ab3cd97f7b4793f77565ea17f9706
parent 783549 f94b64e0020225c71701930f193bd96c3ad1d150
push id106774
push userbmo:nchevobbe@mozilla.com
push dateTue, 17 Apr 2018 17:22:15 +0000
reviewersochameau
bugs1451021
milestone61.0a1
Bug 1451021 - Migrate PropertyIteratorActor to protocol.js; r=ochameau. MozReview-Commit-ID: 1yTtcO92HWU
devtools/server/actors/object.js
devtools/server/actors/object/property-iterator.js
devtools/shared/specs/index.js
devtools/shared/specs/moz.build
devtools/shared/specs/property-iterator.js
--- a/devtools/server/actors/object.js
+++ b/devtools/server/actors/object.js
@@ -259,27 +259,27 @@ ObjectActor.prototype = {
    *
    * @param request object
    *        The protocol request object.
    */
   onEnumProperties: function(request) {
     let actor = new PropertyIteratorActor(this, request.options);
     this.registeredPool.addActor(actor);
     this.iterators.add(actor);
-    return { iterator: actor.grip() };
+    return { iterator: actor.form() };
   },
 
   /**
    * Creates an actor to iterate over entries of a Map/Set-like object.
    */
   onEnumEntries: function() {
     let actor = new PropertyIteratorActor(this, { enumEntries: true });
     this.registeredPool.addActor(actor);
     this.iterators.add(actor);
-    return { iterator: actor.grip() };
+    return { iterator: actor.form() };
   },
 
   /**
    * Creates an actor to iterate over an object symbols properties.
    */
   onEnumSymbols: function() {
     let actor = new SymbolIteratorActor(this);
     this.registeredPool.addActor(actor);
--- a/devtools/server/actors/object/property-iterator.js
+++ b/devtools/server/actors/object/property-iterator.js
@@ -3,16 +3,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { Cu } = require("chrome");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
+const protocol = require("devtools/shared/protocol");
+const { propertyIteratorSpec } = require("devtools/shared/specs/property-iterator");
 loader.lazyRequireGetter(this, "ChromeUtils");
 loader.lazyRequireGetter(this, "ObjectUtils", "devtools/server/actors/object/utils");
 
 /**
  * Creates an actor to iterate over an object's property names and values.
  *
  * @param objectActor ObjectActor
  *        The object actor.
@@ -32,53 +34,52 @@ loader.lazyRequireGetter(this, "ObjectUt
  *          If true, the iterator will sort the properties by name
  *          before dispatching them.
  *        - query String
  *          If non-empty, will filter the properties by names and values
  *          containing this query string. The match is not case-sensitive.
  *          Regarding value filtering it just compare to the stringification
  *          of the property value.
  */
-function PropertyIteratorActor(objectActor, options) {
-  if (!DevToolsUtils.isSafeDebuggerObject(objectActor.obj)) {
-    this.iterator = {
-      size: 0,
-      propertyName: index => undefined,
-      propertyDescription: index => undefined,
-    };
-  } else if (options.enumEntries) {
-    let cls = objectActor.obj.class;
-    if (cls == "Map") {
-      this.iterator = enumMapEntries(objectActor);
-    } else if (cls == "WeakMap") {
-      this.iterator = enumWeakMapEntries(objectActor);
-    } else if (cls == "Set") {
-      this.iterator = enumSetEntries(objectActor);
-    } else if (cls == "WeakSet") {
-      this.iterator = enumWeakSetEntries(objectActor);
+const PropertyIteratorActor  = protocol.ActorClassWithSpec(propertyIteratorSpec, {
+  initialize(objectActor, options) {
+    protocol.Actor.prototype.initialize.call(this);
+    if (!DevToolsUtils.isSafeDebuggerObject(objectActor.obj)) {
+      this.iterator = {
+        size: 0,
+        propertyName: index => undefined,
+        propertyDescription: index => undefined,
+      };
+    } else if (options.enumEntries) {
+      let cls = objectActor.obj.class;
+      if (cls == "Map") {
+        this.iterator = enumMapEntries(objectActor);
+      } else if (cls == "WeakMap") {
+        this.iterator = enumWeakMapEntries(objectActor);
+      } else if (cls == "Set") {
+        this.iterator = enumSetEntries(objectActor);
+      } else if (cls == "WeakSet") {
+        this.iterator = enumWeakSetEntries(objectActor);
+      } else {
+        throw new Error("Unsupported class to enumerate entries from: " + cls);
+      }
+    } else if (
+      ObjectUtils.isArray(objectActor.obj)
+      && options.ignoreNonIndexedProperties
+      && !options.query
+    ) {
+      this.iterator = enumArrayProperties(objectActor, options);
     } else {
-      throw new Error("Unsupported class to enumerate entries from: " + cls);
+      this.iterator = enumObjectProperties(objectActor, options);
     }
-  } else if (
-    ObjectUtils.isArray(objectActor.obj)
-    && options.ignoreNonIndexedProperties
-    && !options.query
-  ) {
-    this.iterator = enumArrayProperties(objectActor, options);
-  } else {
-    this.iterator = enumObjectProperties(objectActor, options);
-  }
-}
+  },
 
-PropertyIteratorActor.prototype = {
-  actorPrefix: "propertyIterator",
-
-  grip() {
+  form() {
     return {
-      type: this.actorPrefix,
+      type: this.typeName,
       actor: this.actorID,
       count: this.iterator.size
     };
   },
 
   names({ indexes }) {
     let list = [];
     for (let idx of indexes) {
@@ -90,31 +91,26 @@ PropertyIteratorActor.prototype = {
   },
 
   slice({ start, count }) {
     let ownProperties = Object.create(null);
     for (let i = start, m = start + count; i < m; i++) {
       let name = this.iterator.propertyName(i);
       ownProperties[name] = this.iterator.propertyDescription(i);
     }
+
     return {
       ownProperties
     };
   },
 
   all() {
     return this.slice({ start: 0, count: this.iterator.size });
   }
-};
-
-PropertyIteratorActor.prototype.requestTypes = {
-  "names": PropertyIteratorActor.prototype.names,
-  "slice": PropertyIteratorActor.prototype.slice,
-  "all": PropertyIteratorActor.prototype.all,
-};
+});
 
 /**
  * Helper function to create a grip from a Map/Set entry
  */
 function gripFromEntry({ obj, hooks }, entry) {
   return hooks.createValueGrip(
     ObjectUtils.makeDebuggeeValueIfNeeded(obj, Cu.unwaiveXrays(entry)));
 }
--- a/devtools/shared/specs/index.js
+++ b/devtools/shared/specs/index.js
@@ -148,16 +148,21 @@ const Types = exports.__TypesForTests = 
     front: "devtools/shared/fronts/preference",
   },
   {
     types: ["promises"],
     spec: "devtools/shared/specs/promises",
     front: "devtools/shared/fronts/promises",
   },
   {
+    types: ["propertyIterator"],
+    spec: "devtools/shared/specs/property-iterator",
+    front: null,
+  },
+  {
     types: ["reflow"],
     spec: "devtools/shared/specs/reflow",
     front: "devtools/shared/fronts/reflow",
   },
   /* Script and source have old fashion client and no front */
   {
     types: ["context"],
     spec: "devtools/shared/specs/script",
--- a/devtools/shared/specs/moz.build
+++ b/devtools/shared/specs/moz.build
@@ -27,16 +27,17 @@ DevToolsModules(
     'layout.js',
     'memory.js',
     'node.js',
     'perf.js',
     'performance-recording.js',
     'performance.js',
     'preference.js',
     'promises.js',
+    'property-iterator.js',
     'reflow.js',
     'script.js',
     'source.js',
     'storage.js',
     'string.js',
     'styles.js',
     'stylesheets.js',
     'symbol-iterator.js',
new file mode 100644
--- /dev/null
+++ b/devtools/shared/specs/property-iterator.js
@@ -0,0 +1,42 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {
+  generateActorSpec,
+  Option,
+  RetVal,
+  types,
+} = require("devtools/shared/protocol");
+
+types.addDictType("propertyiterator.data", {
+  ownProperties: "nullable:json",
+});
+
+const propertyIteratorSpec = generateActorSpec({
+  typeName: "propertyIterator",
+
+  methods: {
+    names: {
+      request: {
+        indexes: Option(0, "array:number"),
+      },
+      response: RetVal("array:string")
+    },
+    slice: {
+      request: {
+        start: Option(0, "number"),
+        count: Option(0, "number"),
+      },
+      response: RetVal("propertyiterator.data")
+    },
+    all: {
+      request: {},
+      response: RetVal("propertyiterator.data")
+    },
+  }
+});
+
+exports.propertyIteratorSpec = propertyIteratorSpec;