提交 c08fb277 编写于 作者: M Martin Aeschlimann

json: Add findNodeAtLocation

上级 73b78b70
......@@ -931,6 +931,49 @@ export function parseTree(text:string, errors: ParseError[] = [], options?: Pars
return result;
}
export function findNodeAtLocation(root: Node, segments: Segment[]) : Node {
let node = root;
for (let segment of segments) {
if (typeof segment === 'string') {
if (node.type !== 'object') {
return void 0;
}
let found = false;
for (let propertyNode of node.children) {
if (propertyNode.children[0].value === segment) {
node = propertyNode.children[1];
found = true;
break;
}
}
if (!found) {
return void 0;
}
} else {
let index = <number> segment;
if (node.type !== 'array' || index < 0 || index >= node.children.length) {
return void 0;
}
node = node.children[index];
}
}
return node;
}
export function getNodeValue(node: Node) : any {
if (node.type === 'array') {
return node.children.map(getNodeValue);
} else if (node.type === 'object') {
let obj = {};
for (let prop of node.children) {
obj[prop.children[0].value] = getNodeValue(prop.children[1]);
}
return obj;
}
return node.value;
}
/**
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
*/
......
......@@ -5,7 +5,8 @@
'use strict';
import * as assert from 'assert';
import { SyntaxKind, createScanner, parse, getLocation, Node, ParseError, parseTree, ParseErrorCode, getParseErrorMessage, ParseOptions, Segment } from 'vs/base/common/json';
import { SyntaxKind, createScanner, parse, getLocation, Node, ParseError, parseTree, ParseErrorCode,
getParseErrorMessage, ParseOptions, Segment, findNodeAtLocation, getNodeValue } from 'vs/base/common/json';
function assertKinds(text:string, ...kinds:SyntaxKind[]):void {
var _json = createScanner(text);
......@@ -54,6 +55,11 @@ function assertTree(input:string, expected:any) : void {
assert.deepEqual(actual, expected);
}
function assertNodeAtLocation(input:Node, segments: Segment[], expected: any) {
let actual = findNodeAtLocation(input, segments);
assert.deepEqual(actual ? getNodeValue(actual) : void 0, expected);
}
function assertLocation(input:string, expectedSegments: Segment[], expectedNodeType: string, expectedCompleteProperty: boolean) : void {
var errors : {error: ParseErrorCode}[] = [];
......@@ -304,4 +310,18 @@ suite('JSON', () => {
]}
);
});
test('tree: find location', () => {
let root = parseTree('{ "key1": { "key11": [ "val111", "val112" ] }, "key2": [ { "key21": false, "key22": 221 }, null, [{}] ] }');
assertNodeAtLocation(root, [ "key1"], { key11: [ 'val111', 'val112' ]});
assertNodeAtLocation(root, [ "key1", "key11"], [ 'val111', 'val112' ]);
assertNodeAtLocation(root, [ "key1", "key11", 0], 'val111');
assertNodeAtLocation(root, [ "key1", "key11", 1], 'val112');
assertNodeAtLocation(root, [ "key1", "key11", 2], void 0);
assertNodeAtLocation(root, [ "key2", 0, "key21"], false);
assertNodeAtLocation(root, [ "key2", 0, "key22"], 221);
assertNodeAtLocation(root, [ "key2", 1], null);
assertNodeAtLocation(root, [ "key2", 2], [{}]);
assertNodeAtLocation(root, [ "key2", 2, 0], {});
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册