Skip to content

Commit aff9e9b

Browse files
authored
Merge pull request #212 from gitKrystan/fix-more-bugs
2 parents f95f948 + 0a5c894 commit aff9e9b

File tree

10 files changed

+216
-123
lines changed

10 files changed

+216
-123
lines changed

src/parse/index.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { traverse } from '@babel/core';
2-
import type { Node, ObjectExpression, StaticBlock } from '@babel/types';
2+
import type {
3+
BlockStatement,
4+
Node,
5+
ObjectExpression,
6+
StaticBlock,
7+
} from '@babel/types';
38
import type { Parsed as RawGlimmerTemplate } from 'content-tag';
49
import { Preprocessor } from 'content-tag';
510
import type { Parser } from 'prettier';
@@ -15,7 +20,7 @@ const p = new Preprocessor();
1520

1621
/** Converts a node into a GlimmerTemplate node */
1722
function convertNode(
18-
node: ObjectExpression | StaticBlock,
23+
node: BlockStatement | ObjectExpression | StaticBlock,
1924
rawTemplate: RawGlimmerTemplate,
2025
): void {
2126
node.extra = Object.assign(node.extra ?? {}, {
@@ -31,27 +36,34 @@ function convertAst(ast: Node, rawTemplates: RawGlimmerTemplate[]): void {
3136
traverse(ast, {
3237
enter(path) {
3338
const { node } = path;
34-
if (node.type === 'ObjectExpression' || node.type === 'StaticBlock') {
39+
if (
40+
node.type === 'BlockStatement' ||
41+
node.type === 'ObjectExpression' ||
42+
node.type === 'StaticBlock'
43+
) {
3544
const { range } = node;
3645
assert('expected range', range);
3746
const [start, end] = range;
3847

3948
const templateIndex = unprocessedTemplates.findIndex(
4049
(t) =>
41-
(node.type === 'StaticBlock' &&
42-
t.range.start === start &&
43-
t.range.end === end) ||
50+
(t.range.start === start && t.range.end === end) ||
4451
(node.type === 'ObjectExpression' &&
52+
node.extra?.['parenthesized'] === true &&
4553
t.range.start === start - 1 &&
4654
t.range.end === end + 1),
4755
);
48-
const rawTemplate = unprocessedTemplates.splice(templateIndex, 1)[0];
49-
50-
if (!rawTemplate) {
56+
if (templateIndex > -1) {
57+
const rawTemplate = unprocessedTemplates.splice(templateIndex, 1)[0];
58+
if (!rawTemplate) {
59+
throw new Error(
60+
'expected raw template because splice index came from findIndex',
61+
);
62+
}
63+
convertNode(node, rawTemplate);
64+
} else {
5165
return null;
5266
}
53-
54-
convertNode(node, rawTemplate);
5567
}
5668

5769
return null;

src/parse/preprocess.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@ const EMPTY_SPACE = ' ';
1010
* Returns the resulting string.
1111
*/
1212
function replaceByteRange(
13-
original: string,
13+
originalBuffer: Buffer,
1414
range: { start: number; end: number },
1515
options: { prefix: string; suffix: string },
1616
): string {
17-
// Convert the original string and the prefix, suffix to buffers for byte manipulation
18-
const originalBuffer = Buffer.from(original);
1917
const prefixBuffer = Buffer.from(options.prefix);
2018
const suffixBuffer = Buffer.from(options.suffix);
2119

@@ -27,7 +25,11 @@ function replaceByteRange(
2725
prefixBuffer.length + suffixBuffer.length > range.end - range.start
2826
) {
2927
throw new Error(
30-
`Invalid byte range:\n\tstart=${range.start}\n\tend=${range.end}\n\tprefix=${options.prefix}\n\tsuffix=${options.suffix}\n\tstring=\n\t${original}`,
28+
`Invalid byte range:\n\tstart=${range.start}\n\tend=${
29+
range.end
30+
}\n\tprefix=${options.prefix}\n\tsuffix=${
31+
options.suffix
32+
}\n\tstring=\n\t${originalBuffer.toString()}`,
3133
);
3234
}
3335

@@ -70,6 +72,8 @@ export function preprocessTemplateRange(
7072
rawTemplate: RawGlimmerTemplate,
7173
code: string,
7274
): string {
75+
const codeBuffer = Buffer.from(code);
76+
7377
let prefix: string;
7478
let suffix: string;
7579

@@ -78,12 +82,22 @@ export function preprocessTemplateRange(
7882
prefix = 'static{';
7983
suffix = '}';
8084
} else {
81-
// Replace with ObjectExpression
82-
prefix = '({';
83-
suffix = '})';
85+
// Replace with BlockStatement or ObjectExpression
86+
prefix = '{';
87+
suffix = '}';
88+
89+
const nextToken = codeBuffer
90+
.subarray(rawTemplate.range.end)
91+
.toString()
92+
.match(/\S+/);
93+
if (nextToken && nextToken[0] === 'as') {
94+
// Replace with parenthesized ObjectExpression
95+
prefix = '(' + prefix;
96+
suffix = suffix + ')';
97+
}
8498
}
8599

86-
return replaceByteRange(code, rawTemplate.range, {
100+
return replaceByteRange(codeBuffer, rawTemplate.range, {
87101
prefix,
88102
suffix,
89103
});

src/print/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,14 @@ export const printer: Printer<Node | undefined> = {
108108
embedOptions as Options,
109109
);
110110

111-
return printTemplateTag(content);
111+
const printed = printTemplateTag(content);
112+
saveCurrentPrintOnSiblingNode(path, printed);
113+
return printed;
112114
} catch (error) {
113115
console.error(error);
114-
return printRawText(path, embedOptions as Options);
116+
const printed = [printRawText(path, embedOptions as Options)];
117+
saveCurrentPrintOnSiblingNode(path, printed);
118+
return printed;
115119
}
116120
}
117121

src/types/glimmer.ts

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type {
2+
BlockStatement,
23
ExportDefaultDeclaration,
34
ExpressionStatement,
45
Node,
@@ -8,7 +9,11 @@ import type {
89
} from '@babel/types';
910
import type { Parsed as RawGlimmerTemplate } from 'content-tag';
1011

11-
type GlimmerTemplate = (ObjectExpression | StaticBlock) & {
12+
type GlimmerTemplateProperties = (
13+
| BlockStatement
14+
| ObjectExpression
15+
| StaticBlock
16+
) & {
1217
/**
1318
* Range of the contents, inclusive of inclusive of the
1419
* `<template></template>` tags.
@@ -28,14 +33,16 @@ type GlimmerTemplate = (ObjectExpression | StaticBlock) & {
2833
};
2934
};
3035

36+
type GlimmerTemplate = (BlockStatement | ObjectExpression | StaticBlock) &
37+
GlimmerTemplateProperties;
38+
3139
/** Returns true if the node is a GlimmerTemplate. */
3240
export function isGlimmerTemplate(node: Node): node is Node & GlimmerTemplate {
3341
return node.extra?.['isGlimmerTemplate'] === true;
3442
}
3543

3644
export type GlimmerTemplateParent =
37-
| GlimmerExpressionStatement
38-
| GlimmerExpressionStatementTS
45+
| GlimmerStatementTS
3946
| GlimmerExportDefaultDeclaration
4047
| GlimmerExportDefaultDeclarationTS;
4148

@@ -49,36 +56,15 @@ export function isGlimmerTemplateParent(
4956
if (!node) return false;
5057

5158
return (
52-
isGlimmerTemplate(node) ||
53-
isGlimmerExpressionStatement(node) ||
54-
isGlimmerExpressionStatementTS(node) ||
59+
isGlimmerStatementTS(node) ||
5560
isGlimmerExportDefaultDeclaration(node) ||
5661
isGlimmerExportDefaultDeclarationTS(node)
5762
);
5863
}
5964

60-
type GlimmerExpressionStatement = ExpressionStatement & {
61-
expression: GlimmerTemplate;
62-
};
63-
64-
/**
65-
* Type predicate for:
66-
*
67-
* ```gts
68-
* <template></template>;
69-
* ```
70-
*/
71-
function isGlimmerExpressionStatement(
72-
node: Node,
73-
): node is GlimmerExpressionStatement {
74-
return (
75-
node.type === 'ExpressionStatement' && isGlimmerTemplate(node.expression)
76-
);
77-
}
78-
79-
type GlimmerExpressionStatementTS = ExpressionStatement & {
65+
type GlimmerStatementTS = ExpressionStatement & {
8066
expression: TSAsExpression & {
81-
expression: GlimmerTemplate;
67+
expression: ObjectExpression & GlimmerTemplateProperties;
8268
};
8369
};
8470

@@ -89,18 +75,17 @@ type GlimmerExpressionStatementTS = ExpressionStatement & {
8975
* <template></template> as TemplateOnlyComponent<Signature>
9076
* ```
9177
*/
92-
function isGlimmerExpressionStatementTS(
93-
node: Node,
94-
): node is GlimmerExpressionStatementTS {
78+
function isGlimmerStatementTS(node: Node): node is GlimmerStatementTS {
9579
return (
9680
node.type === 'ExpressionStatement' &&
9781
node.expression.type === 'TSAsExpression' &&
82+
node.expression.expression.type === 'ObjectExpression' &&
9883
isGlimmerTemplate(node.expression.expression)
9984
);
10085
}
10186

10287
type GlimmerExportDefaultDeclaration = ExportDefaultDeclaration & {
103-
declaration: GlimmerTemplate;
88+
declaration: ObjectExpression & GlimmerTemplateProperties;
10489
};
10590

10691
/**
@@ -115,13 +100,14 @@ function isGlimmerExportDefaultDeclaration(
115100
): node is GlimmerExportDefaultDeclaration {
116101
return (
117102
node.type === 'ExportDefaultDeclaration' &&
103+
node.declaration.type === 'ObjectExpression' &&
118104
isGlimmerTemplate(node.declaration)
119105
);
120106
}
121107

122108
type GlimmerExportDefaultDeclarationTS = ExportDefaultDeclaration & {
123109
declaration: TSAsExpression & {
124-
expression: GlimmerTemplate;
110+
expression: ObjectExpression & GlimmerTemplateProperties;
125111
};
126112
};
127113

@@ -138,6 +124,7 @@ function isGlimmerExportDefaultDeclarationTS(
138124
return (
139125
node.type === 'ExportDefaultDeclaration' &&
140126
node.declaration.type === 'TSAsExpression' &&
127+
node.declaration.expression.type === 'ObjectExpression' &&
141128
isGlimmerTemplate(node.declaration.expression)
142129
);
143130
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const foo = {}
2+
<template>
3+
hello
4+
</template>

tests/unit-tests/__snapshots__/format.test.ts.snap

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,12 @@ exports[`format > config > default > it formats ../cases/gjs/one-line.gjs 1`] =
168168
"
169169
`;
170170
171+
exports[`format > config > default > it formats ../cases/gjs/preceded-by-object.gjs 1`] = `
172+
"const foo = {};
173+
<template>hello</template>
174+
"
175+
`;
176+
171177
exports[`format > config > default > it formats ../cases/gjs/prettier-ignore/component-class.gjs 1`] = `
172178
"import Component from "@glimmer/component";
173179

0 commit comments

Comments
 (0)