Skip to content
This repository has been archived by the owner on Dec 8, 2024. It is now read-only.

Account for comments in preprocessor for proposals #368

Merged
merged 1 commit into from
Mar 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions __tests__/preprocess-embedded-templates-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,55 @@ describe('htmlbars-inline-precompile: preprocessEmbeddedTemplates', () => {
`);
});

it('it does not process templates or tokens in comments', () => {
let preprocessed = preprocessEmbeddedTemplates(
stripIndent`
// <template></template>
/* <template></template> */
/*
<template></template>
other tokens
\`"'/
*/

<template></template>
`,
TEMPLATE_TAG_CONFIG
);

expect(preprocessed).toMatchInlineSnapshot(`
Object {
"output": "// <template></template>
/* <template></template> */
/*
<template></template>
other tokens
\`\\"'/
*/

[GLIMMER_TEMPLATE(\`\`)]",
"replacements": Array [
Object {
"index": 106,
"newLength": 19,
"oldLength": 10,
"originalCol": 1,
"originalLine": 9,
"type": "start",
},
Object {
"index": 116,
"newLength": 3,
"oldLength": 11,
"originalCol": 11,
"originalLine": 9,
"type": "end",
},
],
}
`);
});

it('works with class templates', () => {
let preprocessed = preprocessEmbeddedTemplates(
stripIndent`
Expand Down Expand Up @@ -621,6 +670,59 @@ describe('htmlbars-inline-precompile: preprocessEmbeddedTemplates', () => {
`);
});

it('it does not process templates or tokens in comments', () => {
let preprocessed = preprocessEmbeddedTemplates(
stripIndent`
import { hbs } from 'ember-template-imports';

// hbs\`hello\`
/* hbs\`hello\` */
/*
hbs\`hello\`
other tokens
\`"'/
*/

export default hbs\`hello\`;
`,
TEMPLATE_LITERAL_CONFIG
);

expect(preprocessed).toMatchInlineSnapshot(`
Object {
"output": "import { hbs } from 'ember-template-imports';

// hbs\`hello\`
/* hbs\`hello\` */
/*
hbs\`hello\`
other tokens
\`\\"'/
*/

export default hbs(\`hello\`);",
"replacements": Array [
Object {
"index": 135,
"newLength": 5,
"oldLength": 4,
"originalCol": 16,
"originalLine": 11,
"type": "start",
},
Object {
"index": 144,
"newLength": 2,
"oldLength": 1,
"originalCol": 25,
"originalLine": 11,
"type": "end",
},
],
}
`);
});

it('exposes template identifiers', () => {
let preprocessed = preprocessEmbeddedTemplates(
stripIndent`
Expand Down
74 changes: 65 additions & 9 deletions src/parse-templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export interface TemplateLiteralMatch {
const escapeChar = '\\';
const stringOrRegexDelimiter = /['"/]/;

const singleLineCommentStart = /\/\//;
const newLine = /\n/;
const multiLineCommentStart = /\/\*/;
const multiLineCommentEnd = /\*\//;

const templateLiteralStart = /([$a-zA-Z_][0-9a-zA-Z_$]*)?`/;
const templateLiteralEnd = /`/;

Expand Down Expand Up @@ -70,7 +75,20 @@ export function parseTemplates(
const argumentsMatchRegex = new RegExp(`<${templateTag}[^<]*\\S[^<]*>`);

const allTokens = new RegExp(
`["'\`/]|([$a-zA-Z_][0-9a-zA-Z_$]*)\`|\\\${|{|}|<${templateTag}[^<]*?>|<\\/${templateTag}>`,
[
singleLineCommentStart.source,
newLine.source,
multiLineCommentStart.source,
multiLineCommentEnd.source,
stringOrRegexDelimiter.source,
templateLiteralStart.source,
templateLiteralEnd.source,
dynamicSegmentStart.source,
dynamicSegmentEnd.source,
blockStart.source,
templateTagStart.source,
templateTagEnd.source,
].join('|'),
'g'
);

Expand All @@ -93,21 +111,21 @@ export function parseTemplates(
tokens: RegExpMatchArray[],
isTopLevel = false
) {
if (token[0].match(stringOrRegexDelimiter)) {
parseStringOrRegex(results, template, token, tokens);
}

if (token[0].match(templateLiteralStart)) {
if (token[0].match(multiLineCommentStart)) {
parseMultiLineComment(results, template, token, tokens);
} else if (token[0].match(singleLineCommentStart)) {
parseSingleLineComment(results, template, token, tokens);
} else if (token[0].match(templateLiteralStart)) {
parseTemplateLiteral(results, template, token, tokens, isTopLevel);
}

if (
} else if (
isTopLevel &&
templateTag !== undefined &&
templateTagStart &&
token[0].match(templateTagStart)
) {
parseTemplateTag(results, template, token, tokens);
} else if (token[0].match(stringOrRegexDelimiter)) {
parseStringOrRegex(results, template, token, tokens);
}
}

Expand All @@ -130,6 +148,44 @@ export function parseTemplates(
}
}

/**
* Parse a string or a regex. All tokens within a string or regex are ignored
* since there are no dynamic segments within these.
*/
function parseSingleLineComment(
_results: TemplateMatch[],
_template: string,
_startToken: RegExpMatchArray,
tokens: RegExpMatchArray[]
) {
while (tokens.length > 0) {
const currentToken = expect(tokens.shift(), 'expected token');

if (currentToken[0] === '\n') {
return;
}
}
}

/**
* Parse a string or a regex. All tokens within a string or regex are ignored
* since there are no dynamic segments within these.
*/
function parseMultiLineComment(
_results: TemplateMatch[],
_template: string,
_startToken: RegExpMatchArray,
tokens: RegExpMatchArray[]
) {
while (tokens.length > 0) {
const currentToken = expect(tokens.shift(), 'expected token');

if (currentToken[0] === '*/') {
return;
}
}
}

/**
* Parse a template literal. If a dynamic segment is found, enters the dynamic
* segment and parses it recursively. If no dynamic segments are found and the
Expand Down