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

🐛 In Svelte context=module Scripts error "import { type x ident }' are a TypeScript only feature." #2245

Closed
1 task done
minht11 opened this issue Mar 30, 2024 · 6 comments · Fixed by #2317
Closed
1 task done
Labels
A-Analyzer Area: analyzer S-Bug-confirmed Status: report has been confirmed as a valid bug S-Help-wanted Status: you're familiar with the code base and want to help the project

Comments

@minht11
Copy link
Contributor

minht11 commented Mar 30, 2024

Environment information

CLI:
  Version:                      1.6.3
  Color support:                true

Platform:
  CPU Architecture:             aarch64
  OS:                           macos

Environment:
  BIOME_LOG_DIR:                unset
  NO_COLOR:                     unset
  TERM:                         "xterm-256color"
  JS_RUNTIME_VERSION:           "v20.11.1"
  JS_RUNTIME_NAME:              "node"
  NODE_PACKAGE_MANAGER:         "pnpm/8.15.5"

Biome Configuration:
  Status:                       Loaded successfully
  Formatter disabled:           false
  Linter disabled:              false
  Organize imports disabled:    false
  VCS disabled:                 true

Workspace:
  Open Documents:               0

What happened?

  1. Have a Svelte component with code below
<script context="module" lang="ts">
	import { timeline, type TimelineSegment } from 'motion'
</script>
  1. Observe that type imports produce "import { type x ident }' are a TypeScript only feature". If imports are moved into regular svelte block, things work correctly.

Expected result

No error

Code of Conduct

  • I agree to follow Biome's Code of Conduct
@minht11
Copy link
Contributor Author

minht11 commented Mar 30, 2024

MouseEvent also fails with code below, interestingly only that part, interface itself does not produce any errors.

"Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax."

<script context="module" lang="ts">
	export interface ButtonProps {
		onclick?: (event: MouseEvent) => void
	}
</script>

@Xerios
Copy link

Xerios commented Mar 31, 2024

An option to override parsing would be great, forcing typescript on all "*.svelte" files might be an easy fix to this problem

@togami2864 togami2864 added S-Help-wanted Status: you're familiar with the code base and want to help the project S-Bug-confirmed Status: report has been confirmed as a valid bug A-Analyzer Area: analyzer labels Mar 31, 2024
@ematipico
Copy link
Member

The fix should be fairly easy, we need to update the regex to take context into account:

pub static ref SVELTE_FENCE: Regex = Regex::new(
r#"(?ixms)(?:<script[^>]?)
(?:
(?:(lang)\s*=\s*['"](?P<lang>[^'"]*)['"])
|
(?:(\w+)\s*(?:=\s*['"]([^'"]*)['"])?)
)*
[^>]*>\n(?P<script>(?U:.*))</script>"#
)
.unwrap();

Can anyone help?

@Sec-ant
Copy link
Member

Sec-ant commented Apr 4, 2024

@ematipico Instead of adding error prone syntaxes to our regexes, what do you think of using our jsx parser (for the time being of course) to parse the matched <script ... > openning element? This works for both svelte and vue.

#[test]
pub fn jsx_test() {
    let code = r#"
        <script context="module" lang="ts">
    "#;
    let root = parse(code, JsFileSource::jsx(), JsParserOptions::default());
    let syntax = root.syntax();
    dbg!(&syntax, root.diagnostics(), root.has_errors());
}

@ematipico
Copy link
Member

I'm not sure how reliable that would be though. The regex is good because it gives us the offsets we need to extract the code.

With the parser, we need to calculate the offsets ourselves, and rely on how well our parser can recover itself and still provide the correct ranges of the script tag.

@Sec-ant
Copy link
Member

Sec-ant commented Apr 4, 2024

I'm not sure how reliable that would be though. The regex is good because it gives us the offsets we need to extract the code.

With the parser, we need to calculate the offsets ourselves, and rely on how well our parser can recover itself and still provide the correct ranges of the script tag.

What I wanted to say is that we still use regex to match the script block so we can still have our script body and offsets, but instead we use the JSX parser to parse the opening element to extract the lang attribute reliably.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Analyzer Area: analyzer S-Bug-confirmed Status: report has been confirmed as a valid bug S-Help-wanted Status: you're familiar with the code base and want to help the project
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants