Skip to content

Commit

Permalink
fix(parser): export_named_type should parse default as normal
Browse files Browse the repository at this point in the history
  • Loading branch information
fireairforce committed Jan 20, 2025
1 parent c377f6b commit 5dbc643
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 26 deletions.
14 changes: 14 additions & 0 deletions .changeset/export_named_type_parser.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
cli: patch
biome_js_parser: patch
---

# Export Named Type support `default` parser

The following code:

```ts
export { type A as default } from './b.ts';
```

Should be parsed successfully.
21 changes: 8 additions & 13 deletions crates/biome_analyze/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use biome_console::markup;
use biome_parser::AnyParse;
use std::cmp::Ordering;
use std::collections::{BTreeMap, BinaryHeap};
use std::fmt::{Debug, Display, Formatter};
use std::ops;
Expand Down Expand Up @@ -432,7 +431,7 @@ where
// this signal: first try to load the last line suppression and see
// if it matches the current line index, otherwise perform a binary
// search over all the previously seen suppressions to find one
// with a matching range
// with a matching range, it will find the first one the match the current range.
let suppression =
self.suppressions
.line_suppressions
Expand All @@ -448,19 +447,15 @@ where
let index =
self.suppressions
.line_suppressions
.binary_search_by(|suppression| {
if suppression.text_range.end() < entry.text_range.start() {
Ordering::Less
} else if entry.text_range.end() < suppression.text_range.start() {
Ordering::Greater
} else {
Ordering::Equal
}
.partition_point(|suppression| {
suppression.text_range.end() < entry.text_range.start()
});

index
.ok()
.map(|index| &mut self.suppressions.line_suppressions[index])
if index >= self.suppressions.line_suppressions.len() {
None
} else {
Some(&mut self.suppressions.line_suppressions[index])
}
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ export declare class E { }
export type * from "types";

export type * as types from "types";

export { type default as G } from './types.ts';
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: crates/biome_formatter_test/src/snapshot_builder.rs
info: ts/module/export_clause.ts
snapshot_kind: text
---
# Input

Expand Down Expand Up @@ -28,6 +29,8 @@ export type * from "types";

export type * as types from "types";

export { type default as G } from './types.ts';

```


Expand Down Expand Up @@ -76,4 +79,6 @@ export declare class E {}
export type * from "types";

export type * as types from "types";

export { type default as G } from "./types.ts";
```
5 changes: 3 additions & 2 deletions crates/biome_js_parser/src/syntax/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,7 @@ where
// { type as } // name: `as` type-export: `true`
// { type as as } // name: `type` type-export: `false` (aliased to `as`)
// { type as as as } // name: `as` type-export: `true`, aliased to `as`
// { type default as as } // name: 'as' type-export: `true`, aliased to `as`
// ```
if p.at(T![type]) {
// `{ type identifier }`
Expand All @@ -977,8 +978,8 @@ where
metadata.is_type = true;
}
} else {
// `{ type x }` or `{ type "x" }` or `{ type x as }`
metadata.is_type = is_nth_name(p, 1);
// `{ type x }` or `{ type "x" }` or `{ type x as }` or `{ type default as }`
metadata.is_type = is_nth_name(p, 1) || p.nth_at(1, T![default]);
metadata.has_alias = p.nth_at(2, T![as]);
}
} else if p.at(T![as]) && is_nth_alias(p, 1) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { type A } from "a"
export { type } from "./type";
export { type default as CrsMeta } from './crs-meta.js';
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ snapshot_kind: text
```ts
export { type A } from "a"
export { type } from "./type";
export { type default as CrsMeta } from './crs-meta.js';
```

