Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(686)

Unified Diff: third_party/WebKit/Source/devtools/front_end/formatter_worker/RelaxedJSONParser.js

Issue 1912973002: [DevTools] JSONView parsing smarter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/formatter_worker/RelaxedJSONParser.js
diff --git a/third_party/WebKit/Source/devtools/front_end/formatter_worker/RelaxedJSONParser.js b/third_party/WebKit/Source/devtools/front_end/formatter_worker/RelaxedJSONParser.js
new file mode 100644
index 0000000000000000000000000000000000000000..2c0b38042f2d4a54fe37accb73e5bcdc9c4c7409
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/formatter_worker/RelaxedJSONParser.js
@@ -0,0 +1,201 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+WebInspector.RelaxedJSONParser = {};
+
+/** @enum {string} */
+WebInspector.RelaxedJSONParser.States = {
+ ExpectKey: "ExpectKey",
+ ExpectValue: "ExpectValue"
+};
+
+/** @enum {*} */
+WebInspector.RelaxedJSONParser.Keywords = {
+ "NaN": NaN,
+ "true": true,
+ "false": false,
+ "Infinity": Infinity,
+ "undefined": undefined,
+ "null": null
+};
+
+/**
+ * @param {string} content
+ * @return {*}
+ */
+WebInspector.RelaxedJSONParser.parse = function(content)
+{
+ var Keywords = WebInspector.RelaxedJSONParser.Keywords;
+ var States = WebInspector.RelaxedJSONParser.States;
+ content = "(" + content + ")";
+
+ try {
+ var root = acorn.parse(content, {});
+ } catch (e) {
+ return null;
+ }
+
+ var walker = new WebInspector.ESTreeWalker(beforeVisit, afterVisit);
+
+ var rootTip = [];
+
+ /** @type {!Array.<!WebInspector.RelaxedJSONParser.Context>} */
+ var stack = [];
+
+ var stackData = /** @type {!WebInspector.RelaxedJSONParser.Context} */ ({
+ key: 0,
+ tip: rootTip,
+ state: States.ExpectValue,
+ parentIsArray: true
+ });
+
+ walker.setWalkNulls(true);
+ var hasExpression = false;
+
+ walker.walk(root);
+
+ if (hasExpression)
+ return null;
+ return rootTip.length ? rootTip[0] : null;
+
+ /**
+ * @param {!WebInspector.RelaxedJSONParser.Context} newStack
+ */
+ function pushStack(newStack)
+ {
+ stack.push(stackData);
+ stackData = newStack;
+ }
+
+ function popStack()
+ {
+ stackData = stack.pop();
+ }
+
+ /**
+ * @param {*} value
+ */
+ function applyValue(value)
+ {
+ stackData.tip[stackData.key] = value;
+ if (stackData.parentIsArray)
+ stackData.key++;
+ else
+ stackData.state = null;
+ }
+
+ /**
+ * @param {!ESTree.Node} node
+ * @return {!Object|undefined}
+ */
+ function beforeVisit(node)
+ {
+ switch (node.type) {
+ case "ObjectExpression":
+ var newTip = {};
+ applyValue(newTip);
+
+ pushStack(/** @type {!WebInspector.RelaxedJSONParser.Context} */ ({
+ key: null,
+ tip: newTip,
+ state: null,
+ parentIsArray: false
+ }));
+ break;
+ case "ArrayExpression":
+ var newTip = [];
+ applyValue(newTip);
+
+ pushStack(/** @type {!WebInspector.RelaxedJSONParser.Context} */ ({
+ key: 0,
+ tip: newTip,
+ state: States.ExpectValue,
+ parentIsArray: true
+ }));
+ break;
+ case "Property":
+ stackData.state = States.ExpectKey;
+ break;
+ case "Literal":
+ if (stackData.state === States.ExpectKey) {
+ stackData.key = node.value;
+ stackData.state = States.ExpectValue;
+ } else if (stackData.state === States.ExpectValue) {
+ applyValue(extractValue(node));
+ return WebInspector.ESTreeWalker.SkipSubtree;
+ }
+ break;
+ case "Identifier":
+ if (stackData.state === States.ExpectKey) {
+ stackData.key = /** @type {string} */ (node.name);
+ stackData.state = States.ExpectValue;
+ } else if (stackData.state === States.ExpectValue) {
+ applyValue(extractValue(node));
+ return WebInspector.ESTreeWalker.SkipSubtree;
+ }
+ break;
+ case "UnaryExpression":
+ if (stackData.state === States.ExpectValue) {
+ applyValue(extractValue(node));
+ return WebInspector.ESTreeWalker.SkipSubtree;
+ }
+ break;
+ case "Program":
+ case "ExpressionStatement":
+ break;
+ default:
+ if (stackData.state === States.ExpectValue)
+ applyValue(extractValue(node));
+ return WebInspector.ESTreeWalker.SkipSubtree;
+ }
+ }
+
+ /**
+ * @param {!ESTree.Node} node
+ */
+ function afterVisit(node)
+ {
+ if (node.type === "ObjectExpression" || node.type === "ArrayExpression")
+ popStack();
+ }
+
+ /**
+ * @param {!ESTree.Node} node
+ * @return {*}
+ */
+ function extractValue(node)
+ {
+ var isNegative = false;
+ var originalNode = node;
+ var value;
+ if (node.type === "UnaryExpression" && (node.operator === "-" || node.operator === "+")) {
+ if (node.operator === "-")
+ isNegative = true;
+ node = /** @type {!ESTree.Node} */ (node.argument);
+ }
+
+ if (node.type === "Literal") {
+ value = node.value;
+ } else if (node.type === "Identifier" && Keywords.hasOwnProperty(node.name)) {
+ value = Keywords[node.name];
+ } else {
+ hasExpression = true;
+ return content.substring(originalNode.start, originalNode.end);
+ }
+
+ if (isNegative) {
+ if (typeof value !== "number") {
+ hasExpression = true;
+ return content.substring(originalNode.start, originalNode.end);
+ }
+ value = -(value);
+ }
+ return value;
+ }
+}
+
+/**
+ * @typedef {!{key: (number|string), tip: (!Array|!Object), state: ?WebInspector.RelaxedJSONParser.States, parentIsArray: boolean}}
+ */
+WebInspector.RelaxedJSONParser.Context;

Powered by Google App Engine
This is Rietveld 408576698