Index: src/mirror-debugger.js |
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js |
index b13b3fa8b2457f28ab0e0c7be00ff5547f943ac3..c36d6fd720b7bf1096de432cd180b797a0d77ad8 100644 |
--- a/src/mirror-debugger.js |
+++ b/src/mirror-debugger.js |
@@ -87,6 +87,8 @@ function MakeMirror(value, opt_transient) { |
mirror = new SetMirror(value); |
} else if (ObjectIsPromise(value)) { |
mirror = new PromiseMirror(value); |
+ } else if (IS_GENERATOR(value)) { |
+ mirror = new GeneratorMirror(value); |
} else { |
mirror = new ObjectMirror(value, OBJECT_TYPE, opt_transient); |
} |
@@ -161,6 +163,7 @@ var SCOPE_TYPE = 'scope'; |
var PROMISE_TYPE = 'promise'; |
var MAP_TYPE = 'map'; |
var SET_TYPE = 'set'; |
+var GENERATOR_TYPE = 'generator'; |
// Maximum length when sending strings through the JSON protocol. |
var kMaxProtocolStringLength = 80; |
@@ -214,6 +217,7 @@ var ScopeType = { Global: 0, |
// - PromiseMirror |
// - MapMirror |
// - SetMirror |
+// - GeneratorMirror |
// - PropertyMirror |
// - InternalPropertyMirror |
// - FrameMirror |
@@ -371,6 +375,15 @@ Mirror.prototype.isPromise = function() { |
/** |
+ * Check whether the mirror reflects a generator object. |
+ * @returns {boolean} True if the mirror reflects a generator object |
+ */ |
+Mirror.prototype.isGenerator = function() { |
+ return this instanceof GeneratorMirror; |
+}; |
+ |
+ |
+/** |
* Check whether the mirror reflects a property. |
* @returns {boolean} True if the mirror reflects a property |
*/ |
@@ -986,8 +999,8 @@ FunctionMirror.prototype.script = function() { |
* @return {Number or undefined} in-script position for the function |
*/ |
FunctionMirror.prototype.sourcePosition_ = function() { |
- // Return script if function is resolved. Otherwise just fall through |
- // to return undefined. |
+ // Return position if function is resolved. Otherwise just fall |
+ // through to return undefined. |
if (this.resolved()) { |
return %FunctionGetScriptSourcePosition(this.value_); |
} |
@@ -1352,6 +1365,66 @@ SetMirror.prototype.values = function() { |
/** |
+ * Mirror object for a Generator object. |
+ * @param {Object} data The Generator object |
+ * @constructor |
+ * @extends Mirror |
+ */ |
+function GeneratorMirror(value) { |
+ %_CallFunction(this, value, GENERATOR_TYPE, ObjectMirror); |
+} |
+inherits(GeneratorMirror, ObjectMirror); |
+ |
+ |
+GeneratorMirror.prototype.status = function() { |
+ var continuation = %GeneratorGetContinuation(this.value_); |
+ if (continuation < 0) return "running"; |
+ if (continuation == 0) return "closed"; |
+ return "suspended"; |
+}; |
+ |
+ |
+GeneratorMirror.prototype.sourcePosition_ = function() { |
+ return %GeneratorGetSourcePosition(this.value_); |
+}; |
+ |
+ |
+GeneratorMirror.prototype.sourceLocation = function() { |
+ var pos = this.sourcePosition_(); |
+ if (!IS_UNDEFINED(pos)) { |
+ var script = this.func().script(); |
+ if (script) { |
+ return script.locationFromPosition(pos, true); |
+ } |
+ } |
+}; |
+ |
+ |
+GeneratorMirror.prototype.func = function() { |
+ if (!this.func_) { |
+ this.func_ = MakeMirror(%GeneratorGetFunction(this.value_)); |
+ } |
+ return this.func_; |
+}; |
+ |
+ |
+GeneratorMirror.prototype.context = function() { |
+ if (!this.context_) { |
+ this.context_ = new ContextMirror(%GeneratorGetContext(this.value_)); |
+ } |
+ return this.context_; |
+}; |
+ |
+ |
+GeneratorMirror.prototype.receiver = function() { |
+ if (!this.receiver_) { |
+ this.receiver_ = MakeMirror(%GeneratorGetReceiver(this.value_)); |
+ } |
+ return this.receiver_; |
+}; |
+ |
+ |
+/** |
* Base mirror object for properties. |
* @param {ObjectMirror} mirror The mirror object having this property |
* @param {string} name The name of the property |
@@ -2539,6 +2612,7 @@ JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference, |
case ERROR_TYPE: |
case REGEXP_TYPE: |
case PROMISE_TYPE: |
+ case GENERATOR_TYPE: |
// Add object representation. |
this.serializeObject_(mirror, content, details); |
break; |
@@ -2668,6 +2742,21 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content, |
} |
} |
+ if (mirror.isGenerator()) { |
+ // Add generator specific properties. |
+ |
+ // Either 'running', 'closed', or 'suspended'. |
+ content.status = mirror.status(); |
+ |
+ content.func = this.serializeReference(mirror.func()) |
+ content.receiver = this.serializeReference(mirror.receiver()) |
+ |
+ // If the generator is suspended, the content add line/column properties. |
+ serializeLocationFields(mirror.sourceLocation(), content); |
+ |
+ // TODO(wingo): Also serialize a reference to the context (scope chain). |
+ } |
+ |
if (mirror.isDate()) { |
// Add date specific properties. |
content.value = mirror.value(); |