Repository: sveltejs/prettier-plugin-svelte
Pull request #135 (2020-09-03 14:09:58)

(fix) replace flatMap (node 11+) with flatten util

dummdidumm: .. or we just keep it as is but require at least node 11. @ehrencrona thoughts?

Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 0661191..0000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-version: 2
-jobs:
-    build:
-        docker:
-            - image: circleci/node:lts
-        working_directory: ~/repo
-        steps:
-            - checkout
-            - restore_cache:
-                  keys:
-                      - v1-dependencies-{{ checksum "package.json" }}
-                      # fallback to using the latest cache if no exact match is found
-                      - v1-dependencies-
-            - run: yarn install
-            - save_cache:
-                  paths:
-                      - node_modules
-                  key: v1-dependencies-{{ checksum "package.json" }}
-            - run: yarn test
-            - run: yarn build
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7e25ea4..280356f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 * (fix) make error location properties compatible with both svelte and prettier ([#71](https://github.com/sveltejs/prettier-plugin-svelte/issues/71))
 * Skip formatting <style> or <script> if unsupported language or prettier-ignored ([#55](https://github.com/sveltejs/prettier-plugin-svelte/issues/55), [#59](https://github.com/sveltejs/prettier-plugin-svelte/issues/59), [#95](https://github.com/sveltejs/prettier-plugin-svelte/issues/95))
+* (fix) handle/preserve comments in event handlers ([#96](https://github.com/sveltejs/prettier-plugin-svelte/issues/96))
 
 ## 1.2.0
 
diff --git a/src/embed.ts b/src/embed.ts
index fa1b700..6b0b00a 100644
--- a/src/embed.ts
+++ b/src/embed.ts
@@ -11,7 +11,7 @@ import {
 import { Node } from './print/nodes';
 
 const {
-    builders: { concat, hardline, group, indent, align, literalline },
+    builders: { concat, hardline, group, indent, literalline },
     utils: { removeLines },
 } = doc;
 
@@ -25,7 +25,7 @@ export function embed(
 
     if (node.isJS) {
         return removeLines(
-            textToDoc(getText(node, options), {
+            textToDoc(forceIntoExpression(getText(node, options)), {
                 parser: expressionParser,
                 singleQuote: true,
             }),
@@ -61,12 +61,16 @@ export function embed(
     return null;
 }
 
+function forceIntoExpression(statement: string) {
+    // note the trailing newline: if the statement ends in a // comment, 
+    // we can't add the closing bracket right afterwards
+    return `(${statement}\n)`;
+}
+
 function expressionParser(text: string, parsers: any) {
-    const ast = parsers.babel(`(${text})`);
-    return {
-        type: 'File',
-        program: ast.program.body[0].expression,
-    };
+    const ast = parsers.babel(text);
+
+    return { ...ast, program: ast.program.body[0].expression };
 }
 
 function skipBlank(docs: Doc[]): number {
@@ -110,14 +114,10 @@ function nukeLastLine(doc: Doc): Doc {
 function preformattedBody(str: string): Doc {
     const firstNewline = /^[\t\f\r ]*\n/;
     const lastNewline = /\n[\t\f\r ]*$/;
-    
+
     // If we do not start with a new line prettier might try to break the opening tag
     // to keep it together with the string. Use a literal line to skip indentation.
-    return concat([
-        literalline,
-        str.replace(firstNewline, '').replace(lastNewline, ''),
-        hardline,
-    ]);
+    return concat([literalline, str.replace(firstNewline, '').replace(lastNewline, ''), hardline]);
 }
 
 function getSnippedContent(node: Node) {
diff --git a/src/lib/getText.ts b/src/lib/getText.ts
index 87234fb..3700076 100644
--- a/src/lib/getText.ts
+++ b/src/lib/getText.ts
@@ -2,5 +2,14 @@ import { ParserOptions } from 'prettier';
 import { Node } from '../print/nodes';
 
 export function getText(node: Node, options: ParserOptions) {
-    return options.originalText.slice(options.locStart(node), options.locEnd(node));
+    const leadingComments: Node[] = (node as any).leadingComments
+
+    return options.originalText.slice(
+        options.locStart(
+            // if there are comments before the node they are not included 
+            // in the `start` of the node itself
+            leadingComments && leadingComments[0] || node,
+        ),
+        options.locEnd(node),
+    );
 }
diff --git a/src/print/helpers.ts b/src/print/helpers.ts
index 6bbf057..ec326e4 100644
--- a/src/print/helpers.ts
+++ b/src/print/helpers.ts
@@ -19,3 +19,7 @@ export function isPreTagContent(path: FastPath): boolean {
             (node.type === 'Attribute' && !formattableAttributes.includes(node.name)),
     );
 }
+
+export function flatten<T>(arrays: T[][]): T[] {
+    return ([] as T[]).concat.apply([], arrays);
+}
diff --git a/src/print/index.ts b/src/print/index.ts
index 3d07d34..f5ad53d 100644
--- a/src/print/index.ts
+++ b/src/print/index.ts
@@ -1,6 +1,6 @@
 import { FastPath, Doc, doc, ParserOptions } from 'prettier';
 import { Node, IfBlockNode, AttributeNode } from './nodes';
-import { isASTNode, isPreTagContent } from './helpers';
+import { isASTNode, isPreTagContent, flatten } from './helpers';
 import { extractAttributes } from '../lib/extractAttributes';
 import { getText } from '../lib/getText';
 import { parseSortOrder, SortOrderPart } from '../options';
@@ -104,10 +104,12 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D
     if (ignoreNext && (node.type !== 'Text' || !isEmptyNode(node))) {
         ignoreNext = false;
         return concat(
-            options.originalText
-                .slice(options.locStart(node), options.locEnd(node))
-                .split('\n')
-                .flatMap((o, i) => (i == 0 ? o : [literalline, o])),
+            flatten(
+                options.originalText
+                    .slice(options.locStart(node), options.locEnd(node))
+                    .split('\n')
+                    .map((o, i) => (i == 0 ? [o] : [literalline, o])),
+            ),
         );
     }
 


Test patch:
diff --git a/test/printer/samples/event-handler-comments.html b/test/printer/samples/event-handler-comments.html
new file mode 100644
index 0000000..2475fbc
--- /dev/null
+++ b/test/printer/samples/event-handler-comments.html
@@ -0,0 +1,6 @@
+<button
+    on:click={// comment
+    () => {
+        /* another comment */
+        fn();
+    }} />