Skip to content

Instantly share code, notes, and snippets.

@ivanbatic
Created November 7, 2016 06:30
Show Gist options
  • Save ivanbatic/65145ef29c933f8958fb09584f97393c to your computer and use it in GitHub Desktop.
Save ivanbatic/65145ef29c933f8958fb09584f97393c to your computer and use it in GitHub Desktop.
Given a possibly invalid JSON content and a caret position, determines the structure path that leads to it
const filePath = "whole-genome.json";
const esprima = require("esprima");
const fs = require("fs");
const wholeGenome = fs.readFileSync(filePath, "utf8");
console.time("whole-genome");
console.time("tokenizer");
const tokens = esprima.tokenize(wholeGenome, {loc: true});
console.timeEnd("tokenizer");
const typing = {
column: 42,
row: 2236 + 2
};
const lastIndex = tokens.findIndex(t => {
return t.loc.start.line === typing.row && t.loc.end.column <= typing.column;
});
const preceedingTokens = tokens.slice(0, lastIndex);
let braceBalance = 0;
let lastEntryBalance = 0;
const keyTrace = [];
let keyCandidate;
for (let i = (preceedingTokens.length - 2); i >= 0; i--) {
const t = preceedingTokens[i];
const isString = t.type === "String";
const isPunctuator = t.type === "Punctuator";
const isBlockOpen = t.value === "{" || t.value === "[";
const isBlockClose = t.value === "}" || t.value === "]";
const preceedsColon = preceedingTokens[i + 1].type === "Punctuator" && preceedingTokens[i + 1].value === ":";
if (
(isString && preceedsColon)
|| (isPunctuator && (isBlockOpen || isBlockClose ))
) {
} else {
continue;
}
if (isString && !keyCandidate && braceBalance === keyTrace.length) {
keyCandidate = t.value;
}
if (isPunctuator && isBlockClose) {
braceBalance--;
}
if (isPunctuator && isBlockOpen) {
braceBalance++;
if (braceBalance > 0 && braceBalance > lastEntryBalance) {
keyTrace.push(keyCandidate);
lastEntryBalance = braceBalance;
keyCandidate = undefined;
}
}
}
console.timeEnd("whole-genome");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment