From 8d9dd4c6e065696bdfb0f62db73b8d68e6d8a4a2 Mon Sep 17 00:00:00 2001 From: scott Date: Sat, 6 Mar 2021 14:50:44 -0600 Subject: [PATCH] Add not keyword --- .../passes/1-normalization/keywords/call.ts | 3 +- .../1-normalization/keywords/utils/logical.ts | 40 +++++++++++++++++++ .../test/keywords/logical-test.ts | 29 +++++++++++++- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/call.ts b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/call.ts index c2188da989..2d2141941a 100644 --- a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/call.ts +++ b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/call.ts @@ -8,7 +8,7 @@ import { equalKeyword, notEqualKeyword } from './utils/equality'; import { hasBlockKeyword } from './utils/has-block'; import { ifUnlessInlineKeyword } from './utils/if-unless'; import { logKeyword } from './utils/log'; -import { andKeyword, orKeyword } from './utils/logical'; +import { andKeyword, notKeyword, orKeyword } from './utils/logical'; export const CALL_KEYWORDS = keywords('Call') .kw('has-block', hasBlockKeyword('has-block')) @@ -23,6 +23,7 @@ export const CALL_KEYWORDS = keywords('Call') .kw('gte', comparisonKeyword('gte'), { strictOnly: true }) .kw('and', andKeyword) .kw('or', orKeyword) + .kw('not', notKeyword) .kw('if', ifUnlessInlineKeyword('if')) .kw('unless', ifUnlessInlineKeyword('unless')) .kw('component', curryKeyword(CurriedType.Component)) diff --git a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/utils/logical.ts b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/utils/logical.ts index 26a98c6756..c01c40a5f7 100644 --- a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/utils/logical.ts +++ b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/utils/logical.ts @@ -65,3 +65,43 @@ export const orKeyword: KeywordDelegate< assert: assertOrKeyword, translate: translateOrKeyword, }; + +function assertNotKeyword(node: GenericKeywordNode): Result { + let { + args: { named, positional }, + } = node; + + if (named && !named.isEmpty()) { + return Err(generateSyntaxError(`(not) does not take any named arguments`, node.loc)); + } + + if (positional?.size > 1) { + return Err(generateSyntaxError(`(not) only accepts 1 argument`, node.loc)); + } + + let value = positional?.nth(0); + + if (!value) { + return Err(generateSyntaxError(`(not) requires 1 argument`, node.loc)); + } + + return Ok(value); +} + +function translateNotKeyword( + { node, state }: { node: ASTv2.CallExpression; state: NormalizationState }, + value: ASTv2.ExpressionNode +): Result { + return VISIT_EXPRS.visit(value, state).mapOk( + (result) => new mir.Not({ value: result, loc: node.loc }) + ); +} + +export const notKeyword: KeywordDelegate< + ASTv2.CallExpression | ASTv2.AppendContent, + ASTv2.ExpressionNode, + mir.Not +> = { + assert: assertNotKeyword, + translate: translateNotKeyword, +}; diff --git a/packages/@glimmer/integration-tests/test/keywords/logical-test.ts b/packages/@glimmer/integration-tests/test/keywords/logical-test.ts index e353ccf221..4a5114107c 100644 --- a/packages/@glimmer/integration-tests/test/keywords/logical-test.ts +++ b/packages/@glimmer/integration-tests/test/keywords/logical-test.ts @@ -1,4 +1,4 @@ -import { RenderTest, test, jitSuite } from '../..'; +import { RenderTest, test, jitSuite, syntaxErrorFor } from '../..'; class AndTest extends RenderTest { static suiteName = '{{and}} keyword'; @@ -119,3 +119,30 @@ class OrTest extends RenderTest { } jitSuite(OrTest); + +class NotTest extends RenderTest { + static suiteName = '{{not}} keyword'; + + @test + ['it works']() { + this.render(`{{not 1}}`); + + this.assertHTML('false'); + } + + @test + ['it works falsey']() { + this.render(`{{not 0}}`); + + this.assertHTML('true'); + } + + @test + ['it errors with too many arguments']() { + this.assert.throws(() => { + this.render(`{{not 1 2}}`); + }, syntaxErrorFor('(not) only accepts 1 argument', '{{not 1 2}}', 'an unknown module', 1, 0)); + } +} + +jitSuite(NotTest);