Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annoying popup in VSCode while typing #23680

Closed
nicolo-ribaudo opened this issue May 3, 2024 · 0 comments · Fixed by #23691
Closed

Annoying popup in VSCode while typing #23680

nicolo-ribaudo opened this issue May 3, 2024 · 0 comments · Fixed by #23691

Comments

@nicolo-ribaudo
Copy link

nicolo-ribaudo commented May 3, 2024

Version: Deno 1.43.1

I semi-randomly get this popup while typing:

image

My full (JavaScript) file is:

// @ts-types="https://esm.sh/v135/@babel/[email protected]/typings/babel-parser.d.ts"
import { parse } from "https://esm.sh/@babel/[email protected]/lib/index.js";
//import traverse from "https://esm.sh/@babel/[email protected]/lib/index.js";
import generate from "https://esm.sh/@babel/[email protected]/lib/index.js";
//import h from "https://esm.sh/@babel/[email protected]/lib/index.js";
import * as t from "https://esm.sh/@babel/[email protected]/lib/index.js";

export function matches(url) {
  return !new URL(url).searchParams.has("no-defer-polyfill");
}

export function transform(code, url) {
  const ast = parse(code, { sourceType: "module" });

  // TODO: Handle TLA

  return generate(getDeferredModule(ast)).code;
}

/** @param {ReturnType<typeof parse>} ast  */
function getWrapper(ast, url) {
  const newBody = [];
  let hasDefault = false;

  for (const node of ast.program.body) {
    if (
      node.type === "ImportDeclaration" ||
      (node.type === "ExportNamedDeclaration" && node.source)
    ) {
      newBody.push(t.importDeclaration([], node.source));
    }
    if (node.type === "ExportDefaultDeclaration") {
      hasDefault = true;
    } else if (node.type === "ExportNamedDeclaration" && node.specifiers && node.specifiers.some(s => s.exported.name === "defaul")) {
      newBody.push(node.declaration);
    }
  }

  const deferredURL = new URL(url);
  deferredURL.searchParams.set("deferred", "");
  newBody.push(
    t.importDeclaration(
      [t.identifier("__$evaluate")],
      t.stringLiteral(deferredURL.href)
    )
  );

  newBody.push();
}

/** @param {ReturnType<typeof parse>} ast  */
function getDeferredModule(ast) {
  const imports = [];

  const vars = [];
  const assignments = [];
  const exports = [];

  const functionBody = [];

  for (const node of ast.program.body) {
    if (
      node.type === "ImportDeclaration" ||
      (node.type === "ExportNamedDeclaration" && node.source)
    ) {
      imports.push(node);
    } else if (node.type === "ExportDefaultDeclaration") {
      const id = t.identifier("__default");
      vars.push(id);
      exports.push(t.exportSpecifier(t.cloneNode(id), t.identifier("default")));

      if (t.isExpression(node.declaration) || !node.declaration.id) {
        functionBody.push(
          t.expressionStatement(
            t.assignmentExpression("=", t.cloneNode(id), node.declaration)
          )
        );
      } else {
        functionBody.push(node.declaration);
        assignments.push(
          t.assignmentExpression("=", t.cloneNode(id), node.declaration.id)
        );
      }
    } else if (node.type === "ExportNamedDeclaration" && node.declaration) {
      functionBody.push(node.declaration);

      const names = Object.keys(
        t.getBindingIdentifiers(node.declaration, false, true)
      );
      for (const name of names) {
        vars.push(t.identifier(`__${name}`));
        exports.push(
          t.exportSpecifier(t.identifier(`__${name}`), t.identifier(name))
        );
        assignments.push(
          t.assignmentExpression(
            "=",
            t.identifier(`__${name}`),
            t.identifier(name)
          )
        );
      }
    } else if (node.type === "ExportNamedDeclaration") {
      exports.push(...node.specifiers);
    } else {
      functionBody.push(node);
    }
  }

  functionBody.push(t.expressionStatement(t.sequenceExpression(assignments)));

  return t.program(
    [
      ...imports,
      vars.length > 0 &&
        t.variableDeclaration(
          "var",
          vars.map((v) => t.variableDeclarator(v))
        ),
      exports.length > 0 && t.exportNamedDeclaration(null, exports),
      t.exportNamedDeclaration(
        t.functionDeclaration(
          t.identifier("__$evaluate"),
          [],
          t.blockStatement(functionBody)
        ),
        []
      ),
    ].filter(Boolean)
  );
}

It seems to only happen while I'm typing inside strings -- in this last case I was typing inside the string "defaul" on line 34 (the long line).

The output panel says

specifier: file:///Users/nic/Documents/dev/experiments.localhost/import-defer-polyfill/tools/import-defer-polyfill/interceptor.js
open: true
start_pos: Position { line: 38, character: 35 }
end_pos: Position { line: 39, character: 10 }
[Error - 17:30:49] Request textDocument/semanticTokens/full failed.
  Message: Internal error
  Code: -32603 

I think that if there is a syntax error while typing, the error should just be ignored (or maybe shown as a red underline in the editor), rather than constantly bringing up a popup. Note that in this case the file was syntactically valid, and I was editing inside the string (so not changing its validity).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant