Skip to content

Commit

Permalink
feat(codegen): introduce better format for traversal zones
Browse files Browse the repository at this point in the history
  • Loading branch information
P0lip committed Feb 5, 2024
1 parent 13bc7da commit 1c99eab
Show file tree
Hide file tree
Showing 10 changed files with 333 additions and 353 deletions.
183 changes: 113 additions & 70 deletions src/__tests__/codegen.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ describe('Code Generator', () => {
'$.info',
'$.info.contact',
'$.info.contact.*',
'$[servers,paths][*]',
'$.servers[*].url',
'$.servers[0:2]',
'$.servers[:5]',
Expand All @@ -24,36 +25,38 @@ describe('Code Generator', () => {
]),
).to.eq(`import {Scope, isObject} from "nimma/runtime";
const zones = {
"info": {
"contact": {
"*": {}
keys: ["info", "servers", "paths", "channels"],
zones: [{
keys: ["contact"],
zones: [{
zone: {}
}]
}, {
zone: {
keys: ["url"],
zones: [{}]
}
},
"servers": {
"*": {
"url": {}
}
},
"paths": {
"*": {
"202": {},
"404": {}
}, {
zone: {
keys: [404, 202],
zones: [{}, {}]
}
},
"channels": {
"*": {
"publish": {
"*": {
"payload": {}
}, {
zone: {
keys: ["publish", "subscribe"],
zones: [{
zone: {
keys: ["payload"],
zones: [{}]
}
},
"subscribe": {
"*": {
"payload": {}
}, {
zone: {
keys: ["payload"],
zones: [{}]
}
}
}]
}
}
}]
};
const tree = {
"$.info": function (scope) {
Expand All @@ -76,6 +79,11 @@ const tree = {
if (scope.path[1] !== "contact") return;
scope.emit("$.info.contact.*", 0, false);
},
"$[servers,paths][*]": function (scope) {
if (scope.path.length !== 2) return;
if (scope.path[0] !== "servers" && scope.path[0] !== "paths") return;
scope.emit("$[servers,paths][*]", 0, false);
},
"$.servers[*].url": function (scope) {
if (scope.path.length !== 3) return;
if (scope.path[0] !== "servers") return;
Expand Down Expand Up @@ -148,6 +156,7 @@ export default function (input, callbacks) {
const state0 = scope.allocState();
scope.traverse(() => {
tree["$.info.contact.*"](scope);
tree["$[servers,paths][*]"](scope);
tree["$.servers[*].url"](scope);
tree["$.servers[0:2]"](scope);
tree["$.servers[:5]"](scope);
Expand All @@ -166,11 +175,13 @@ export default function (input, callbacks) {
expect(generate(['$.info~', '$.servers[*].url~', '$.servers[:5]~'])).to
.eq(`import {Scope, isObject} from "nimma/runtime";
const zones = {
"servers": {
"*": {
"url": {}
keys: ["servers"],
zones: [{
zone: {
keys: ["url"],
zones: [{}]
}
}
}]
};
const tree = {
"$.info~": function (scope) {
Expand Down Expand Up @@ -595,7 +606,7 @@ export default function (input, callbacks) {
expect(generate(['$[*]', '$.*', '$[*]^', '$[*]~'])).to
.eq(`import {Scope} from "nimma/runtime";
const zones = {
"*": {}
zone: {}
};
const tree = {
"$[*]": function (scope) {
Expand Down Expand Up @@ -698,7 +709,7 @@ export default function (input, callbacks) {
]),
).to.eq(`import {Scope, inBounds} from "nimma/runtime";
const zones = {
"*": {}
zone: {}
};
const tree = {
"$[0:2]": function (scope) {
Expand Down Expand Up @@ -816,9 +827,8 @@ export default function (input, callbacks) {
expect(generate(['$.store..[price,bar,baz]', '$.book'])).to
.eq(`import {Scope, isObject} from "nimma/runtime";
const zones = {
"store": {
"**": null
}
keys: ["store"],
zones: [null]
};
const tree = {
"$.store..[price,bar,baz]": function (scope) {
Expand Down Expand Up @@ -857,11 +867,12 @@ export default function (input, callbacks) {
]),
).to.eq(`import {Scope} from "nimma/runtime";
const zones = {
"paths": {
"*": {
"**": null
keys: ["paths"],
zones: [{
zone: {
zone: null
}
}
}]
};
const tree = {
"$.paths[*][*]..content[*].examples[*]": function (scope) {
Expand Down Expand Up @@ -897,18 +908,15 @@ export default function (input, callbacks) {
expect(generate(['$.data[*][*][city,street]..id'])).to
.eq(`import {Scope} from "nimma/runtime";
const zones = {
"data": {
"*": {
"*": {
"city": {
"**": null
},
"street": {
"**": null
}
keys: ["data"],
zones: [{
zone: {
zone: {
keys: ["city", "street"],
zones: [null, null]
}
}
}
}]
};
const tree = {
"$.data[*][*][city,street]..id": function (scope) {
Expand Down Expand Up @@ -944,28 +952,28 @@ export default function (input, callbacks) {
]),
).to.eq(`import {Scope} from "nimma/runtime";
const zones = {
"paths": {
"*": {
"*": {
"tags": {
"*": {}
},
"operationId": {}
keys: ["paths", "abc"],
zones: [{
zone: {
zone: {
keys: ["tags", "operationId"],
zones: [{
zone: {}
}, {}]
}
}
},
"abc": {
"*": {
"*": {
"*": {
"*": {
"baz": {},
"bar": {}
}, {
zone: {
zone: {
zone: {
zone: {
keys: ["baz", "bar"],
zones: [{}, {}]
}
}
}
}
}
}]
};
const tree = {
"$.paths[*][*].tags[*]": function (scope) {
Expand Down Expand Up @@ -1020,6 +1028,39 @@ export default function (input, callbacks) {
scope.destroy();
}
}
`);
});

it('* and ** used as member property keys', () => {
expect(generate(['$.test[*]["*"]'])).to
.eq(`import {Scope} from "nimma/runtime";
const zones = {
keys: ["test"],
zones: [{
zone: {
keys: ["*"],
zones: [{}]
}
}]
};
const tree = {
"$.test[*][\\"*\\"]": function (scope) {
if (scope.path.length !== 3) return;
if (scope.path[0] !== "test") return;
if (scope.path[2] !== "*") return;
scope.emit("$.test[*][\\"*\\"]", 0, false);
}
};
export default function (input, callbacks) {
const scope = new Scope(input, callbacks);
try {
scope.traverse(() => {
tree["$.test[*][\\"*\\"]"](scope);
}, zones);
} finally {
scope.destroy();
}
}
`);
});
});
Expand Down Expand Up @@ -1075,7 +1116,7 @@ export default function (input, callbacks) {
]),
).to.eq(`import {Scope} from "nimma/runtime";
const zones = {
"*": {}
zone: {}
};
const tree = {
"$[?(index(@)=='key')]": function (scope) {
Expand Down Expand Up @@ -1181,11 +1222,13 @@ export default function (input, callbacks) {
}),
).to.eq(`import {Scope} from "nimma/runtime";
const zones = {
"components": {
"schemas": {
"**": null
}
}
keys: ["components"],
zones: [{
keys: ["schemas"],
zones: [{
zone: null
}]
}]
};
const tree = {
"$.components.schemas[*]..@@schema()": function (scope) {
Expand Down
37 changes: 0 additions & 37 deletions src/__tests__/index.test.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-disable no-undef */
import { expect } from 'chai';
import forEach from 'mocha-each';

import Nimma from '../index.mjs';
import { RuntimeError } from '../runtime/errors/index.mjs';
Expand Down Expand Up @@ -1452,42 +1451,6 @@ describe('Nimma', () => {
});
});

forEach([
Object.preventExtensions({
shirts: Object.seal({
color: 'red',
size: 'xl',
a: Object.freeze({
size: 'xl',
}),
b: Object.freeze({
size: 'm',
}),
}),
}),
{
shirts: {
color: 'red',
size: 'xl',
a: Object.seal({
size: 'xl',
}),
b: {
size: 'm',
},
},
},
]).it('frozen/sealed/non-extensible', document => {
const collected = collect(document, ['$.shirts[a,b].size']);

expect(collected).to.deep.eq({
'$.shirts[a,b].size': [
['xl', ['shirts', 'a', 'size']],
['m', ['shirts', 'b', 'size']],
],
});
});

it('given runtime errors, throws AggregateError', () => {
const n = new Nimma(['$.a', '$.b', '$.c', '$.d', '$.e', '$.f']);

Expand Down
7 changes: 3 additions & 4 deletions src/codegen/baseline/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ export default function baseline(jsonPaths, opts) {
]
: [];

const zone = tree.traversalZones.create();
let zone = tree.traversalZones.create();

for (const node of iterator) {
if (isDeep(node)) {
zone?.allIn();
zone?.unbind();
zone = null;
}

switch (node.type) {
Expand Down Expand Up @@ -115,8 +116,6 @@ export default function baseline(jsonPaths, opts) {
} else {
tree.addTreeMethod(ctx.id, b.blockStatement(branch), 'traverse');
}

zone?.attach();
}

return tree;
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/fast-paths/only-filter-script-expression.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default (nodes, tree, ctx) => {
);

if (!isDeep(nodes[0])) {
tree.traversalZones.create()?.resize().attach();
tree.traversalZones.create()?.resize();
}

return true;
Expand Down
Loading

0 comments on commit 1c99eab

Please sign in to comment.