From beb1a4c098e8069fdb42ea107db4062e3c86bb99 Mon Sep 17 00:00:00 2001 From: Giorgio Bellisario <72039923+Bellisario@users.noreply.github.com> Date: Sat, 25 Jun 2022 21:33:33 +0200 Subject: [PATCH] feature: add should keyword (#5) * Add should keyword * Fix bad spelling Co-authored-by: Giorgio Bellisario <{ID}+{username}@users.noreply.github.com> --- README.md | 19 ++++ .../keyword-should/fixture/await-should.gs | 1 + .../keyword-should/fixture/await-should.js | 3 + .../keyword-should/fixture/not-supported.gs | 4 + packages/keyword-should/fixture/should.gs | 1 + packages/keyword-should/fixture/should.js | 3 + packages/keyword-should/index.js | 99 +++++++++++++++++++ packages/keyword-should/index.spec.js | 19 ++++ 8 files changed, 149 insertions(+) create mode 100644 packages/keyword-should/fixture/await-should.gs create mode 100644 packages/keyword-should/fixture/await-should.js create mode 100644 packages/keyword-should/fixture/not-supported.gs create mode 100644 packages/keyword-should/fixture/should.gs create mode 100644 packages/keyword-should/fixture/should.js create mode 100644 packages/keyword-should/index.js create mode 100644 packages/keyword-should/index.spec.js diff --git a/README.md b/README.md index 3485d83..b4b1a52 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,25 @@ import tryToCatch from 'try-catch'; const [error, result] = await tryToCatch(1, 2, 3); ``` +### `should` + +`should` can be used as an expression. +This keyword is useful if you want to prevent a function call (also async) to throw an error because you don't need to have any result and the real execution is just optional (so runs if supported). + +```gs +should hello() +``` + +Is the same as: + +```js +try { + hello(); +} catch (e) {}; +``` + +> Warning: this feature can be helpful but also dangerous especially if you're debugging your application. In fact, this is made to be used as an optional function call (ex. should load content, but not necessary and knowing this feature is optional), if you call a function in this way while debugging, no error will be printed and the application will continue run as nothing happened. + ### `if` You can omit parens. But you must use braces in this case. diff --git a/packages/keyword-should/fixture/await-should.gs b/packages/keyword-should/fixture/await-should.gs new file mode 100644 index 0000000..0e3d08a --- /dev/null +++ b/packages/keyword-should/fixture/await-should.gs @@ -0,0 +1 @@ +should await hello() \ No newline at end of file diff --git a/packages/keyword-should/fixture/await-should.js b/packages/keyword-should/fixture/await-should.js new file mode 100644 index 0000000..60c4b0f --- /dev/null +++ b/packages/keyword-should/fixture/await-should.js @@ -0,0 +1,3 @@ +try { + await hello(); +} catch (e) {}; \ No newline at end of file diff --git a/packages/keyword-should/fixture/not-supported.gs b/packages/keyword-should/fixture/not-supported.gs new file mode 100644 index 0000000..07a0d8e --- /dev/null +++ b/packages/keyword-should/fixture/not-supported.gs @@ -0,0 +1,4 @@ +should { + var a = "hello" + console.log(a) +} \ No newline at end of file diff --git a/packages/keyword-should/fixture/should.gs b/packages/keyword-should/fixture/should.gs new file mode 100644 index 0000000..4d3b5dc --- /dev/null +++ b/packages/keyword-should/fixture/should.gs @@ -0,0 +1 @@ +should hello() \ No newline at end of file diff --git a/packages/keyword-should/fixture/should.js b/packages/keyword-should/fixture/should.js new file mode 100644 index 0000000..4610fd3 --- /dev/null +++ b/packages/keyword-should/fixture/should.js @@ -0,0 +1,3 @@ +try { + hello(); +} catch (e) {}; \ No newline at end of file diff --git a/packages/keyword-should/index.js b/packages/keyword-should/index.js new file mode 100644 index 0000000..9483428 --- /dev/null +++ b/packages/keyword-should/index.js @@ -0,0 +1,99 @@ +import {types} from 'putout'; +import { + addKeyword, + TokenType, + tokTypes as tt, +} from '../operator/index.js'; + +const { + isCallExpression, + isAwaitExpression, +} = types; + +export default function newSpeak(Parser) { + const {keywordTypes} = Parser.acorn; + keywordTypes.should = new TokenType('should', { + keyword: 'should', + }); + + return class extends Parser { + parse() { + this.keywords = addKeyword('should', this.keywords); + return super.parse(); + } + parseStatement(context, topLevel, exports) { + if (this.type === keywordTypes.should) { + return this.parseShould(); + } + + return super.parseStatement(context, topLevel, exports); + } + + parseShould() { + this.next(); + + const node = super.startNode(); + + if (this.type === tt.braceL) + return this.raise(this.start, `After 'should' only 'await' and 'function call' can come, brakets are not suppoted`); + + const expression = this.parseExpression(); + + if (isCallExpression(expression)) + node.expression = { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: expression.callee, + arguments: expression.arguments.slice(), + }, + }], + }, + handler: { + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'e', + }, + body: { + type: 'BlockStatement', + body: [], + }, + }, + }; + + else if (isAwaitExpression(expression)) + node.expression = { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression, + }], + }, + handler: { + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'e', + }, + body: { + type: 'BlockStatement', + body: [], + }, + }, + }; + + else + this.raise(this.start, `After 'should' only 'await' and 'function call' can come`); + + return super.finishNode(node, 'ExpressionStatement'); + } + }; +} + diff --git a/packages/keyword-should/index.spec.js b/packages/keyword-should/index.spec.js new file mode 100644 index 0000000..2d815b3 --- /dev/null +++ b/packages/keyword-should/index.spec.js @@ -0,0 +1,19 @@ +import {createTest} from '../test/index.js'; +import keywordFn from './index.js'; + +const test = createTest(import.meta.url, keywordFn); + +test('goldstein: keyword: should', (t) => { + t.compile('should'); + t.end(); +}); + +test('goldstein: keyword: should (with await)', (t) => { + t.compile('await-should'); + t.end(); +}); + +test('goldstein: keyword: should (brakets)', (t) => { + t.raise('not-supported', `After 'should' only 'await' and 'function call' can come, brakets are not suppoted (1:7)`); + t.end(); +});