diff --git a/__tests__/preprocess-embedded-templates-tests.js b/__tests__/preprocess-embedded-templates-tests.js
index 8a70fd03..6d238c18 100644
--- a/__tests__/preprocess-embedded-templates-tests.js
+++ b/__tests__/preprocess-embedded-templates-tests.js
@@ -245,6 +245,55 @@ describe('htmlbars-inline-precompile: preprocessEmbeddedTemplates', () => {
`);
});
+ it('it does not process templates or tokens in comments', () => {
+ let preprocessed = preprocessEmbeddedTemplates(
+ stripIndent`
+ //
+ /* */
+ /*
+
+ other tokens
+ \`"'/
+ */
+
+
+ `,
+ TEMPLATE_TAG_CONFIG
+ );
+
+ expect(preprocessed).toMatchInlineSnapshot(`
+ Object {
+ "output": "//
+ /* */
+ /*
+
+ 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`
@@ -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`
diff --git a/src/parse-templates.ts b/src/parse-templates.ts
index cf43a58f..6d1d6761 100644
--- a/src/parse-templates.ts
+++ b/src/parse-templates.ts
@@ -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 = /`/;
@@ -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'
);
@@ -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);
}
}
@@ -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