Skip to content

Commit ea51a50

Browse files
author
Neil Fraser
committed
Factor out location object encoding/decoding.
Also make a change to reduce the size of the serialized output. If the start line and the end line are the same, then don't record the end line. This is a small (but breaking) change to the serialization format. However the docs are explicit about the format not being backwards compatible.
1 parent 0ec779f commit ea51a50

File tree

1 file changed

+72
-54
lines changed

1 file changed

+72
-54
lines changed

demos/serialize.js

Lines changed: 72 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ var NODE_CONSTRUCTOR;
1616
var NODE_LOC_CONSTRUCTOR;
1717
var LINE_LOC_CONSTRUCTOR;
1818

19-
var LOC_REGEX = /^(\d*):(\d*)-(\d*):(\d*) ?(.*)$/;
20-
2119
/**
2220
* All non-primitives in the interpreter.
2321
* @type {!Array<!Object>}
@@ -130,40 +128,50 @@ function deserialize(json, interpreter) {
130128
delete obj.end;
131129
var locText = jsonObj['loc'];
132130
if (locText) {
133-
// Turn a serialized string '1:0-4:21 code' into a location object:
134-
// {
135-
// start: {line 1, column: 0},
136-
// end: {line 4, column: 21},
137-
// source: "code"
138-
// }
139-
var loc = new NODE_LOC_CONSTRUCTOR();
140-
var m = locText.match(LOC_REGEX);
141-
var locStart = null;
142-
if (m[1] || m[2]) {
143-
locStart = new LINE_LOC_CONSTRUCTOR();
144-
locStart.line = Number(m[1]);
145-
locStart.column = Number(m[2]);
146-
}
147-
loc.start = locStart;
148-
var locEnd = null;
149-
if (m[3] || m[4]) {
150-
locEnd = new LINE_LOC_CONSTRUCTOR();
151-
locEnd.line = Number(m[3]);
152-
locEnd.column = Number(m[4]);
153-
}
154-
loc.end = locEnd;
155-
if (m[5]) {
156-
loc.source = decodeURI(m[5]);
157-
} else {
158-
delete loc.source;
159-
}
160-
obj.loc = loc;
131+
obj.loc = decodeLoc_(locText);
161132
}
162133
return obj;
163134
}
164135
throw TypeError('Unknown type: ' + jsonObj['type']);
165136
}
166137

138+
var LOC_REGEX = /^(\d*):(\d*)-(\d*):(\d*) ?(.*)$/;
139+
140+
/**
141+
* Turn a serialized string '1:0-4:21 code' into a location object:
142+
* {
143+
* start: {line 1, column: 0},
144+
* end: {line 4, column: 21},
145+
* source: "code"
146+
* }
147+
* @param {string} locText Serialized location.
148+
* @return {!Object} Location object.
149+
*/
150+
function decodeLoc_(locText) {
151+
var loc = new NODE_LOC_CONSTRUCTOR();
152+
var m = locText.match(LOC_REGEX);
153+
var locStart = null;
154+
if (m[1] || m[2]) {
155+
locStart = new LINE_LOC_CONSTRUCTOR();
156+
locStart.line = Number(m[1]);
157+
locStart.column = Number(m[2]);
158+
}
159+
loc.start = locStart;
160+
var locEnd = null;
161+
if (m[3] || m[4]) {
162+
locEnd = new LINE_LOC_CONSTRUCTOR();
163+
locEnd.line = m[3] ? Number(m[3]) : Number(m[1]);
164+
locEnd.column = Number(m[4]);
165+
}
166+
loc.end = locEnd;
167+
if (m[5]) {
168+
loc.source = decodeURI(m[5]);
169+
} else {
170+
delete loc.source;
171+
}
172+
return loc;
173+
}
174+
167175
/**
168176
* Repopulate an object's or array's properties based on th JSON description.
169177
* @param {!Object} jsonObj JSON object describing property contents.
@@ -350,30 +358,7 @@ function serialize(interpreter) {
350358
for (var j = 0; j < names.length; j++) {
351359
var name = names[j];
352360
if (jsonObj['type'] === 'Node' && name === 'loc') {
353-
// Compactly serialize the location objects on a Node:
354-
// {
355-
// start: {line 1, column: 0},
356-
// end: {line 4, column: 21},
357-
// source: "code"
358-
// }
359-
// into a string like this: '1:0-4:21 code'
360-
var loc = obj.loc;
361-
var locText = '';
362-
if (loc.start) {
363-
locText += loc.start.line + ':' + loc.start.column;
364-
} else {
365-
locText += ':';
366-
}
367-
locText += '-';
368-
if (loc.end) {
369-
locText += loc.end.line + ':' + loc.end.column;
370-
} else {
371-
locText += ':';
372-
}
373-
if (loc.source !== undefined) {
374-
locText += ' ' + encodeURI(loc.source);
375-
}
376-
jsonObj['loc'] = locText;
361+
jsonObj['loc'] = encodeLoc_(obj.loc);
377362
} else {
378363
var descriptor = Object.getOwnPropertyDescriptor(obj, name);
379364
props[name] = encodeValue_(descriptor.value);
@@ -417,6 +402,39 @@ function serialize(interpreter) {
417402
return json;
418403
}
419404

405+
/**
406+
* Compactly serialize the location objects on a Node:
407+
* {
408+
* start: {line 1, column: 0},
409+
* end: {line 4, column: 21},
410+
* source: "code"
411+
* }
412+
* into a string like this: '1:0-4:21 code'
413+
* @param {!Object} loc Location object.
414+
* @return {string} Serializade location.
415+
*/
416+
function encodeLoc_(loc) {
417+
var locText = '';
418+
if (loc.start) {
419+
locText += loc.start.line + ':' + loc.start.column;
420+
} else {
421+
locText += ':';
422+
}
423+
locText += '-';
424+
if (loc.end) {
425+
if (!loc.start || loc.start.line !== loc.end.line) {
426+
locText += loc.end.line;
427+
}
428+
locText += ':' + loc.end.column;
429+
} else {
430+
locText += ':';
431+
}
432+
if (loc.source !== undefined) {
433+
locText += ' ' + encodeURI(loc.source);
434+
}
435+
return locText;
436+
}
437+
420438
/**
421439
* Given a real value, encode it to a serialized value.
422440
* Most values are themselves. But objects are references, and Infinity, NaN,

0 commit comments

Comments
 (0)