Skip to content

Commit

Permalink
Remove support for a legacy syntax for functions
Browse files Browse the repository at this point in the history
  • Loading branch information
lahmatiy committed Oct 24, 2023
1 parent 4561cf9 commit e210489
Show file tree
Hide file tree
Showing 8 changed files with 7 additions and 175 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## next

- Removed support for a legacy syntax for functions, i.e. `<expr>`
- Disallowed whitespace between a method name and open parenthesis
- Allowed keywords as a property getter in query chains when a dot is before the keyword. For example, `.has.and.is` is now a valid query, while `has.and` is not valid due to the missing dot before `has`.
- Added support for keyword literals (`null`, `undefined`, `true`, `false`, `NaN` and `Infinity`), numbers and strings as property name in an object literal when a value is not specified, i.e. `{ null }` is the same as `{ "null": $["null"] }`
Expand Down
13 changes: 1 addition & 12 deletions src/compile-modules/lang/grammar.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,6 @@ exports.lex = {

// functions
['=>', 'return "FUNCTION";'],
['<(?!=)', function() {
this.fnOpened++;
return 'FUNCTION_START';
}],

// operators
['=', 'return "=";'],
Expand All @@ -276,13 +272,7 @@ exports.lex = {
['>=', 'return ">=";'],
['<=', 'return "<=";'],
['<', 'return "<";'],
['>', function() {
if (this.fnOpened) {
this.fnOpened--;
return 'FUNCTION_END';
}
return '>';
}],
['>', 'return ">";'],
['\\.\\.\\(', 'return "..(";'],
['\\.\\(', 'return ".(";'],
['\\.\\[', 'return ".[";'],
Expand Down Expand Up @@ -377,7 +367,6 @@ exports.bnf = {
['query', asis],

// functions
['FUNCTION_START block FUNCTION_END', $$(Function([], $2, true))],
['FUNCTION e', $$(Function([], $2))],
['compareFunction', $$(CompareFunction($1))],

Expand Down
5 changes: 2 additions & 3 deletions src/compile-modules/lang/nodes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,11 @@ exports.Filter = function(value, query) {
query
};
};
exports.Function = function(args, body, legacy) {
exports.Function = function(args, body) {
return {
type: 'Function',
arguments: args,
body,
legacy: Boolean(legacy)
body
};
};
exports.GetProperty = function(value, property) {
Expand Down
8 changes: 0 additions & 8 deletions src/compile-modules/lang/parse-patch.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ module.exports = function buildParsers(strictParser) {
['EOF', ['<end of input>']],
['IDENT', ['ident']],
['$IDENT', ['$ident']],
['FUNCTION_START', ["'<'"]],
['FUNCTION_END', ["'>'"]],
['FUNCTION', ["'=>'"]],
['NOT', ["'not'"]],
['NO', ["'no'"]],
Expand Down Expand Up @@ -230,8 +228,6 @@ module.exports = function buildParsers(strictParser) {
}
};

this.fnOpened = 0;
this.fnOpenedStack = [];
this.bracketStack = [];
this.prevToken = null;
this.prevYylloc = {
Expand Down Expand Up @@ -386,14 +382,10 @@ module.exports = function buildParsers(strictParser) {
if (expected !== token) {
this.parseError(`Expected "${expected}" got "${token}"`);
}

this.fnOpened = this.fnOpenedStack.pop() || 0;
}

if (openBalance.has(token)) {
this.bracketStack.push(openBalance.get(token));
this.fnOpenedStack.push(this.fnOpened);
this.fnOpened = 0;
}

return token;
Expand Down
2 changes: 1 addition & 1 deletion test/helpers/all-syntax.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export default [
'$foo:true;$a:false;$c;$;$d:d.e;$f:$["f"];',
'bar([#,@,null,undefined,Infinity,NaN,not $,no $,1,"2\'\\"",/3/i,/asd/],{a:3,$b,$,c,$d:1,"asd":3,["asd"+x]:3,...,...$,...foo,...(a+5)},<foo+4>,',
'bar([#,@,null,undefined,Infinity,NaN,not $,no $,1,"2\'\\"",/3/i,/asd/],{a:3,$b,$,c,$d:1,"asd":3,["asd"+x]:3,...,...$,...foo,...(a+5)},',
'`template`,`temp${1}late`,`te${1+1}mp${{a:3}["a"]+`xxx${42}xxx`}late`,`${1}${2} ${3}${4} ${5}${6}`,`${} ${} ${}`,',
'[...,...$,...1+1],',
'x?1 in xx():2,sort((($x;$x+b)*7) asc,b desc)).(a.[foo]).x($[a+"asd"],$[foo])',
Expand Down
138 changes: 0 additions & 138 deletions test/lang/function.js
Original file line number Diff line number Diff line change
@@ -1,144 +1,6 @@
import assert from 'assert';
import query from 'jora';

describe('lang/function (legacy)', () => {
it('empty function', () => {
assert.strictEqual(
typeof query('<>')(),
'function'
);
});

it('body is a query', () => {
assert.strictEqual(
typeof query('<foo>')(),
'function'
);
});

it('allow definitions in a function', () => {
assert.strictEqual(
query('map(<$a;$a>)')({ a: 42 }),
42
);
});

it('body is an empty object', () => {
assert.deepEqual(
query('<{}>')()(),
{}
);
});

it('body is an object with a single key', () => {
assert.deepEqual(
query('<{foo:1}>')()(),
{ foo: 1 }
);
});

it('body is an object with a couple keys', () => {
assert.deepEqual(
query('<{foo:1,bar:2}>')()(),
{ foo: 1, bar: 2 }
);
});

it('body is an expression', () => {
assert.strictEqual(
typeof query('<foo or bar>')(),
'function'
);
});

it('body is an expression #2', () => {
assert.strictEqual(
query('map(<foo ? 1 : 2>)')({ foo: true }),
1
);
});

it('body is an expression with `>` operator', () => {
assert.strictEqual(
typeof query('<(a > b)>')(),
'function'
);

assert.strictEqual(
query('map(<(a > b)>)')({ a: 1, b: 2 }),
false
);

assert.strictEqual(
query('map(<(a > b)>)')({ a: 2, b: 1 }),
true
);

assert.deepEqual(
query('map(<{ test: a.size() > 2 }>)')([{ a: [2, 3] }, { a: [1, 2, 3] }]),
[{ test: false }, { test: true }]
);

assert.deepEqual(
query('map(<a.[$ > 2]>)')([{ a: [2, 3] }, { a: [1, 5, 2] }]),
[3, 5]
);

assert.deepEqual(
query('map(<a.($ > 2)>)')([{ a: [2, 3] }, { a: [1, 5, 2] }]),
[false, true]
);

assert.deepEqual(
query('map(<a..($ > 2)>)')([{ a: [2, 3] }, { a: [1, 5, 2] }]),
[false, true]
);

assert.deepEqual(
query('map(<a[b > 2]>)')([{ a: { true: 1, false: 2 }, b: 1 }, { a: { true: 3, false: 4 }, b: 3 }]),
[2, 3]
);
});

it('body is an expression with `<` operator', () => {
assert.strictEqual(
typeof query('<a < b>')(),
'function'
);

assert.strictEqual(
query('map(<a < b>)')({ a: 1, b: 2 }),
true
);

assert.strictEqual(
query('map(<a < b>)')({ a: 2, b: 1 }),
false
);
});

it('body is an expression with `<` and `>` operators', () => {
assert.strictEqual(
typeof query('<$ < 10 or ($ > 20)>')(),
'function'
);
});

it('body is an expression with `<` and `>` operators with map()', () => {
assert.deepEqual(
[5, 15, 25].map(value => query('map(<$ < 10 or ($ > 20)>)')(value)),
[true, false, true]
);
});

it('nested functions', () => {
assert.deepEqual(
query('map(<<a>>)')([1, 2]).map(value => typeof value),
['function', 'function']
);
});
});

describe('lang/function', () => {
it('empty function', () => {
assert.strictEqual(
Expand Down
11 changes: 0 additions & 11 deletions test/suggestions.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,6 @@ describe('query/suggestions', () => {
);
});

it('function context old syntax <...>', () => {
assert.deepEqual(
suggestQuery('map(|<|>|)', data),
[
null,
suggestion('', ['foo', 'bar'], 5, 5),
null
]
);
});

it('function context', () => {
assert.deepEqual(
suggestQuery('map(|=|>|)', data),
Expand Down
4 changes: 2 additions & 2 deletions test/syntax/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ describe('syntax/parse', () => {
() => parse('foo\n .[bar =]'),
function(e) {
assert.deepEqual(e.details, {
rawMessage: "Parse error on line 2:\nfoo\\n .[bar =]\n-------------^\nExpecting '$', 'IDENT', '$IDENT', '?', 'FUNCTION_START', 'FUNCTION', 'NOT', 'NO', '-', '+', 'IS', '@', '#', '$$', 'STRING', 'NUMBER', 'REGEXP', 'LITERAL', '[', '(', '.', '.(', '.[', '..', '..(', 'METHOD(', '$METHOD(', 'TEMPLATE', 'TPL_START', '{', got ']'",
rawMessage: "Parse error on line 2:\nfoo\\n .[bar =]\n-------------^\nExpecting '$', 'IDENT', '$IDENT', '?', 'FUNCTION', 'NOT', 'NO', '-', '+', 'IS', '@', '#', '$$', 'STRING', 'NUMBER', 'REGEXP', 'LITERAL', '[', '(', '.', '.(', '.[', '..', '..(', 'METHOD(', '$METHOD(', 'TEMPLATE', 'TPL_START', '{', got ']'",
text: ']',
token: ']',
expected: ["'$'", 'ident', '$ident', "'?'", "'<'", "'=>'", "'not'", "'no'", "'-'", "'+'", "'is'", "'@'", "'#'", "'$$'", 'string', 'number', 'regexp', "'true'", "'false'", "'null'", "'undefined'", "'NaN'", "'Infinity'", "'['", "'('", "'.'", "'.('", "'.['", "'..'", "'..('", "'method('", "'$method('", 'template', "'{'"],
expected: ["'$'", 'ident', '$ident', "'?'", "'=>'", "'not'", "'no'", "'-'", "'+'", "'is'", "'@'", "'#'", "'$$'", 'string', 'number', 'regexp', "'true'", "'false'", "'null'", "'undefined'", "'NaN'", "'Infinity'", "'['", "'('", "'.'", "'.('", "'.['", "'..'", "'..('", "'method('", "'$method('", 'template', "'{'"],
loc: {
range: [12, 13],
start: {
Expand Down

0 comments on commit e210489

Please sign in to comment.