Prettier server style fixes

Kirill Bulatov created

Change summary

crates/node_runtime/src/node_runtime.rs |  4 ++--
crates/prettier/src/prettier.rs         | 21 ++++++++++++++++-----
crates/prettier/src/prettier_server.js  | 23 +++++++++++++----------
3 files changed, 31 insertions(+), 17 deletions(-)

Detailed changes

crates/node_runtime/src/node_runtime.rs 🔗

@@ -243,7 +243,7 @@ impl NodeRuntime for FakeNodeRuntime {
         if name == "prettier" {
             Ok("0.0.1".to_string())
         } else {
-            unreachable!()
+            unreachable!("Unexpected package name: {name}")
         }
     }
 
@@ -255,7 +255,7 @@ impl NodeRuntime for FakeNodeRuntime {
         if packages == [("prettier", "0.0.1")] {
             Ok(())
         } else {
-            unreachable!()
+            unreachable!("Unexpected packages to install: {packages:?}")
         }
     }
 }

crates/prettier/src/prettier.rs 🔗

@@ -197,11 +197,14 @@ impl Prettier {
         _: Arc<dyn NodeRuntime>,
         _: AsyncAppContext,
     ) -> anyhow::Result<Self> {
-        Ok(Self::Test(TestPrettier {
-            worktree_id,
-            default: prettier_dir == DEFAULT_PRETTIER_DIR.as_path(),
-            prettier_dir,
-        }))
+        Ok(
+            #[cfg(any(test, feature = "test-support"))]
+            Self::Test(TestPrettier {
+                worktree_id,
+                default: prettier_dir == DEFAULT_PRETTIER_DIR.as_path(),
+                prettier_dir,
+            }),
+        )
     }
 
     #[cfg(not(any(test, feature = "test-support")))]
@@ -212,6 +215,8 @@ impl Prettier {
         node: Arc<dyn NodeRuntime>,
         cx: AsyncAppContext,
     ) -> anyhow::Result<Self> {
+        use lsp::LanguageServerBinary;
+
         let backgroud = cx.background();
         anyhow::ensure!(
             prettier_dir.is_dir(),
@@ -425,6 +430,7 @@ impl Prettier {
                 .diff
                 .map(deserialize_diff)
                 .context("missing diff after prettier diff invocation"),
+            #[cfg(any(test, feature = "test-support"))]
             Self::Test(_) => Ok(buffer
                 .read_with(cx, |buffer, cx| {
                     let formatted_text = buffer.text() + "\nformatted by test prettier";
@@ -458,6 +464,7 @@ impl Prettier {
                     )
                 })
                 .context("prettier invoke clear cache"),
+            #[cfg(any(test, feature = "test-support"))]
             Self::Test(_) => Ok(()),
         }
     }
@@ -466,6 +473,7 @@ impl Prettier {
         match self {
             Self::Local(local) => Some(&local.server),
             Self::Remote(_) => None,
+            #[cfg(any(test, feature = "test-support"))]
             Self::Test(_) => None,
         }
     }
@@ -474,6 +482,7 @@ impl Prettier {
         match self {
             Self::Local(local) => local.default,
             Self::Remote(_) => false,
+            #[cfg(any(test, feature = "test-support"))]
             Self::Test(test_prettier) => test_prettier.default,
         }
     }
@@ -482,6 +491,7 @@ impl Prettier {
         match self {
             Self::Local(local) => &local.prettier_dir,
             Self::Remote(remote) => &remote.prettier_dir,
+            #[cfg(any(test, feature = "test-support"))]
             Self::Test(test_prettier) => &test_prettier.prettier_dir,
         }
     }
@@ -490,6 +500,7 @@ impl Prettier {
         match self {
             Self::Local(local) => local.worktree_id,
             Self::Remote(remote) => remote.worktree_id,
+            #[cfg(any(test, feature = "test-support"))]
             Self::Test(test_prettier) => test_prettier.worktree_id,
         }
     }

crates/prettier/src/prettier_server.js 🔗

@@ -39,13 +39,13 @@ class Prettier {
         process.stderr.write(`Failed to load prettier: ${e}\n`);
         process.exit(1);
     }
-    process.stderr.write(`Prettier at path '${prettierPath}' loaded successfully, config: ${config}\n`);
+    process.stderr.write(`Prettier at path '${prettierPath}' loaded successfully, config: ${JSON.stringify(config)}\n`);
     process.stdin.resume();
     handleBuffer(new Prettier(prettierPath, prettier, config));
 })()
 
 async function handleBuffer(prettier) {
-    for await (let messageText of readStdin()) {
+    for await (const messageText of readStdin()) {
         let message;
         try {
             message = JSON.parse(messageText);
@@ -53,6 +53,7 @@ async function handleBuffer(prettier) {
             sendResponse(makeError(`Failed to parse message '${messageText}': ${e}`));
             continue;
         }
+        // allow concurrent request handling by not `await`ing the message handling promise (async function)
         handleMessage(message, prettier).catch(e => {
             sendResponse({ id: message.id, ...makeError(`error during message handling: ${e}`) });
         });
@@ -96,16 +97,18 @@ async function* readStdin() {
                     await once(process.stdin, 'readable');
                 }
                 const headers = buffer.subarray(0, buffer.indexOf(`${headerSeparator}${headerSeparator}`)).toString('ascii');
-                const contentLengthHeader = headers.split(headerSeparator).map(header => header.split(':'))
+                const contentLengthHeader = headers.split(headerSeparator)
+                    .map(header => header.split(':'))
                     .filter(header => header[2] === undefined)
                     .filter(header => (header[1] || '').length > 0)
-                    .find(header => header[0].trim() === contentLengthHeaderName);
-                if (contentLengthHeader === undefined) {
+                    .find(header => (header[0] || '').trim() === contentLengthHeaderName);
+                const contentLength = (contentLengthHeader || [])[1];
+                if (contentLength === undefined) {
                     await handleStreamEnded(`Missing or incorrect ${contentLengthHeaderName} header: ${headers}`);
                     continue main_loop;
                 }
                 headersLength = headers.length + headerSeparator.length * 2;
-                messageLength = parseInt(contentLengthHeader[1], 10);
+                messageLength = parseInt(contentLength, 10);
             }
 
             while (buffer.length < (headersLength + messageLength)) {
@@ -120,6 +123,7 @@ async function* readStdin() {
             const messageEnd = headersLength + messageLength;
             const message = buffer.subarray(headersLength, messageEnd);
             buffer = buffer.subarray(messageEnd);
+            headersLength = null;
             messageLength = null;
             yield message.toString('utf8');
         }
@@ -188,13 +192,12 @@ function makeError(message) {
 }
 
 function sendResponse(response) {
-    let responsePayloadString = JSON.stringify({
+    const responsePayloadString = JSON.stringify({
         jsonrpc: "2.0",
         ...response
     });
-    let headers = `${contentLengthHeaderName}: ${Buffer.byteLength(responsePayloadString)}${headerSeparator}${headerSeparator}`;
-    let dataToSend = headers + responsePayloadString;
-    process.stdout.write(dataToSend);
+    const headers = `${contentLengthHeaderName}: ${Buffer.byteLength(responsePayloadString)}${headerSeparator}${headerSeparator}`;
+    process.stdout.write(headers + responsePayloadString);
 }
 
 function loadPrettier(prettierPath) {