From: sgjesse@chromium.org Date: Wed, 7 Jan 2009 09:27:30 +0000 (+0000) Subject: Factored the generation of JSON serialization from beeing part of the mirror objects... X-Git-Tag: upstream/4.7.83~24825 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=60cb58ea914b7138da4b74c5dd7838b4eb9c5303;p=platform%2Fupstream%2Fv8.git 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 --- diff --git a/src/mirror-delay.js b/src/mirror-delay.js index caf963e..e7ff910 100644 --- a/src/mirror-delay.js +++ b/src/mirror-delay.js @@ -33,6 +33,12 @@ RegExp; 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) { if (IS_UNDEFINED(value)) return new UndefinedMirror(); if (IS_NULL(value)) return new NullMirror(); @@ -106,7 +112,6 @@ PropertyType.ConstantTransition = 6; PropertyType.NullDescriptor = 7; - // Different attributes for a property. PropertyAttribute = {}; PropertyAttribute.None = NONE; @@ -123,12 +128,12 @@ PropertyAttribute.DontDelete = DONT_DELETE; // - NumberMirror // - StringMirror // - ObjectMirror -// - FunctionMirror -// - UnresolvedFunctionMirror -// - ArrayMirror -// - DateMirror -// - RegExpMirror -// - ErrorMirror +// - FunctionMirror +// - UnresolvedFunctionMirror +// - ArrayMirror +// - DateMirror +// - RegExpMirror +// - ErrorMirror // - PropertyMirror // - InterceptorPropertyMirror // - AccessorMirror @@ -296,29 +301,24 @@ Mirror.prototype.isFrame = function() { } -Mirror.prototype.fillJSONType_ = function(content) { - content.push(MakeJSONPair_('type', StringToJSON_(this.type()))); -}; - - -Mirror.prototype.fillJSON_ = function(content) { - this.fillJSONType_(content); -}; +/** + * Check whether the mirror reflects a script. + * @returns {boolean} True if the mirror reflects a script + */ +Mirror.prototype.isScript = function() { + return this instanceof ScriptMirror; +} /** - * Serialize object in JSON format. For the basic mirrors this includes only - * the type in the following format. - * {"type":""} - * For specialized mirrors inheriting from the base Mirror + * Serialize object in JSON format. The actual serialization is handled by the + * JSONProtocolSerializer. * @param {boolean} details Indicate level of details to include * @return {string} JSON serialization */ -Mirror.prototype.toJSONProtocol = function(details, propertiesKind, interceptorPropertiesKind) { - var content = new Array(); - this.fillJSON_(content, details, propertiesKind, interceptorPropertiesKind); - content.push(MakeJSONPair_('text', StringToJSON_(this.toText()))); - return ArrayToJSONObject_(content); +Mirror.prototype.toJSONProtocol = function(details) { + var serializer = new JSONProtocolSerializer(details) + return serializer.serialize(this) } @@ -409,12 +409,6 @@ function BooleanMirror(value) { 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() { return this.value_ ? 'true' : 'false'; } @@ -432,12 +426,6 @@ function NumberMirror(value) { 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() { return %NumberToString(this.value_); } @@ -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() { if (this.length() > kMaxProtocolStringLength) { return this.value_.substring(0, kMaxProtocolStringLength) + @@ -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() { var name; var ctor = this.constructorFunction(); @@ -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() { return this.source(); } @@ -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. * @param {Date} value The Date object reflected by this mirror @@ -1012,14 +915,6 @@ function DateMirror(value) { 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() { return DateToISO8601_(this.value_); } @@ -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() { // Simpel to text which is used when on specialization in subclass. return "/" + this.source() + "/"; @@ -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() { // Use the same text representation as in messages.js. var text; @@ -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. * @param {ObjectMirror} mirror The mirror object having this property @@ -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:", - "getter":, - "setter":} - * 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 kFrameDetailsReceiverIndex = 1; const kFrameDetailsFunctionIndex = 2; @@ -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() { // Format frame invoaction (receiver, function and arguments). var result = ''; @@ -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() { var result = ''; result += this.name(); @@ -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) { return '"' + name + '":' + value; } diff --git a/test/mjsunit/mirror-array.js b/test/mjsunit/mirror-array.js index 25e64a6..93c87bd 100644 --- a/test/mjsunit/mirror-array.js +++ b/test/mjsunit/mirror-array.js @@ -47,7 +47,7 @@ function testArrayMirror(a, names) { assertTrue(mirror.constructorFunction() instanceof debug.ObjectMirror); assertTrue(mirror.protoObject() 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(); assertEquals(indexedValueMirrors.length, a.length); @@ -64,7 +64,7 @@ function testArrayMirror(a, names) { assertEquals('Array', fromJSON.className); assertEquals('function', fromJSON.constructorFunction.type); 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. for (var i = 0; i < fromJSON.indexedProperties.length; i++) { diff --git a/test/mjsunit/mirror-function.js b/test/mjsunit/mirror-function.js index c6e7a4e..43ff50f 100644 --- a/test/mjsunit/mirror-function.js +++ b/test/mjsunit/mirror-function.js @@ -31,7 +31,6 @@ function testFunctionMirror(f) { // Create mirror and JSON representation. var mirror = debug.MakeMirror(f); - print(mirror.toJSONProtocol(true)); var json = mirror.toJSONProtocol(true); // Check the mirror hierachy. diff --git a/test/mjsunit/mirror-object.js b/test/mjsunit/mirror-object.js index bbaf044..ff896fc 100644 --- a/test/mjsunit/mirror-object.js +++ b/test/mjsunit/mirror-object.js @@ -119,7 +119,7 @@ function testObjectMirror(o, cls_name, ctor_name, hasSpecialProperties) { 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 testObjectMirror([], '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 global_mirror = debug.MakeMirror(this); assertEquals('property', global_mirror.property("Math").type()); diff --git a/test/mjsunit/mirror-script.js b/test/mjsunit/mirror-script.js new file mode 100644 index 0000000..0034829 --- /dev/null +++ b/test/mjsunit/mirror-script.js @@ -0,0 +1,70 @@ +// 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); diff --git a/test/mjsunit/mirror-string.js b/test/mjsunit/mirror-string.js index 451f8f1..0a382d3 100644 --- a/test/mjsunit/mirror-string.js +++ b/test/mjsunit/mirror-string.js @@ -28,6 +28,8 @@ // Flags: --expose-debug-as debug // Test the mirror object for string values +const kMaxProtocolStringLength = 80; // Constant from mirror-delay.js + function testStringMirror(s) { // Create mirror and JSON representation. var mirror = debug.MakeMirror(s); @@ -44,16 +46,26 @@ function testStringMirror(s) { assertTrue(mirror.isPrimitive()); // 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. var fromJSON = eval('(' + json + ')'); 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. testStringMirror(''); testStringMirror('abcdABCD'); @@ -67,3 +79,10 @@ testStringMirror('\\'); testStringMirror('\b\t\n\f\r'); testStringMirror('\u0001\u0002\u001E\u001F'); 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);