Commit 60cb58ea authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Factored the generation of JSON serialization from beeing part of the mirror...

Factored the generation of JSON serialization from beeing part of the mirror objects into a seperate class. The purpose of this is to make it easier to change the serialization to contain object identification and references.

Added a test case for the script mirror and modified a number of the other mirror tests.
Review URL: http://codereview.chromium.org/16539

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1035 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0d22bce3
...@@ -33,6 +33,12 @@ RegExp; ...@@ -33,6 +33,12 @@ RegExp;
Date; Date;
/**
* Returns the mirror for a specified value or object.
*
* @param {value or Object} value the value or object to retreive the mirror for
* @returns {Mirror} the mirror reflects the passed value or object
*/
function MakeMirror(value) { function MakeMirror(value) {
if (IS_UNDEFINED(value)) return new UndefinedMirror(); if (IS_UNDEFINED(value)) return new UndefinedMirror();
if (IS_NULL(value)) return new NullMirror(); if (IS_NULL(value)) return new NullMirror();
...@@ -106,7 +112,6 @@ PropertyType.ConstantTransition = 6; ...@@ -106,7 +112,6 @@ PropertyType.ConstantTransition = 6;
PropertyType.NullDescriptor = 7; PropertyType.NullDescriptor = 7;
// Different attributes for a property. // Different attributes for a property.
PropertyAttribute = {}; PropertyAttribute = {};
PropertyAttribute.None = NONE; PropertyAttribute.None = NONE;
...@@ -123,12 +128,12 @@ PropertyAttribute.DontDelete = DONT_DELETE; ...@@ -123,12 +128,12 @@ PropertyAttribute.DontDelete = DONT_DELETE;
// - NumberMirror // - NumberMirror
// - StringMirror // - StringMirror
// - ObjectMirror // - ObjectMirror
// - FunctionMirror // - FunctionMirror
// - UnresolvedFunctionMirror // - UnresolvedFunctionMirror
// - ArrayMirror // - ArrayMirror
// - DateMirror // - DateMirror
// - RegExpMirror // - RegExpMirror
// - ErrorMirror // - ErrorMirror
// - PropertyMirror // - PropertyMirror
// - InterceptorPropertyMirror // - InterceptorPropertyMirror
// - AccessorMirror // - AccessorMirror
...@@ -296,29 +301,24 @@ Mirror.prototype.isFrame = function() { ...@@ -296,29 +301,24 @@ Mirror.prototype.isFrame = function() {
} }
Mirror.prototype.fillJSONType_ = function(content) { /**
content.push(MakeJSONPair_('type', StringToJSON_(this.type()))); * Check whether the mirror reflects a script.
}; * @returns {boolean} True if the mirror reflects a script
*/
Mirror.prototype.isScript = function() {
Mirror.prototype.fillJSON_ = function(content) { return this instanceof ScriptMirror;
this.fillJSONType_(content); }
};
/** /**
* Serialize object in JSON format. For the basic mirrors this includes only * Serialize object in JSON format. The actual serialization is handled by the
* the type in the following format. * JSONProtocolSerializer.
* {"type":"<type name>"}
* For specialized mirrors inheriting from the base Mirror
* @param {boolean} details Indicate level of details to include * @param {boolean} details Indicate level of details to include
* @return {string} JSON serialization * @return {string} JSON serialization
*/ */
Mirror.prototype.toJSONProtocol = function(details, propertiesKind, interceptorPropertiesKind) { Mirror.prototype.toJSONProtocol = function(details) {
var content = new Array(); var serializer = new JSONProtocolSerializer(details)
this.fillJSON_(content, details, propertiesKind, interceptorPropertiesKind); return serializer.serialize(this)
content.push(MakeJSONPair_('text', StringToJSON_(this.toText())));
return ArrayToJSONObject_(content);
} }
...@@ -409,12 +409,6 @@ function BooleanMirror(value) { ...@@ -409,12 +409,6 @@ function BooleanMirror(value) {
inherits(BooleanMirror, ValueMirror); inherits(BooleanMirror, ValueMirror);
BooleanMirror.prototype.fillJSON_ = function(content, details) {
BooleanMirror.super_.fillJSONType_.call(this, content);
content.push(MakeJSONPair_('value', BooleanToJSON_(this.value_)));
}
BooleanMirror.prototype.toText = function() { BooleanMirror.prototype.toText = function() {
return this.value_ ? 'true' : 'false'; return this.value_ ? 'true' : 'false';
} }
...@@ -432,12 +426,6 @@ function NumberMirror(value) { ...@@ -432,12 +426,6 @@ function NumberMirror(value) {
inherits(NumberMirror, ValueMirror); inherits(NumberMirror, ValueMirror);
NumberMirror.prototype.fillJSON_ = function(content, details) {
NumberMirror.super_.fillJSONType_.call(this, content);
content.push(MakeJSONPair_('value', NumberToJSON_(this.value_)));
}
NumberMirror.prototype.toText = function() { NumberMirror.prototype.toText = function() {
return %NumberToString(this.value_); return %NumberToString(this.value_);
} }
...@@ -460,21 +448,6 @@ StringMirror.prototype.length = function() { ...@@ -460,21 +448,6 @@ StringMirror.prototype.length = function() {
}; };
StringMirror.prototype.fillJSON_ = function(content, details) {
StringMirror.super_.fillJSONType_.call(this, content);
content.push(MakeJSONPair_('length', NumberToJSON_(this.length())));
if (this.length() > kMaxProtocolStringLength) {
content.push(MakeJSONPair_('fromIndex', NumberToJSON_(0)));
content.push(MakeJSONPair_('toIndex',
NumberToJSON_(kMaxProtocolStringLength)));
var str = this.value_.substring(0, kMaxProtocolStringLength);
content.push(MakeJSONPair_('value', StringToJSON_(str)));
} else {
content.push(MakeJSONPair_('value', StringToJSON_(this.value_)));
}
}
StringMirror.prototype.toText = function() { StringMirror.prototype.toText = function() {
if (this.length() > kMaxProtocolStringLength) { if (this.length() > kMaxProtocolStringLength) {
return this.value_.substring(0, kMaxProtocolStringLength) + return this.value_.substring(0, kMaxProtocolStringLength) +
...@@ -738,49 +711,6 @@ ObjectMirror.prototype.referencedBy = function(opt_max_instances) { ...@@ -738,49 +711,6 @@ ObjectMirror.prototype.referencedBy = function(opt_max_instances) {
}; };
ObjectMirror.prototype.fillJSONProperties_ = function(content, kind, name, details) {
var propertyNames = this.propertyNames(kind);
var x = new Array(propertyNames.length);
for (var i = 0; i < propertyNames.length; i++) {
x[i] = this.property(propertyNames[i]).toJSONProtocol(details);
}
content.push(MakeJSONPair_(name || 'properties', ArrayToJSONArray_(x)));
};
ObjectMirror.prototype.fillJSONInterceptorProperties_ = function(content, kind, name, details) {
var propertyNames = this.interceptorPropertyNames(kind);
var x = new Array(propertyNames.length);
for (var i = 0; i < propertyNames.length; i++) {
x[i] = properties[i].toJSONProtocol(details);
}
content.push(MakeJSONPair_(name || 'interceptorProperties', ArrayToJSONArray_(x)));
};
ObjectMirror.prototype.fillJSON_ = function(content, details, propertiesKind, interceptorPropertiesKind) {
ObjectMirror.super_.fillJSONType_.call(this, content);
content.push(MakeJSONPair_('className', StringToJSON_(this.className())));
if (details) {
content.push(MakeJSONPair_('constructorFunction', this.constructorFunction().toJSONProtocol(false)));
content.push(MakeJSONPair_('protoObject', this.protoObject().toJSONProtocol(false)));
content.push(MakeJSONPair_('prototypeObject', this.prototypeObject().toJSONProtocol(false)));
}
if (details) {
this.fillJSONProperties_(content, propertiesKind)
if (interceptorPropertiesKind) {
this.fillJSONInterceptorProperties_(content, interceptorPropertiesKind)
}
}
if (this.hasNamedInterceptor()) {
content.push(MakeJSONPair_('namedInterceptor', BooleanToJSON_(true)));
}
if (this.hasIndexedInterceptor()) {
content.push(MakeJSONPair_('indexedInterceptor', BooleanToJSON_(true)));
}
};
ObjectMirror.prototype.toText = function() { ObjectMirror.prototype.toText = function() {
var name; var name;
var ctor = this.constructorFunction(); var ctor = this.constructorFunction();
...@@ -884,21 +814,6 @@ FunctionMirror.prototype.constructedBy = function(opt_max_instances) { ...@@ -884,21 +814,6 @@ FunctionMirror.prototype.constructedBy = function(opt_max_instances) {
}; };
FunctionMirror.prototype.fillJSON_ = function(content, details) {
// Fill JSON properties from parent (ObjectMirror).
FunctionMirror.super_.fillJSON_.call(this, content, details);
// Add function specific properties.
content.push(MakeJSONPair_('name', StringToJSON_(this.name())));
content.push(MakeJSONPair_('resolved', BooleanToJSON_(this.resolved())));
if (details && this.resolved()) {
content.push(MakeJSONPair_('source', StringToJSON_(this.source())));
}
if (this.script()) {
content.push(MakeJSONPair_('script', this.script().toJSONProtocol()));
}
}
FunctionMirror.prototype.toText = function() { FunctionMirror.prototype.toText = function() {
return this.source(); return this.source();
} }
...@@ -988,18 +903,6 @@ ArrayMirror.prototype.indexedPropertiesFromRange = function(opt_from_index, opt_ ...@@ -988,18 +903,6 @@ ArrayMirror.prototype.indexedPropertiesFromRange = function(opt_from_index, opt_
} }
ArrayMirror.prototype.fillJSON_ = function(content, details) {
// Fill JSON as for parent (ObjectMirror) but just with named properties.
ArrayMirror.super_.fillJSON_.call(this, content, details, PropertyKind.Named);
// Fill indexed properties seperately.
if (details) {
this.fillJSONProperties_(content, PropertyKind.Indexed, 'indexedProperties')
}
// Add the array length.
content.push(MakeJSONPair_('length', NumberToJSON_(this.length())));
}
/** /**
* Mirror object for dates. * Mirror object for dates.
* @param {Date} value The Date object reflected by this mirror * @param {Date} value The Date object reflected by this mirror
...@@ -1012,14 +915,6 @@ function DateMirror(value) { ...@@ -1012,14 +915,6 @@ function DateMirror(value) {
inherits(DateMirror, ObjectMirror); inherits(DateMirror, ObjectMirror);
DateMirror.prototype.fillJSON_ = function(content, details) {
// Fill JSON properties from parent (ObjectMirror).
DateMirror.super_.fillJSON_.call(this, content, details);
// Add date specific properties.
content.push(MakeJSONPair_('value', DateToJSON_(this.value_)));
}
DateMirror.prototype.toText = function() { DateMirror.prototype.toText = function() {
return DateToISO8601_(this.value_); return DateToISO8601_(this.value_);
} }
...@@ -1073,17 +968,6 @@ RegExpMirror.prototype.multiline = function() { ...@@ -1073,17 +968,6 @@ RegExpMirror.prototype.multiline = function() {
}; };
RegExpMirror.prototype.fillJSON_ = function(content, details) {
// Fill JSON properties from parent (ObjectMirror).
RegExpMirror.super_.fillJSON_.call(this, content, details);
// Add regexp specific properties.
content.push(MakeJSONPair_('source', StringToJSON_(this.source())));
content.push(MakeJSONPair_('global', BooleanToJSON_(this.global())));
content.push(MakeJSONPair_('ignoreCase', BooleanToJSON_(this.ignoreCase())));
content.push(MakeJSONPair_('multiline', BooleanToJSON_(this.multiline())));
}
RegExpMirror.prototype.toText = function() { RegExpMirror.prototype.toText = function() {
// Simpel to text which is used when on specialization in subclass. // Simpel to text which is used when on specialization in subclass.
return "/" + this.source() + "/"; return "/" + this.source() + "/";
...@@ -1111,14 +995,6 @@ ErrorMirror.prototype.message = function() { ...@@ -1111,14 +995,6 @@ ErrorMirror.prototype.message = function() {
}; };
ErrorMirror.prototype.fillJSON_ = function(content, details) {
// Fill JSON properties from parent (ObjectMirror).
ErrorMirror.super_.fillJSON_.call(this, content, details);
// Add error specific properties.
content.push(MakeJSONPair_('message', StringToJSON_(this.message())));
}
ErrorMirror.prototype.toText = function() { ErrorMirror.prototype.toText = function() {
// Use the same text representation as in messages.js. // Use the same text representation as in messages.js.
var text; var text;
...@@ -1206,18 +1082,6 @@ PropertyMirror.prototype.insertionIndex = function() { ...@@ -1206,18 +1082,6 @@ PropertyMirror.prototype.insertionIndex = function() {
} }
PropertyMirror.prototype.fillJSON_ = function(content, details) {
content.push(MakeJSONPair_('name', StringToJSON_(this.name())));
content.push(MakeJSONPair_('value', this.value().toJSONProtocol(details)));
if (this.attributes() != PropertyAttribute.None) {
content.push(MakeJSONPair_('attributes', NumberToJSON_(this.attributes())));
}
if (this.propertyType() != PropertyType.Normal) {
content.push(MakeJSONPair_('propertyType', NumberToJSON_(this.propertyType())));
}
}
/** /**
* Mirror object for interceptor named properties. * Mirror object for interceptor named properties.
* @param {ObjectMirror} mirror The mirror object having this property * @param {ObjectMirror} mirror The mirror object having this property
...@@ -1278,28 +1142,6 @@ AccessorMirror.prototype.setter = function(details) { ...@@ -1278,28 +1142,6 @@ AccessorMirror.prototype.setter = function(details) {
} }
/**
* Serialize the accessor mirror into JSON format. For accessor it has the
* following format.
* {"type":"accessor",
"native:"<boolean>,
"getter":<function mirror JSON serialization>,
"setter":<function mirror JSON serialization>}
* For specialized mirrors inheriting from the base Mirror
* @param {boolean} details Indicate level of details to include
* @return {string} JSON serialization
*/
AccessorMirror.prototype.fillJSON_ = function(content, details) {
AccessorMirror.super_.fillJSONType_.call(this, content);
if (this.isNative()) {
content.push(MakeJSONPair_('native', BooleanToJSON_(true)));
} else {
content.push(MakeJSONPair_('getter', this.getter().toJSONProtocol(false)));
content.push(MakeJSONPair_('setter', this.setter().toJSONProtocol(false)));
}
}
const kFrameDetailsFrameIdIndex = 0; const kFrameDetailsFrameIdIndex = 0;
const kFrameDetailsReceiverIndex = 1; const kFrameDetailsReceiverIndex = 1;
const kFrameDetailsFunctionIndex = 2; const kFrameDetailsFunctionIndex = 2;
...@@ -1558,47 +1400,6 @@ FrameMirror.prototype.evaluate = function(source, disable_break) { ...@@ -1558,47 +1400,6 @@ FrameMirror.prototype.evaluate = function(source, disable_break) {
}; };
FrameMirror.prototype.fillJSON_ = function(content, details) {
FrameMirror.super_.fillJSONType_.call(this, content);
content.push(MakeJSONPair_('index', NumberToJSON_(this.index())));
content.push(MakeJSONPair_('receiver', this.receiver().toJSONProtocol(false)));
content.push(MakeJSONPair_('func', this.func().toJSONProtocol(false)));
content.push(MakeJSONPair_('constructCall', BooleanToJSON_(this.isConstructCall())));
content.push(MakeJSONPair_('debuggerFrame', BooleanToJSON_(this.isDebuggerFrame())));
var x = new Array(this.argumentCount());
for (var i = 0; i < this.argumentCount(); i++) {
arg = new Array();
var argument_name = this.argumentName(i)
if (argument_name) {
arg.push(MakeJSONPair_('name', StringToJSON_(argument_name)));
}
arg.push(MakeJSONPair_('value', this.argumentValue(i).toJSONProtocol(false)));
x[i] = ArrayToJSONObject_(arg);
}
content.push(MakeJSONPair_('arguments', ArrayToJSONArray_(x)));
var x = new Array(this.localCount());
for (var i = 0; i < this.localCount(); i++) {
var name = MakeJSONPair_('name', StringToJSON_(this.localName(i)));
var value = MakeJSONPair_('value', this.localValue(i).toJSONProtocol(false));
x[i] = '{' + name + ',' + value + '}';
}
content.push(MakeJSONPair_('locals', ArrayToJSONArray_(x)));
content.push(MakeJSONPair_('position', NumberToJSON_(this.sourcePosition())));
var line = this.sourceLine();
if (!IS_UNDEFINED(line)) {
content.push(MakeJSONPair_('line', NumberToJSON_(line)));
}
var column = this.sourceColumn();
if (!IS_UNDEFINED(column)) {
content.push(MakeJSONPair_('column', NumberToJSON_(column)));
}
var source_line_text = this.sourceLineText();
if (!IS_UNDEFINED(source_line_text)) {
content.push(MakeJSONPair_('sourceLineText', StringToJSON_(source_line_text)));
}
}
FrameMirror.prototype.invocationText = function() { FrameMirror.prototype.invocationText = function() {
// Format frame invoaction (receiver, function and arguments). // Format frame invoaction (receiver, function and arguments).
var result = ''; var result = '';
...@@ -1783,18 +1584,6 @@ ScriptMirror.prototype.sourceSlice = function (opt_from_line, opt_to_line) { ...@@ -1783,18 +1584,6 @@ ScriptMirror.prototype.sourceSlice = function (opt_from_line, opt_to_line) {
} }
ScriptMirror.prototype.fillJSON_ = function(content, details) {
ScriptMirror.super_.fillJSONType_.call(this, content);
if (this.name()) {
content.push(MakeJSONPair_('name', StringToJSON_(this.name())));
}
content.push(MakeJSONPair_('lineOffset', NumberToJSON_(this.lineOffset())));
content.push(MakeJSONPair_('columnOffset', NumberToJSON_(this.columnOffset())));
content.push(MakeJSONPair_('lineCount', NumberToJSON_(this.lineCount())));
content.push(MakeJSONPair_('scriptType', NumberToJSON_(this.scriptType())));
}
ScriptMirror.prototype.toText = function() { ScriptMirror.prototype.toText = function() {
var result = ''; var result = '';
result += this.name(); result += this.name();
...@@ -1811,6 +1600,244 @@ ScriptMirror.prototype.toText = function() { ...@@ -1811,6 +1600,244 @@ ScriptMirror.prototype.toText = function() {
} }
function JSONProtocolSerializer(details) {
this.details_ = details;
}
JSONProtocolSerializer.prototype.serialize = function(mirror) {
// Collect the JSON property/value pairs in a array.
var content = new Array();
// Always add the type
content.push(MakeJSONPair_('type', StringToJSON_(mirror.type())));
switch (mirror.type()) {
case UNDEFINED_TYPE:
case NULL_TYPE:
// Undefined and null are represented just by their type.
break;
case BOOLEAN_TYPE:
// Boolean values are simply represented by their value.
content.push(MakeJSONPair_('value', BooleanToJSON_(mirror.value())));
break;
case NUMBER_TYPE:
// Number values are simply represented by their value.
content.push(MakeJSONPair_('value', NumberToJSON_(mirror.value())));
break;
case STRING_TYPE:
// String values might have their value cropped to keep down size.
if (mirror.length() > kMaxProtocolStringLength) {
var str = mirror.value().substring(0, kMaxProtocolStringLength);
content.push(MakeJSONPair_('value', StringToJSON_(str)));
content.push(MakeJSONPair_('fromIndex', NumberToJSON_(0)));
content.push(MakeJSONPair_('toIndex',
NumberToJSON_(kMaxProtocolStringLength)));
} else {
content.push(MakeJSONPair_('value', StringToJSON_(mirror.value())));
}
content.push(MakeJSONPair_('length', NumberToJSON_(mirror.length())));
break;
case OBJECT_TYPE:
case FUNCTION_TYPE:
case ERROR_TYPE:
case REGEXP_TYPE:
// Add object representation.
this.serializeObject_(mirror, content);
break;
case PROPERTY_TYPE:
// Properties are represented by name, value, attributes and type.
content.push(MakeJSONPair_('name',
StringToJSON_(mirror.name())));
content.push(MakeJSONPair_('value',
mirror.value().toJSONProtocol(this.details_)));
if (mirror.attributes() != PropertyAttribute.None) {
content.push(MakeJSONPair_('attributes',
NumberToJSON_(mirror.attributes())));
}
if (mirror.propertyType() != PropertyType.Normal) {
content.push(MakeJSONPair_('propertyType',
NumberToJSON_(mirror.propertyType())));
}
break;
case ACCESSOR_TYPE:
// An accessor can either be native or defined through JavaScript.
if (mirror.isNative()) {
content.push(MakeJSONPair_('native', BooleanToJSON_(true)));
} else {
content.push(MakeJSONPair_('getter',
mirror.getter().toJSONProtocol(false)));
content.push(MakeJSONPair_('setter',
mirror.setter().toJSONProtocol(false)));
}
break;
case FRAME_TYPE:
// Add object representation.
this.serializeFrame_(mirror, content);
break;
case SCRIPT_TYPE:
// Script is represented by name and source attributes.
if (mirror.name()) {
content.push(MakeJSONPair_('name', StringToJSON_(mirror.name())));
}
content.push(MakeJSONPair_('lineOffset',
NumberToJSON_(mirror.lineOffset())));
content.push(MakeJSONPair_('columnOffset',
NumberToJSON_(mirror.columnOffset())));
content.push(MakeJSONPair_('lineCount',
NumberToJSON_(mirror.lineCount())));
content.push(MakeJSONPair_('scriptType',
NumberToJSON_(mirror.scriptType())));
break;
}
// Always add the text representation.
content.push(MakeJSONPair_('text', StringToJSON_(mirror.toText())));
// Create and return the JSON string.
return ArrayToJSONObject_(content);
}
JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content) {
content.push(MakeJSONPair_('className',
StringToJSON_(mirror.className())));
if (this.details_) {
content.push(MakeJSONPair_('constructorFunction',
mirror.constructorFunction().toJSONProtocol(false)));
content.push(MakeJSONPair_('protoObject',
mirror.protoObject().toJSONProtocol(false)));
content.push(MakeJSONPair_('prototypeObject',
mirror.prototypeObject().toJSONProtocol(false)));
// Add properties. For arrays don't include indexed proeprties.
var kind = PropertyKind.Named;
if (!mirror.isArray()) {
kind |= PropertyKind.Indexed
}
var propertyNames = mirror.propertyNames(kind);
var x = new Array(propertyNames.length);
for (var i = 0; i < propertyNames.length; i++) {
x[i] = mirror.property(propertyNames[i]).toJSONProtocol(false);
}
content.push(MakeJSONPair_('properties', ArrayToJSONArray_(x)));
// Add interceptor properties.
propertyNames = mirror.interceptorPropertyNames();
var x = new Array(propertyNames.length);
for (var i = 0; i < propertyNames.length; i++) {
x[i] = properties[i].toJSONProtocol(details);
}
content.push(MakeJSONPair_('interceptorProperties', ArrayToJSONArray_(x)));
// For arrays the indexed properties are added separately and the length is
// added as well.
if (mirror.isArray()) {
var propertyNames = mirror.propertyNames(PropertyKind.Indexed);
var x = new Array(propertyNames.length);
for (var i = 0; i < propertyNames.length; i++) {
x[i] = mirror.property(propertyNames[i]).toJSONProtocol(false);
}
content.push(MakeJSONPair_('indexedProperties', ArrayToJSONArray_(x)));
// Add the array length.
content.push(MakeJSONPair_('length', NumberToJSON_(mirror.length())));
}
}
if (mirror.hasNamedInterceptor()) {
content.push(MakeJSONPair_('namedInterceptor', BooleanToJSON_(true)));
}
if (mirror.hasIndexedInterceptor()) {
content.push(MakeJSONPair_('indexedInterceptor', BooleanToJSON_(true)));
}
if (mirror.isFunction()) {
// Add function specific properties.
content.push(MakeJSONPair_('name', StringToJSON_(mirror.name())));
content.push(MakeJSONPair_('resolved', BooleanToJSON_(mirror.resolved())));
if (this.details_ && mirror.resolved()) {
content.push(MakeJSONPair_('source', StringToJSON_(mirror.source())));
}
if (mirror.script()) {
content.push(MakeJSONPair_('script', mirror.script().toJSONProtocol()));
}
} else if (mirror.isDate()) {
// Add date specific properties.
content.push(MakeJSONPair_('value', DateToJSON_(mirror.value())));
} else if (mirror.isRegExp()) {
// Add regexp specific properties.
content.push(MakeJSONPair_('source', StringToJSON_(mirror.source())));
content.push(MakeJSONPair_('global', BooleanToJSON_(mirror.global())));
content.push(MakeJSONPair_('ignoreCase',
BooleanToJSON_(mirror.ignoreCase())));
content.push(MakeJSONPair_('multiline',
BooleanToJSON_(mirror.multiline())));
} else if (mirror.isError()) {
// Add error specific properties.
content.push(MakeJSONPair_('message', StringToJSON_(mirror.message())));
}
}
JSONProtocolSerializer.prototype.serializeFrame_ = function(mirror, content) {
content.push(MakeJSONPair_('index', NumberToJSON_(mirror.index())));
content.push(MakeJSONPair_('receiver',
mirror.receiver().toJSONProtocol(false)));
content.push(MakeJSONPair_('func', mirror.func().toJSONProtocol(false)));
content.push(MakeJSONPair_('constructCall',
BooleanToJSON_(mirror.isConstructCall())));
content.push(MakeJSONPair_('debuggerFrame',
BooleanToJSON_(mirror.isDebuggerFrame())));
var x = new Array(mirror.argumentCount());
for (var i = 0; i < mirror.argumentCount(); i++) {
arg = new Array();
var argument_name = mirror.argumentName(i)
if (argument_name) {
arg.push(MakeJSONPair_('name', StringToJSON_(argument_name)));
}
arg.push(MakeJSONPair_('value',
mirror.argumentValue(i).toJSONProtocol(false)));
x[i] = ArrayToJSONObject_(arg);
}
content.push(MakeJSONPair_('arguments', ArrayToJSONArray_(x)));
var x = new Array(mirror.localCount());
for (var i = 0; i < mirror.localCount(); i++) {
var name = MakeJSONPair_('name', StringToJSON_(mirror.localName(i)));
var value = MakeJSONPair_('value',
mirror.localValue(i).toJSONProtocol(false));
x[i] = '{' + name + ',' + value + '}';
}
content.push(MakeJSONPair_('locals', ArrayToJSONArray_(x)));
content.push(MakeJSONPair_('position',
NumberToJSON_(mirror.sourcePosition())));
var line = mirror.sourceLine();
if (!IS_UNDEFINED(line)) {
content.push(MakeJSONPair_('line', NumberToJSON_(line)));
}
var column = mirror.sourceColumn();
if (!IS_UNDEFINED(column)) {
content.push(MakeJSONPair_('column', NumberToJSON_(column)));
}
var source_line_text = mirror.sourceLineText();
if (!IS_UNDEFINED(source_line_text)) {
content.push(MakeJSONPair_('sourceLineText',
StringToJSON_(source_line_text)));
}
}
function MakeJSONPair_(name, value) { function MakeJSONPair_(name, value) {
return '"' + name + '":' + value; return '"' + name + '":' + value;
} }
......
...@@ -47,7 +47,7 @@ function testArrayMirror(a, names) { ...@@ -47,7 +47,7 @@ function testArrayMirror(a, names) {
assertTrue(mirror.constructorFunction() instanceof debug.ObjectMirror); assertTrue(mirror.constructorFunction() instanceof debug.ObjectMirror);
assertTrue(mirror.protoObject() instanceof debug.Mirror); assertTrue(mirror.protoObject() instanceof debug.Mirror);
assertTrue(mirror.prototypeObject() instanceof debug.Mirror); assertTrue(mirror.prototypeObject() instanceof debug.Mirror);
assertEquals(mirror.length(), a.length); assertEquals(mirror.length(), a.length, "Length mismatch");
var indexedValueMirrors = mirror.indexedPropertiesFromRange(); var indexedValueMirrors = mirror.indexedPropertiesFromRange();
assertEquals(indexedValueMirrors.length, a.length); assertEquals(indexedValueMirrors.length, a.length);
...@@ -64,7 +64,7 @@ function testArrayMirror(a, names) { ...@@ -64,7 +64,7 @@ function testArrayMirror(a, names) {
assertEquals('Array', fromJSON.className); assertEquals('Array', fromJSON.className);
assertEquals('function', fromJSON.constructorFunction.type); assertEquals('function', fromJSON.constructorFunction.type);
assertEquals('Array', fromJSON.constructorFunction.name); assertEquals('Array', fromJSON.constructorFunction.name);
assertEquals(a.length, fromJSON.length); assertEquals(a.length, fromJSON.length, "Length mismatch in parsed JSON");
// Check that the serialization contains all indexed properties. // Check that the serialization contains all indexed properties.
for (var i = 0; i < fromJSON.indexedProperties.length; i++) { for (var i = 0; i < fromJSON.indexedProperties.length; i++) {
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
function testFunctionMirror(f) { function testFunctionMirror(f) {
// Create mirror and JSON representation. // Create mirror and JSON representation.
var mirror = debug.MakeMirror(f); var mirror = debug.MakeMirror(f);
print(mirror.toJSONProtocol(true));
var json = mirror.toJSONProtocol(true); var json = mirror.toJSONProtocol(true);
// Check the mirror hierachy. // Check the mirror hierachy.
......
...@@ -119,7 +119,7 @@ function testObjectMirror(o, cls_name, ctor_name, hasSpecialProperties) { ...@@ -119,7 +119,7 @@ function testObjectMirror(o, cls_name, ctor_name, hasSpecialProperties) {
found = true; found = true;
} }
} }
assertTrue(found, '"' + name + '" not found'); assertTrue(found, '"' + name + '" not found (' + json + ')');
} }
} }
...@@ -139,6 +139,11 @@ testObjectMirror(this, 'global', undefined, true); // Global object has special ...@@ -139,6 +139,11 @@ testObjectMirror(this, 'global', undefined, true); // Global object has special
testObjectMirror([], 'Array', 'Array'); testObjectMirror([], 'Array', 'Array');
testObjectMirror([1,2], 'Array', 'Array'); testObjectMirror([1,2], 'Array', 'Array');
// Test circular references.
o = {};
o.o = o;
testObjectMirror(o, 'Object', 'Object');
// Test that non enumerable properties are part of the mirror // Test that non enumerable properties are part of the mirror
global_mirror = debug.MakeMirror(this); global_mirror = debug.MakeMirror(this);
assertEquals('property', global_mirror.property("Math").type()); assertEquals('property', global_mirror.property("Math").type());
......
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Test the mirror object for scripts.
function testScriptMirror(f, file_name, file_lines, script_type) {
// Create mirror and JSON representation.
var mirror = debug.MakeMirror(f).script();
var json = mirror.toJSONProtocol(true);
print(json);
// Check the mirror hierachy.
assertTrue(mirror instanceof debug.Mirror);
assertFalse(mirror instanceof debug.ValueMirror);
assertTrue(mirror instanceof debug.ScriptMirror);
// Check the mirror properties.
assertTrue(mirror.isScript());
assertEquals('script', mirror.type());
var name = mirror.name();
assertEquals(file_name, name.substring(name.length - file_name.length));
assertEquals(0, mirror.lineOffset());
assertEquals(0, mirror.columnOffset());
if (file_lines > 0) {
assertEquals(file_lines, mirror.lineCount());
}
assertEquals(script_type, mirror.scriptType());
// Parse JSON representation and check.
var fromJSON = eval('(' + json + ')');
assertEquals('script', fromJSON.type);
name = fromJSON.name;
assertEquals(file_name, name.substring(name.length - file_name.length));
assertEquals(0, fromJSON.lineOffset);
assertEquals(0, fromJSON.columnOffset);
if (file_lines > 0) {
assertEquals(file_lines, fromJSON.lineCount);
}
assertEquals(script_type, fromJSON.scriptType);
}
// Test the script mirror for different functions.
testScriptMirror(function(){}, 'mirror-script.js', 70, 2);
testScriptMirror(Math.sin, 'native math.js', -1, 0);
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
// Flags: --expose-debug-as debug // Flags: --expose-debug-as debug
// Test the mirror object for string values // Test the mirror object for string values
const kMaxProtocolStringLength = 80; // Constant from mirror-delay.js
function testStringMirror(s) { function testStringMirror(s) {
// Create mirror and JSON representation. // Create mirror and JSON representation.
var mirror = debug.MakeMirror(s); var mirror = debug.MakeMirror(s);
...@@ -44,16 +46,26 @@ function testStringMirror(s) { ...@@ -44,16 +46,26 @@ function testStringMirror(s) {
assertTrue(mirror.isPrimitive()); assertTrue(mirror.isPrimitive());
// Test text representation // Test text representation
assertEquals(s, mirror.toText()); if (s.length <= kMaxProtocolStringLength) {
assertEquals(s, mirror.toText());
} else {
assertEquals(s.substring(0, kMaxProtocolStringLength),
mirror.toText().substring(0, kMaxProtocolStringLength));
}
// Parse JSON representation and check. // Parse JSON representation and check.
var fromJSON = eval('(' + json + ')'); var fromJSON = eval('(' + json + ')');
assertEquals('string', fromJSON.type); assertEquals('string', fromJSON.type);
assertEquals(s, fromJSON.value); if (s.length <= kMaxProtocolStringLength) {
assertEquals(s, fromJSON.value);
} else {
assertEquals(s.substring(0, kMaxProtocolStringLength),
fromJSON.value.substring(0, kMaxProtocolStringLength));
assertEquals(fromJSON.fromIndex, 0);
assertEquals(fromJSON.toIndex, kMaxProtocolStringLength);
}
} }
Number =2;
// Test a number of different strings. // Test a number of different strings.
testStringMirror(''); testStringMirror('');
testStringMirror('abcdABCD'); testStringMirror('abcdABCD');
...@@ -67,3 +79,10 @@ testStringMirror('\\'); ...@@ -67,3 +79,10 @@ testStringMirror('\\');
testStringMirror('\b\t\n\f\r'); testStringMirror('\b\t\n\f\r');
testStringMirror('\u0001\u0002\u001E\u001F'); testStringMirror('\u0001\u0002\u001E\u001F');
testStringMirror('"a":1,"b":2'); testStringMirror('"a":1,"b":2');
var s = "1234567890"
s = s + s + s + s + s + s + s + s;
assertEquals(kMaxProtocolStringLength, s.length);
testStringMirror(s);
s = s + 'X';
testStringMirror(s);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment