Skip to content

Commit

Permalink
Merge pull request #195 from gitKrystan/cherry-c89b8141f7074e46bf44f7…
Browse files Browse the repository at this point in the history
…bb3fb58c89c5189067
  • Loading branch information
gitKrystan authored Dec 6, 2023
2 parents 92277b7 + 86499f0 commit b0a0335
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 118 deletions.
4 changes: 2 additions & 2 deletions examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"private": true,
"version": "0.0.0",
"scripts": {
"example": "pnpm exec prettier . --write",
"example-debug": "pnpm exec prettier . --write --log-level debug",
"example": "pnpm prettier ./input --write",
"example-debug": "pnpm prettier ./input --write --log-level debug",
"test": "node ./bin/test.mjs"
},
"dependencies": {
Expand Down
69 changes: 30 additions & 39 deletions src/parse/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import { parsers as babelParsers } from 'prettier/plugins/babel.js';

import { PRINTER_NAME } from '../config';
import type { Options } from '../options.js';
import type { GlimmerTemplateInfo, RawGlimmerTemplate } from '../types/glimmer';
import type { GlimmerTemplate, RawGlimmerTemplate } from '../types/glimmer';
import { isDefaultTemplate } from '../types/glimmer';
import { assert } from '../utils';
import { normalizeWhitespace } from './whitespace';
import { preprocessTemplateRange } from './preprocess';

const typescript = babelParsers['babel-ts'] as Parser<Node | undefined>;
const p = new Preprocessor();
Expand All @@ -24,19 +24,23 @@ const p = new Preprocessor();
function convertNode(
path: NodePath,
node: BlockStatement | ObjectExpression | StaticBlock,
templateInfo: GlimmerTemplateInfo,
rawTemplate: RawGlimmerTemplate,
): void {
Object.assign(node, templateInfo, {
type: 'FunctionDeclaration',
extra: Object.assign(node.extra ?? {}, templateInfo.extra, {
isGlimmerTemplate: true,
isDefaultTemplate: isDefaultTemplate(path),
}),
const cast = node as unknown as GlimmerTemplate;
// HACK: Changing the node type here isn't recommended by babel
cast.type = 'FunctionDeclaration';
cast.range = [rawTemplate.range.start, rawTemplate.range.end];
cast.start = rawTemplate.range.start;
cast.end = rawTemplate.range.end;
cast.extra = Object.assign(node.extra ?? {}, {
isGlimmerTemplate: true as const,
isDefaultTemplate: isDefaultTemplate(path),
template: rawTemplate,
});
}

/** Traverses the AST and replaces the transformed template parts with other AST */
function convertAst(ast: Node, templateInfos: GlimmerTemplateInfo[]): void {
function convertAst(ast: Node, rawTemplates: RawGlimmerTemplate[]): void {
let counter = 0;

traverse(ast, {
Expand All @@ -49,27 +53,28 @@ function convertAst(ast: Node, templateInfos: GlimmerTemplateInfo[]): void {
) {
const { range } = node;
assert('expected range', range);
const [start, end] = range;

const templateInfo = templateInfos.find(
(p) =>
(p.range[0] === range[0] && p.range[1] === range[1]) ||
(p.range[0] === range[0] - 1 && p.range[1] === range[1] + 1) ||
(p.range[0] === range[0] && p.range[1] === range[1] + 1),
const rawTemplate = rawTemplates.find(
(t) =>
(t.range.start === start && t.range.end === end) ||
(t.range.start === start - 1 && t.range.end === end + 1) ||
(t.range.start === start && t.range.end === end + 1),
);

if (!templateInfo) {
if (!rawTemplate) {
return null;
}

convertNode(path, node, templateInfo);
convertNode(path, node, rawTemplate);

counter++;
}
return null;
},
});

if (counter !== templateInfos.length) {
if (counter !== rawTemplates.length) {
throw new Error('failed to process all templates');
}
}
Expand All @@ -81,30 +86,16 @@ function convertAst(ast: Node, templateInfos: GlimmerTemplateInfo[]): void {
*/
function preprocess(code: string): {
code: string;
templateInfos: GlimmerTemplateInfo[];
rawTemplates: RawGlimmerTemplate[];
} {
const templateNodes = p.parse(code) as RawGlimmerTemplate[];
const templateInfos: GlimmerTemplateInfo[] = [];
let output = code;
for (const templateNode of templateNodes) {
output = normalizeWhitespace(templateNode, code, output);
const rawTemplates = p.parse(code) as RawGlimmerTemplate[];

const template = code.slice(
templateNode.contentRange.start,
templateNode.contentRange.end,
);
const templateInfo: GlimmerTemplateInfo = {
range: [templateNode.range.start, templateNode.range.end],
start: templateNode.range.start,
end: templateNode.range.end,
extra: {
template,
},
};
templateInfos.push(templateInfo);
let output = code;
for (const rawTemplate of rawTemplates) {
output = preprocessTemplateRange(rawTemplate, code, output);
}

return { templateInfos, code: output };
return { rawTemplates, code: output };
}

export const parser: Parser<Node | undefined> = {
Expand All @@ -115,7 +106,7 @@ export const parser: Parser<Node | undefined> = {
const preprocessed = preprocess(code);
const ast = await typescript.parse(preprocessed.code, options);
assert('expected ast', ast);
convertAst(ast, preprocessed.templateInfos);
convertAst(ast, preprocessed.rawTemplates);
return ast;
},
};
49 changes: 49 additions & 0 deletions src/parse/preprocess.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { RawGlimmerTemplate } from '../types/glimmer';

function replaceRange(
original: string,
range: { start: number; end: number },
substitute: string,
): string {
return (
original.slice(0, range.start) + substitute + original.slice(range.end)
);
}

/**
* Replace the template with a parsable placeholder that takes up the same
* range.
*/
export function preprocessTemplateRange(
rawTemplate: RawGlimmerTemplate,
originalCode: string,
currentCode: string,
): string {
let prefix: string;
let suffix: string;

if (rawTemplate.type === 'class-member') {
prefix = 'static{`';
suffix = '`}';
} else {
prefix = '{';
suffix = '}';
const nextWord = originalCode.slice(rawTemplate.range.end).match(/\S+/);
if (nextWord && nextWord[0] === 'as') {
prefix = '(' + prefix;
suffix = suffix + ')';
} else if (!nextWord || ![',', ')'].includes(nextWord[0][0] || '')) {
suffix += ';';
}
}

const totalLength = rawTemplate.range.end - rawTemplate.range.start;
const placeholderLength = totalLength - prefix.length - suffix.length;
const placeholder = ' '.repeat(placeholderLength);

return replaceRange(
currentCode,
rawTemplate.range,
`${prefix}${placeholder}${suffix}`,
);
}
54 changes: 0 additions & 54 deletions src/parse/whitespace.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/print/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export const printer: Printer<Node | undefined> = {
if (node && isGlimmerTemplate(node)) {
try {
const content = await printTemplateContent(
node.extra.template,
node.extra.template.contents,
textToDoc,
embedOptions as Options,
);
Expand Down
25 changes: 3 additions & 22 deletions src/types/glimmer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { NodePath } from '@babel/core';
import type { Comment, Node } from '@babel/types';
import type { Node } from '@babel/types';

/** The raw GlimmerTemplate node as parsed by the content-tag parser. */
export interface RawGlimmerTemplate {
Expand Down Expand Up @@ -41,29 +41,9 @@ export interface RawGlimmerTemplate {
};
}

export interface GlimmerTemplateInfo {
/**
* Range of the contents, inclusive of inclusive of the
* `<template></template>` tags.
*/
range: [start: number, end: number];

/** Beginning of the range, before the opening `<template>` tag. */
start: number;

/** End of the range, after the closing `</template>` tag. */
end: number;

extra: {
template: string;
};
}

export interface GlimmerTemplate {
type: 'FunctionDeclaration';

leadingComments: Comment[];

/**
* Range of the contents, inclusive of inclusive of the
* `<template></template>` tags.
Expand All @@ -79,7 +59,8 @@ export interface GlimmerTemplate {
extra: {
isGlimmerTemplate: true;
isDefaultTemplate: boolean;
template: string;
template: RawGlimmerTemplate;
[key: string]: unknown;
};
}

Expand Down

0 comments on commit b0a0335

Please sign in to comment.