Expand Down Expand Up @@ -68,19 +69,48 @@ JsModule {
semicolon_token: SEMICOLON@56..57 ";" [] [],
},
},
JsExport {
decorators: JsDecoratorList [],
export_token: EXPORT_KW@57..65 "export" [Newline("\n")] [Whitespace(" ")],
export_clause: JsExportNamedFromClause {
type_token: missing (optional),
l_curly_token: L_CURLY@65..67 "{" [] [Whitespace(" ")],
specifiers: JsExportNamedFromSpecifierList [
JsExportNamedFromSpecifier {
type_token: TYPE_KW@67..72 "type" [] [Whitespace(" ")],
source_name: JsLiteralExportName {
value: IDENT@72..80 "default" [] [Whitespace(" ")],
},
export_as: JsExportAsClause {
as_token: AS_KW@80..83 "as" [] [Whitespace(" ")],
exported_name: JsLiteralExportName {
value: IDENT@83..91 "CrsMeta" [] [Whitespace(" ")],
},
},
},
],
r_curly_token: R_CURLY@91..93 "}" [] [Whitespace(" ")],
from_token: FROM_KW@93..98 "from" [] [Whitespace(" ")],
source: JsModuleSource {
value_token: JS_STRING_LITERAL@98..113 "'./crs-meta.js'" [] [],
},
assertion: missing (optional),
semicolon_token: SEMICOLON@113..114 ";" [] [],
},
},
],
eof_token: EOF@57..58 "" [Newline("\n")] [],
eof_token: EOF@114..115 "" [Newline("\n")] [],
}
```

## CST

```
0: JS_MODULE@0..58
0: JS_MODULE@0..115
0: (empty)
1: (empty)
2: JS_DIRECTIVE_LIST@0..0
3: JS_MODULE_ITEM_LIST@0..57
3: JS_MODULE_ITEM_LIST@0..114
0: JS_EXPORT@0..26
0: JS_DECORATOR_LIST@0..0
1: EXPORT_KW@0..7 "export" [] [Whitespace(" ")]
Expand Down Expand Up @@ -117,6 +147,27 @@ JsModule {
0: JS_STRING_LITERAL@48..56 "\"./type\"" [] []
6: (empty)
7: SEMICOLON@56..57 ";" [] []
4: EOF@57..58 "" [Newline("\n")] []
2: JS_EXPORT@57..114
0: JS_DECORATOR_LIST@57..57
1: EXPORT_KW@57..65 "export" [Newline("\n")] [Whitespace(" ")]
2: JS_EXPORT_NAMED_FROM_CLAUSE@65..114
0: (empty)
1: L_CURLY@65..67 "{" [] [Whitespace(" ")]
2: JS_EXPORT_NAMED_FROM_SPECIFIER_LIST@67..91
0: JS_EXPORT_NAMED_FROM_SPECIFIER@67..91
0: TYPE_KW@67..72 "type" [] [Whitespace(" ")]
1: JS_LITERAL_EXPORT_NAME@72..80
0: IDENT@72..80 "default" [] [Whitespace(" ")]
2: JS_EXPORT_AS_CLAUSE@80..91
0: AS_KW@80..83 "as" [] [Whitespace(" ")]
1: JS_LITERAL_EXPORT_NAME@83..91
0: IDENT@83..91 "CrsMeta" [] [Whitespace(" ")]
3: R_CURLY@91..93 "}" [] [Whitespace(" ")]
4: FROM_KW@93..98 "from" [] [Whitespace(" ")]
5: JS_MODULE_SOURCE@98..113
0: JS_STRING_LITERAL@98..113 "'./crs-meta.js'" [] []
6: (empty)
7: SEMICOLON@113..114 ";" [] []
4: EOF@114..115 "" [Newline("\n")] []
```
8 changes: 1 addition & 7 deletions crates/biome_js_parser/tests/spec_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,7 @@ pub fn run(test_case: &str, _snapshot_name: &str, test_directory: &str, outcome_
#[test]
pub fn quick_test() {
let code = r#"
export let shim: typeof import("./foo2") = {
Bar: Bar2
};
export interface Foo {
bar: import('immutable').Map<string, int>;
}
export { type default as CrsMeta } from './crs-meta.js';
"#;

let root = parse(code, JsFileSource::ts(), JsParserOptions::default());
Expand Down

0 comments on commit 5dbc643

Please sign in to comment.