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

Windows line endings break source maps #6694

Closed
mischnic opened this issue Dec 20, 2022 · 6 comments · Fixed by #6752 or #6763
Closed

Windows line endings break source maps #6694

mischnic opened this issue Dec 20, 2022 · 6 comments · Fixed by #6752 or #6763
Assignees
Labels
Milestone

Comments

@mischnic
Copy link
Contributor

mischnic commented Dec 20, 2022

Describe the bug

A block comment before a function produces invalid sourcemaps

Bildschirm­foto 2022-12-20 um 18 24 14

Input code

(See #6694 (comment), this is due to Windows line endings)

/**
 * foo
 * @param data foo
 * @returns foo
 */
export const fixupRiskConfigData = (data: any): types.RiskConfigType => {
  if (x) {
    return 123;
  } else {
    return 456;
  }
};

Config

{
	"jsc": {
		"parser": {
			"syntax": "typescript"
		},
		"target": "es2022"
	},
	"sourceMaps": true,
	"inlineSourcesContent": true
}

Expected behavior

The sourcemap should be correct

Actual behavior

No response

Version

1.3.23

Additional context

Found in parcel-bundler/parcel#8691

@jridgewell
Copy link
Contributor

jridgewell commented Dec 20, 2022

We recently had improvements to our sourcemap code. Running the example in the playground, and pasting that into the visualizer, I'm getting correct sourcemaps:
Screen Shot 2022-12-20 at 3 40 36 PM

@mischnic
Copy link
Contributor Author

Turns out, this is actually due to Windows line endings. Reproduction:

const { transformSync } = require("@swc/core");

let output = transformSync(
  `/**
 * foo
 * @param data foo
 * @returns foo
 */
export const fixupRiskConfigData = (data: any): types.RiskConfigType => {
  if (x) {
    return 123;
  } else {
    return 456;
  }
};`.replaceAll("\n", "\r\n"),

  {
    jsc: {
      parser: {
        syntax: "typescript",
      },
      target: "es2022",
    },
    sourceMaps: "inline",
    inlineSourcesContent: true,
  }
);

console.log(output.code);

I got the reproduction from a Git repo, and copying that code into the issue of course normalized the line endings...

@mischnic
Copy link
Contributor Author

(And related to that, someone also reported similar sourcemap problem in Parcel)

Bildschirm­foto 2022-12-20 um 22 04 40

swc Repo for that:

const { transformSync } = require("@swc/core");

let output = transformSync(
  ` console.log("test1") // line 1 correct

let text = \`
    1
    1
    1
    1
    1
    1
    \`

console.log("test2") // this should be line 12, instead 17 in devtools

let test0
let test1

console.log("test3")  // this only woks because last line if you add more content it wont work`.replaceAll("\n", "\r\n"),

  {
    jsc: {
      parser: {
        syntax: "typescript",
      },
      target: "es2022",
    },
    sourceMaps: "inline",
    inlineSourcesContent: true,
  }
);

console.log(output.code);

@jridgewell
Copy link
Contributor

Ah, ok, seems we need to update:

@jridgewell jridgewell changed the title Block comment before functions breaks sourcemaps Windows line endings break source maps Dec 20, 2022
@kdy1 kdy1 added this to the Planned milestone Dec 21, 2022
@kdy1 kdy1 self-assigned this Dec 22, 2022
@kdy1 kdy1 closed this as completed in #6752 Jan 6, 2023
kdy1 added a commit that referenced this issue Jan 6, 2023
**Related issue:**

 - Closes #6694.
@mischnic
Copy link
Contributor Author

mischnic commented Jan 6, 2023

It's still not working for me:
Bildschirm­foto 2023-01-06 um 11 11 09

Using this on fb6770f:

use std::collections::HashSet;

use swc::{self};
use swc_atoms::JsWord;
use swc_common::{
    chain,
    comments::SingleThreadedComments,
    errors::{DiagnosticBuilder, Emitter, Handler},
    source_map::SourceMapGenConfig,
    sync::Lrc,
    FileName, Globals, Mark, SourceMap, SyntaxContext, DUMMY_SP,
};
use swc_ecma_ast::{CatchClause, Decl, Id, Ident, Module, Pat, Stmt, VarDeclKind};
use swc_ecma_codegen::{text_writer::JsWriter, Config};
use swc_ecma_parser::{lexer::Lexer, EsConfig, PResult, Parser, StringInput, Syntax, TsConfig};
use swc_ecma_preset_env::{preset_env, BrowserData, Mode, Targets, Version};
use swc_ecma_transforms::{
    compat::reserved_words::reserved_words,
    fixer,
    fixer::paren_remover,
    helpers, hygiene,
    optimization::simplify::{dead_branch_remover, expr_simplifier},
    react::{self, Runtime},
    resolver,
};
use swc_ecma_visit::{Fold, FoldWith, Visit, VisitWith};

#[derive(Debug, Clone, Default)]
pub struct ErrorBuffer(std::sync::Arc<std::sync::Mutex<Vec<swc_common::errors::Diagnostic>>>);

type SourceMapBuffer = Vec<(swc_common::BytePos, swc_common::LineCol)>;

impl Emitter for ErrorBuffer {
    fn emit(&mut self, db: &DiagnosticBuilder) {
        self.0.lock().unwrap().push((**db).clone());
    }
}

fn main() {
    let cm = Lrc::<SourceMap>::default();
    //     let src = r#"
    // let a = function l1(){};
    // let {x: {b}, x: [c]} = 0;
    // let [d, [e], {f}] = 0;
    // function g(){
    //     var l1;
    //     let l2;
    //     const l3;
    // }
    // class A {
    //     l1;
    //     func(){
    //         var l1;
    //         let l2;
    //         const l3;
    //     }
    // }
    // try {
    //     throw new Error();
    // } catch (l1) {
    //     var l1 = 2;
    //     var h = 1;
    // }
    // "#;

    let src = r#"/**
 * foo
 * @param data foo
 * @returns foo
 */
export const fixupRiskConfigData = (data: any): types.RiskConfigType => {
  if (x) {
    return 123;
  } else {
    return 456;
  }
};
"#
    .replace("\n", "\r\n");
    //     let src = r#"
    // let funcs = [];
    // for (let i = 0; i < 2; i++) {
    //     for (let j = 0; j < 2; j++) {
    //         funcs.push(() => console.log(i, j));
    //     }
    // }

    // funcs.forEach((f) => f());
    // "#;
    let (module, comments) = parse(&src, "test.js", &cm).unwrap();

    let error_buffer = ErrorBuffer::default();
    let handler = Handler::with_emitter(true, false, Box::new(error_buffer.clone()));
    swc_common::errors::HANDLER.set(&handler, || {
        swc_common::GLOBALS.set(&Globals::new(), || {
            helpers::HELPERS.set(&helpers::Helpers::new(true), || {
                let unresolved_mark = Mark::fresh(Mark::root());
                let top_level_mark = Mark::fresh(Mark::root());
                let module =
                    module.fold_with(&mut resolver(unresolved_mark, top_level_mark, false));

                // let mut global_vars = FindGlobalVariables {
                //     variables: HashSet::new(),
                //     var_kind: VarDeclKind::Var,
                //     in_block: false,
                //     catch_binding: None,
                // };
                // module.visit_with(&mut global_vars);
                // println!("{:?}", global_vars.variables);

                // let module = module.fold_with(&mut react::react(
                //     cm.clone(),
                //     Some(&comments),
                //     react::Options {
                //         runtime: Some(Runtime::Automatic),
                //         development: Some(false),
                //         refresh: Some(Default::default()),
                //         ..Default::default()
                //     },
                //     top_level_mark,
                // ));
                // let code = emit(&module, &comments, cm.clone());
                // println!("#{}", code);
                // let module = module.fold_with(&mut dead_branch_remover(unresolved_mark));
                // let code = emit(&module, &comments, cm.clone());
                // println!("#{}", code);

                // let module = module.fold_with(&mut chain!(
                //     preset_env(
                //         top_level_mark,
                //         Some(&comments),
                //         swc_ecma_preset_env::Config {
                //             targets: Some(Targets::Versions(BrowserData {
                //                 chrome: Some(Version {
                //                     major: 70,
                //                     minor: 0,
                //                     patch: 0,
                //                 }),
                //                 ..Default::default()
                //             })),
                //             bugfixes: true,
                //             shipped_proposals: true,
                //             mode: Some(Mode::Entry),
                //             ..Default::default()
                //         },
                //         Default::default(),
                //         &mut Default::default()
                //     ),
                //     helpers::inject_helpers(),
                // ));

                // let module = module.fold_with(&mut chain!(
                //     hygiene(),
                //     resolver(unresolved_mark, top_level_mark, false)
                // ));
                // let module = module.fold_with(&mut chain!(
                //     paren_remover(Some(&comments)),
                //     // expr_simplifier(unresolved_mark, Default::default()),
                //     dead_branch_remover(unresolved_mark)
                // ));
                let module = module.fold_with(&mut dead_branch_remover(unresolved_mark));

                // let module = module.fold_with(&mut ShowSyntaxContext {
                //     top_level_mark,
                //     unresolved_mark,
                // });

                let module = module.fold_with(&mut chain!(
                    reserved_words(),
                    hygiene(),
                    fixer(Some(&comments))
                ));

                // for diagnostic in error_buffer.0.lock().unwrap().clone() {
                //     let message = diagnostic.message();
                //     let span = diagnostic.span.clone();
                //     println!("-- Diagnostic --\nMessage:{}", message);

                //     let span_labels = span.span_labels();
                //     if !span_labels.is_empty() {
                //         for span_label in span_labels {
                //             let start =
                // cm.lookup_char_pos(span_label.span.lo);
                //             let end = cm.lookup_char_pos(span_label.span.hi);
                //             println!("{:?} - {:?} :: {:?}", start, end,
                // span_label.label);         }
                //     };
                // }

                let mut map_buf = vec![];
                let (code, src_map_buf) = emit(cm.clone(), comments, &module).unwrap();

                struct SourceMapConfigImpl;

                impl SourceMapGenConfig for SourceMapConfigImpl {
                    fn file_name_to_source(&self, f: &swc_common::FileName) -> String {
                        f.to_string()
                    }

                    fn inline_sources_content(&self, _: &swc_common::FileName) -> bool {
                        true
                    }
                }
                cm.build_source_map_with_config(&src_map_buf, None, SourceMapConfigImpl)
                    .to_writer(&mut map_buf)
                    .unwrap();
                // if cm
                //     .build_source_map(&src_map_buf)
                //     .to_writer(&mut map_buf)
                //     .is_ok()
                // {
                // println!("{}", String::from_utf8(map_buf).unwrap());
                // }
                // println!("{}", code);

                println!(
                    "{}",
                    visualizer_url(&code, &String::from_utf8(map_buf).unwrap())
                );
            });
        });
    });
}

fn visualizer_url(code: &str, map: &str) -> String {
    println!("{}", code);
    println!("{}", map);
    let code_len = format!("{}\0", code.len());
    let map_len = format!("{}\0", map.len());
    let hash = base64::encode(format!("{}{}{}{}", code_len, code, map_len, map));
    format!("https://evanw.github.io/source-map-visualization/#{}", hash)
}

struct ShowSyntaxContext {
    top_level_mark: Mark,
    unresolved_mark: Mark,
}
impl Fold for ShowSyntaxContext {
    fn fold_ident(&mut self, node: Ident) -> Ident {
        let new_name: JsWord = format!(
            "{}_{}{}{}",
            node.sym,
            node.span.ctxt().as_u32(),
            if node.span.has_mark(self.top_level_mark) {
                "_top"
            } else {
                ""
            },
            if node.span.has_mark(self.unresolved_mark) {
                "_unres"
            } else {
                ""
            },
        )
        .into();
        Ident::new(new_name, node.span)
    }
}

// struct FindGlobalVariables {
//     variables: HashSet<Id>,
//     var_kind: VarDeclKind,
//     in_block: bool,
//     catch_binding: Option<Id>,
// }

// impl Visit for FindGlobalVariables {
//     fn visit_var_decl(&mut self, n: &swc_ecma_ast::VarDecl) {
//         self.var_kind = n.kind;
//         n.visit_children_with(self)
//     }

//     fn visit_binding_ident(&mut self, n: &swc_ecma_ast::BindingIdent) {
//         if self.var_kind == VarDeclKind::Var || !self.in_block {
//             self.variables.insert(n.id.clone().into());
//         }
//     }

//     // fn visit_array_pat(&mut self, n: &swc_ecma_ast::ArrayPat) {
//     //     for e in &n.elems {
//     //         if let Some(Pat::Ident(id)) = e.as_ref() {}
//     //     }
//     // }

//     fn visit_assign_pat_prop(&mut self, n: &swc_ecma_ast::AssignPatProp) {
//         if n.value.is_none() {
//             self.variables.insert(n.key.clone().into());
//         } else {
//             n.value.visit_with(self)
//         }
//         // for e in &n.value {
//         //     if let Some(Pat::Ident(id)) = e.as_ref() {}
//         // }
//     }

//     fn visit_fn_decl(&mut self, n: &swc_ecma_ast::FnDecl) {
//         self.variables.insert(n.ident.clone().into());
//     }

//     fn visit_class_decl(&mut self, n: &swc_ecma_ast::ClassDecl) {
//         self.variables.insert(n.ident.clone().into());
//     }

//     fn visit_stmt(&mut self, stmt: &swc_ecma_ast::Stmt) {
//         match stmt {
//             Stmt::Decl(decl) => decl.visit_with(self),
//             Stmt::If(n) => {
//                 self.in_block = true;
//                 n.visit_children_with(self);
//                 self.in_block = false;
//             }
//             Stmt::For(n) => {
//                 n.init.visit_with(self);
//                 self.in_block = true;
//                 n.visit_children_with(self);
//                 self.in_block = false;
//             }
//             Stmt::ForIn(n) => {
//                 n.left.visit_with(self);
//                 self.in_block = true;
//                 n.visit_children_with(self);
//                 self.in_block = false;
//             }
//             Stmt::ForOf(n) => {
//                 n.left.visit_with(self);
//                 self.in_block = true;
//                 n.visit_children_with(self);
//                 self.in_block = false;
//             }
//             Stmt::While(n) => {
//                 self.in_block = true;
//                 n.visit_children_with(self);
//                 self.in_block = false;
//             }
//             Stmt::DoWhile(n) => {
//                 self.in_block = true;
//                 n.visit_children_with(self);
//                 self.in_block = false;
//             }
//             Stmt::Switch(n) => {
//                 n.visit_children_with(self);
//             }
//             Stmt::Try(n) => {
//                 n.block.visit_with(self);
//                 if let Some(CatchClause { body, param, .. }) = n.handler {
//                     body.visit_with(self);
//                 }
//                 n.finalizer.visit_with(self);
//             }
//             Stmt::Labeled(n) => {
//                 n.visit_children_with(self);
//             }
//             Stmt::Block(n) => {
//                 self.in_block = true;
//                 n.visit_children_with(self);
//                 self.in_block = false;
//             }
//             _ => {}
//         }
//     }
// }

fn parse(
    code: &str,
    filename: &str,
    cm: &Lrc<SourceMap>,
) -> PResult<(Module, SingleThreadedComments)> {
    let source_file = cm.new_source_file(FileName::Real(filename.into()), code.into());
    let comments = SingleThreadedComments::default();

    let lexer = Lexer::new(
        // Syntax::Es(EsConfig {
        //     jsx: true,
        //     ..Default::default()
        // }),
        Syntax::Typescript(TsConfig {
            tsx: true,
            ..Default::default()
        }),
        Default::default(),
        StringInput::from(&*source_file),
        Some(&comments),
    );
    let mut parser = Parser::new_from(lexer);
    match parser.parse_module() {
        Err(err) => Err(err),
        Ok(module) => Ok((module, comments)),
    }
}

fn emit(
    source_map: Lrc<SourceMap>,
    comments: SingleThreadedComments,
    module: &Module,
) -> Result<(String, SourceMapBuffer), std::io::Error> {
    let mut src_map_buf = vec![];
    let mut buf = vec![];
    {
        let writer = Box::new(JsWriter::new(
            source_map.clone(),
            "\n",
            &mut buf,
            Some(&mut src_map_buf),
        ));
        let config = Config {
            minify: false,
            ascii_only: false,
            omit_last_semi: false,
            ..Default::default()
        };
        let mut emitter = swc_ecma_codegen::Emitter {
            cfg: config,
            comments: Some(&comments),
            cm: source_map,
            wr: writer,
        };

        emitter.emit_module(module)?;
    }

    Ok((String::from_utf8(buf).unwrap(), src_map_buf))
}

@kdy1 kdy1 reopened this Jan 6, 2023
@kdy1 kdy1 closed this as completed in #6763 Jan 8, 2023
kdy1 pushed a commit that referenced this issue Jan 8, 2023
**Description:**

There were several issues with the way we updated the current `LineCol` position during the printing of the generated file:

- We used `chars` and `char_indices` (UTF-32) instead of `encode_utf16` (UTF-16) chars.
- JS uses UCS-2 (basically UTF-16) for its strings, and source maps default to that implicitly.
- `\r` was incorrectly handled
  - it didn't add a `line_start`; only `\n` did
- `\r\n` was incorrectly handled
- It was trying to let the `\n` path handle the `line_start`, but it called
`chars.next()` which ate the `\n` char.

I also took the opportunity to avoid the `Vec` allocations and reduced some code duplication.

See the
[before](https://evanw.github.io/source-map-visualization/#ODEzAC8qKgogKiBmb28KICogQHBhcmFtIGRhdGEgZm9vCiAqIEByZXR1cm5zIGZvbwogKi8gZXhwb3J0IGNvbnN0IGZpeHVwUmlza0NvbmZpZ0RhdGEgPSAoZGF0YSk9PnsKICAgIGlmICh4KSB7CiAgICAgICAgcmV0dXJuIDEyMzsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIDQ1NjsKICAgIH0KfTsKCi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbWx1Y0hWMExuUnpJbDBzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiSWk4cUtseHlYRzRnS2lCbWIyOWNjbHh1SUNvZ1FIQmhjbUZ0SUdSaGRHRWdabTl2WEhKY2JpQXFJRUJ5WlhSMWNtNXpJR1p2YjF4eVhHNGdLaTljY2x4dVpYaHdiM0owSUdOdmJuTjBJR1pwZUhWd1VtbHphME52Ym1acFowUmhkR0VnUFNBb1pHRjBZVG9nWVc1NUtUb2dkSGx3WlhNdVVtbHphME52Ym1acFoxUjVjR1VnUFQ0Z2UxeHlYRzRnSUdsbUlDaDRLU0I3WEhKY2JpQWdJQ0J5WlhSMWNtNGdNVEl6TzF4eVhHNGdJSDBnWld4elpTQjdYSEpjYmlBZ0lDQnlaWFIxY200Z05EVTJPMXh5WEc0Z0lIMWNjbHh1ZlRzaVhTd2libUZ0WlhNaU9sc2labWw0ZFhCU2FYTnJRMjl1Wm1sblJHRjBZU0lzSW1SaGRHRWlMQ0o0SWwwc0ltMWhjSEJwYm1keklqb2lRVUZCUVN4dFJFRkpReXhIUVVORUxFOUJRVThzVFVGQlRVRXNjMEpCUVhOQ0xFTkJRVU5ETEU5QlFXOURPMGxCUTNSRkxFbEJRVWxETEVkQlFVYzdVVUZEVEN4UFFVRlBPMGxCUTFRc1QwRkJUenRSUVVOTUxFOUJRVTg3U1VGRFZDeERRVUZETzBGQlEwZ3NSVUZCUlNKOTQ0NAB7InZlcnNpb24iOjMsInNvdXJjZXMiOlsiaW5wdXQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIGZvb1xyXG4gKiBAcGFyYW0gZGF0YSBmb29cclxuICogQHJldHVybnMgZm9vXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgZml4dXBSaXNrQ29uZmlnRGF0YSA9IChkYXRhOiBhbnkpOiB0eXBlcy5SaXNrQ29uZmlnVHlwZSA9PiB7XHJcbiAgaWYgKHgpIHtcclxuICAgIHJldHVybiAxMjM7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiA0NTY7XHJcbiAgfVxyXG59OyJdLCJuYW1lcyI6WyJmaXh1cFJpc2tDb25maWdEYXRhIiwiZGF0YSIsIngiXSwibWFwcGluZ3MiOiJBQUFBLG1EQUlDLEdBQ0QsT0FBTyxNQUFNQSxzQkFBc0IsQ0FBQ0MsT0FBb0M7SUFDdEUsSUFBSUMsR0FBRztRQUNMLE9BQU87SUFDVCxPQUFPO1FBQ0wsT0FBTztJQUNULENBQUM7QUFDSCxFQUFFIn0=)
and
[after](https://evanw.github.io/source-map-visualization/#ODIyAC8qKgogKiBmb28KICogQHBhcmFtIGRhdGEgZm9vCiAqIEByZXR1cm5zIGZvbwogKi8gZXhwb3J0IHZhciBmaXh1cFJpc2tDb25maWdEYXRhID0gZnVuY3Rpb24oZGF0YSkgewogICAgaWYgKHgpIHsKICAgICAgICByZXR1cm4gMTIzOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gNDU2OwogICAgfQp9OwoKLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYklpNHZZWEJ3TG1weklsMHNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJJaThxS2x4eVhHNGdLaUJtYjI5Y2NseHVJQ29nUUhCaGNtRnRJR1JoZEdFZ1ptOXZYSEpjYmlBcUlFQnlaWFIxY201eklHWnZiMXh5WEc0Z0tpOWNjbHh1Wlhod2IzSjBJR052Ym5OMElHWnBlSFZ3VW1semEwTnZibVpwWjBSaGRHRWdQU0FvWkdGMFlUb2dZVzU1S1RvZ2RIbHdaWE11VW1semEwTnZibVpwWjFSNWNHVWdQVDRnZTF4eVhHNGdJR2xtSUNoNEtTQjdYSEpjYmlBZ0lDQnlaWFIxY200Z01USXpPMXh5WEc0Z0lIMGdaV3h6WlNCN1hISmNiaUFnSUNCeVpYUjFjbTRnTkRVMk8xeHlYRzRnSUgxY2NseHVmVHNpWFN3aWJtRnRaWE1pT2xzaVptbDRkWEJTYVhOclEyOXVabWxuUkdGMFlTSXNJbVJoZEdFaUxDSjRJbDBzSW0xaGNIQnBibWR6SWpvaVFVRkJRVHM3T3p0RFFVbERMRWRCUTBRc1QwRkJUeXhKUVVGTlFTeHpRa0ZCYzBJc1UwRkJRME1zVFVGQmIwTTdTVUZEZEVVc1NVRkJTVU1zUjBGQlJ6dFJRVU5NTEU5QlFVODdTVUZEVkN4UFFVRlBPMUZCUTB3c1QwRkJUenRKUVVOVUxFTkJRVU03UVVGRFNDeEZRVUZGSW4wPTQ0NgB7InZlcnNpb24iOjMsInNvdXJjZXMiOlsiLi9hcHAuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIGZvb1xyXG4gKiBAcGFyYW0gZGF0YSBmb29cclxuICogQHJldHVybnMgZm9vXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgZml4dXBSaXNrQ29uZmlnRGF0YSA9IChkYXRhOiBhbnkpOiB0eXBlcy5SaXNrQ29uZmlnVHlwZSA9PiB7XHJcbiAgaWYgKHgpIHtcclxuICAgIHJldHVybiAxMjM7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiA0NTY7XHJcbiAgfVxyXG59OyJdLCJuYW1lcyI6WyJmaXh1cFJpc2tDb25maWdEYXRhIiwiZGF0YSIsIngiXSwibWFwcGluZ3MiOiJBQUFBOzs7O0NBSUMsR0FDRCxPQUFPLElBQU1BLHNCQUFzQixTQUFDQyxNQUFvQztJQUN0RSxJQUFJQyxHQUFHO1FBQ0wsT0FBTztJQUNULE9BQU87UUFDTCxPQUFPO0lBQ1QsQ0FBQztBQUNILEVBQUUifQ==)


**Related issue:**

 - Closes #6694.
@kdy1 kdy1 modified the milestones: Planned, v1.3.26 Jan 11, 2023
@swc-bot
Copy link
Collaborator

swc-bot commented Feb 10, 2023

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@swc-project swc-project locked as resolved and limited conversation to collaborators Feb 10, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.