Skip to content

Commit

Permalink
feature: add should keyword (#5)
Browse files Browse the repository at this point in the history
* Add should keyword

* Fix bad spelling

Co-authored-by: Giorgio Bellisario <{ID}+{username}@users.noreply.github.com>
  • Loading branch information
Bellisario and Giorgio Bellisario committed Jun 25, 2022
1 parent 9481390 commit beb1a4c
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 0 deletions.
19 changes: 19 additions & 0 deletions README.md
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions packages/keyword-should/fixture/await-should.gs
@@ -0,0 +1 @@
should await hello()
3 changes: 3 additions & 0 deletions packages/keyword-should/fixture/await-should.js
@@ -0,0 +1,3 @@
try {
await hello();
} catch (e) {};
4 changes: 4 additions & 0 deletions packages/keyword-should/fixture/not-supported.gs
@@ -0,0 +1,4 @@
should {
var a = "hello"
console.log(a)
}
1 change: 1 addition & 0 deletions packages/keyword-should/fixture/should.gs
@@ -0,0 +1 @@
should hello()
3 changes: 3 additions & 0 deletions packages/keyword-should/fixture/should.js
@@ -0,0 +1,3 @@
try {
hello();
} catch (e) {};
99 changes: 99 additions & 0 deletions 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');
}
};
}

19 changes: 19 additions & 0 deletions 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();
});

0 comments on commit beb1a4c

Please sign in to comment.