Skip to content

Commit bae23cb

Browse files
committed
fix(rewriter): glimmer requires that subexpressions be helper invocations.
1 parent 55882c3 commit bae23cb

File tree

3 files changed

+32
-27
lines changed

3 files changed

+32
-27
lines changed

packages/glimmer-templates/src/ClassnamesHelperGenerator.ts

+26-11
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ function constructDependency(stateExpr: Dependency, rewrite: IndexedClassRewrite
161161

162162
function constructConditional(stateExpr: Conditional<BooleanAST> & HasState, _rewrite: IndexedClassRewrite<BlockObject>): AST.Expression[] {
163163
let expr = new Array<AST.Expression>();
164-
expr.push(stateExpr.condition);
164+
expr.push(moustacheToBooleanExpression(stateExpr.condition));
165165
return expr;
166166
}
167167

@@ -207,28 +207,43 @@ function constructSwitch(stateExpr: Switch<StringAST> & HasGroup, rewrite: Index
207207
return expr;
208208
}
209209

210+
function moustacheToBooleanExpression(booleanExpression: BooleanAST): AST.Expression {
211+
if (booleanExpression.type === "MustacheStatement") {
212+
return moustacheToExpression(booleanExpression);
213+
} else {
214+
return booleanExpression;
215+
}
216+
}
217+
218+
function moustacheToExpression(expr: AST.MustacheStatement): AST.Expression {
219+
if (expr.path.type === "PathExpression") {
220+
if (expr.params.length === 0 && expr.hash.pairs.length === 0) {
221+
debug("converting", expr.path.original, "to path");
222+
return expr.path;
223+
} else {
224+
debug("converting", expr.path.original, "to sexpr");
225+
return builders.sexpr(expr.path, expr.params, expr.hash);
226+
}
227+
} else {
228+
debug("preserving literal", expr.path.original, "as literal");
229+
return expr.path;
230+
}
231+
}
232+
210233
function moustacheToStringExpression(stringExpression: StringAST): AST.Expression {
211234
if (stringExpression.type === "ConcatStatement") {
212235
return builders.sexpr(builders.path("/css-blocks/components/concat"),
213236
stringExpression.parts.reduce( (arr, val) => {
214237
if (val.type === 'TextNode') {
215238
arr.push(builders.string(val.chars));
216239
} else {
217-
arr.push(moustacheToStringExpression(val));
240+
arr.push(val.path);
218241
}
219242
return arr;
220243
}, new Array<AST.Expression>())
221244
);
222245
} else {
223-
let { path, params, hash } = stringExpression;
224-
if (path.type === "PathExpression") {
225-
return builders.sexpr(path, params, hash);
226-
} else {
227-
if (params.length > 0) {
228-
throw new Error("Unsure how to deal with this node.");
229-
}
230-
return path;
231-
}
246+
return moustacheToExpression(stringExpression);
232247
}
233248
}
234249

packages/glimmer-templates/src/ElementAnalyzer.ts

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AST, builders} from '@glimmer/syntax';
1+
import { AST } from '@glimmer/syntax';
22
import {
33
Block,
44
QueryKeySelector,
@@ -14,7 +14,7 @@ import { objectValues, assertNever } from "@opticss/util";
1414

1515
export type TernaryExpression = AST.Expression;
1616
export type StringExpression = AST.MustacheStatement | AST.ConcatStatement;
17-
export type BooleanExpression = AST.Expression;
17+
export type BooleanExpression = AST.Expression | AST.MustacheStatement;
1818
export type TemplateElement = ElementAnalysis<BooleanExpression, StringExpression, TernaryExpression>;
1919
export type AnalysisElement = ElementAnalysis<null, null, null>;
2020

@@ -231,17 +231,7 @@ export class ElementAnalyzer {
231231
throw cssBlockError(`The dynamic statement for a boolean state must be set to a mustache statement with no additional text surrounding it.`, dynamicSubState, this.template);
232232
}
233233
if (analysis.storeConditionals) {
234-
let expr: AST.Expression;
235-
let {path, params, hash} = dynamicSubState;
236-
if (path.type === "PathExpression") {
237-
expr = builders.sexpr(path, params, hash);
238-
} else {
239-
if (params.length > 0) {
240-
throw cssBlockError(`Unsure how to handle this node.`, dynamicSubState, this.template);
241-
}
242-
expr = path;
243-
}
244-
analysis.element.addDynamicState(container, states[0], expr);
234+
analysis.element.addDynamicState(container, states[0], dynamicSubState);
245235
} else {
246236
analysis.element.addDynamicState(container, states[0], null);
247237
}

packages/glimmer-templates/test/template-rewrite-test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ describe('Template Rewriting', function() {
8282
// TODO why is `f` class both static and dynamic?
8383
assert.deepEqual(minify(res), minify(`
8484
<div class="b">
85-
<h1 class="e">Hello, <span class="f c {{/css-blocks/components/classnames 2 3 2 (isThick) 1 2 4 2 1 (textStyle) "bold" 1 0 "italic" 1 1 "g" 0 "f" 1 "d" 2}}">World</span>!</h1>
85+
<h1 class="e">Hello, <span class="f c {{/css-blocks/components/classnames 2 3 2 isThick 1 2 4 2 1 textStyle "bold" 1 0 "italic" 1 1 "g" 0 "f" 1 "d" 2}}">World</span>!</h1>
8686
</div>`));
8787
assert.deepEqual(minify(result.css), minify(`
8888
.b { color: red; }
@@ -107,7 +107,7 @@ describe('Template Rewriting', function() {
107107
// TODO: why is `f` both static and dynamic on the same element
108108
assert.deepEqual(minify(res), minify(`
109109
<div class="b">
110-
<h1 class="e">Hello, <span class="f h {{/css-blocks/components/classnames 3 4 0 isWorld 1 2 0 3 1 2 (eq isThick 1) 1 3 4 2 1 (textStyle) "bold" 1 0 "italic" 1 1 "g" 0 "f" 1 "c" 2 "d" 3}}">World</span>!</h1>
110+
<h1 class="e">Hello, <span class="f h {{/css-blocks/components/classnames 3 4 0 isWorld 1 2 0 3 1 2 (eq isThick 1) 1 3 4 2 1 textStyle "bold" 1 0 "italic" 1 1 "g" 0 "f" 1 "c" 2 "d" 3}}">World</span>!</h1>
111111
<div class={{/css-blocks/components/classnames 1 2 0 isWorld 1 1 1 0 "f" 0 "c" 1}}>World</div>
112112
<div class={{/css-blocks/components/classnames 1 2 0 isWorld 1 0 1 1 "f" 0 "c" 1}}>World</div>
113113
<div class={{/css-blocks/components/classnames 1 1 0 isWorld 0 1 0 "c" 0}}>World</div>
@@ -125,7 +125,7 @@ describe('Template Rewriting', function() {
125125
let { css, ast } = result;
126126
let res = print(ast);
127127
assert.deepEqual(minify(res), minify(`
128-
<div class="a {{/css-blocks/components/classnames 1 1 2 (isLoading) 1 0 "b" 0}}">
128+
<div class="a {{/css-blocks/components/classnames 1 1 2 isLoading 1 0 "b" 0}}">
129129
<aside class="g h c d"> </aside>
130130
<article class="i {{/css-blocks/components/classnames 1 2 0 isRecommended 1 1 1 0 "e" 0 "f" 1}}"> </article>
131131
</div>

0 commit comments

Comments
 (0)