feat(semantic): report error on optional variable declaration in TypeScript (#2261)

closes #2253
closes #2255
This commit is contained in:
Boshen 2024-02-02 14:13:10 +08:00 committed by GitHub
parent 2578bb3d64
commit 8d99a15ac9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 69 additions and 3 deletions

View file

@ -16,9 +16,8 @@ impl EarlyErrorTypeScript {
pub fn run<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) { pub fn run<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) {
let kind = node.kind(); let kind = node.kind();
// should be removed when add more matches.
#[allow(clippy::single_match)]
match kind { match kind {
AstKind::VariableDeclarator(decl) => check_variable_declarator(decl, ctx),
AstKind::SimpleAssignmentTarget(target) => check_simple_assignment_target(target, ctx), AstKind::SimpleAssignmentTarget(target) => check_simple_assignment_target(target, ctx),
AstKind::FormalParameters(params) => check_formal_parameters(params, ctx), AstKind::FormalParameters(params) => check_formal_parameters(params, ctx),
_ => {} _ => {}
@ -26,6 +25,20 @@ impl EarlyErrorTypeScript {
} }
} }
#[allow(clippy::cast_possible_truncation)]
fn check_variable_declarator(decl: &VariableDeclarator, ctx: &SemanticBuilder<'_>) {
#[derive(Debug, Error, Diagnostic)]
#[error("Unexpected `?` operator")]
#[diagnostic()]
struct UnexpectedOptional(#[label] Span);
if decl.id.optional {
let start = decl.id.span().end;
let Some(offset) = ctx.source_text[start as usize..].find('?') else { return };
let offset = start + offset as u32;
ctx.error(UnexpectedOptional(Span::new(offset, offset)));
}
}
fn check_formal_parameters(params: &FormalParameters, ctx: &SemanticBuilder<'_>) { fn check_formal_parameters(params: &FormalParameters, ctx: &SemanticBuilder<'_>) {
if !params.is_empty() && params.kind == FormalParameterKind::Signature { if !params.is_empty() && params.kind == FormalParameterKind::Signature {
check_duplicate_bound_names(params, ctx); check_duplicate_bound_names(params, ctx);

View file

@ -0,0 +1,7 @@
const a? = "A"
const [b]? = ["B"]
const { c }? = { c: "C" }
const d ? = "A"
const [e, f] ? = ["B"]
const { g, h } ? = { c: "C" }

View file

@ -1,7 +1,7 @@
parser_misc Summary: parser_misc Summary:
AST Parsed : 10/10 (100.00%) AST Parsed : 10/10 (100.00%)
Positive Passed: 10/10 (100.00%) Positive Passed: 10/10 (100.00%)
Negative Passed: 5/5 (100.00%) Negative Passed: 6/6 (100.00%)
× Unexpected token × Unexpected token
╭─[fail/oxc-169.js:1:1] ╭─[fail/oxc-169.js:1:1]
1 │ 1<(V=82<<t-j0<(V=$<LBI<(V=ut<I<(V=$<LBI<(V=uIV=82<<t-j0<(V=$<LBI<(V=ut<I<(V=$<LBI<(V<II> 1 │ 1<(V=82<<t-j0<(V=$<LBI<(V=ut<I<(V=$<LBI<(V=uIV=82<<t-j0<(V=$<LBI<(V=ut<I<(V=$<LBI<(V<II>
@ -23,6 +23,52 @@ Negative Passed: 5/5 (100.00%)
3 │ } 3 │ }
╰──── ╰────
× Unexpected `?` operator
╭─[fail/oxc-2253.ts:1:1]
1 │ const a? = "A"
· ▲
2 │ const [b]? = ["B"]
╰────
× Unexpected `?` operator
╭─[fail/oxc-2253.ts:1:1]
1 │ const a? = "A"
2 │ const [b]? = ["B"]
· ▲
3 │ const { c }? = { c: "C" }
╰────
× Unexpected `?` operator
╭─[fail/oxc-2253.ts:2:1]
2 │ const [b]? = ["B"]
3 │ const { c }? = { c: "C" }
· ▲
4 │
╰────
× Unexpected `?` operator
╭─[fail/oxc-2253.ts:4:1]
4 │
5 │ const d ? = "A"
· ▲
6 │ const [e, f] ? = ["B"]
╰────
× Unexpected `?` operator
╭─[fail/oxc-2253.ts:5:1]
5 │ const d ? = "A"
6 │ const [e, f] ? = ["B"]
· ▲
7 │ const { g, h } ? = { c: "C" }
╰────
× Unexpected `?` operator
╭─[fail/oxc-2253.ts:6:1]
6 │ const [e, f] ? = ["B"]
7 │ const { g, h } ? = { c: "C" }
· ▲
╰────
× Empty parenthesized expression × Empty parenthesized expression
╭─[fail/oxc-232.js:1:1] ╭─[fail/oxc-232.js:1:1]
1 │ x = (/* a */) 1 │ x = (/* a */)