Skip to content

Commit 3138ee1

Browse files
committed
check invalid compute prop name
1 parent 06994ab commit 3138ee1

48 files changed

Lines changed: 1859 additions & 228 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 153 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ members = [
1414
"crates/middle",
1515
"crates/module_graph",
1616
"crates/module_resolve",
17+
"crates/napi",
1718
"crates/optimize",
1819
"crates/parser",
1920
"crates/path",

crates/ast/src/expr.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ impl<'cx> Expr<'cx> {
112112
)
113113
}
114114

115+
pub fn is_signed_numeric_lit(&self) -> bool {
116+
let ExprKind::PrefixUnary(n) = &self.kind else {
117+
return false;
118+
};
119+
matches!(n.op, PrefixUnaryOp::Plus | PrefixUnaryOp::Minus)
120+
&& matches!(n.expr.kind, ExprKind::NumLit(_))
121+
}
122+
115123
pub fn is_string_or_number_lit_like(&self) -> bool {
116124
self.is_string_lit_like() || matches!(self.kind, ExprKind::NumLit(_))
117125
}

crates/ast/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ impl<'cx> DeclarationName<'cx> {
7272
pub fn is_dynamic_name(&self) -> bool {
7373
use DeclarationName::*;
7474
match self {
75-
Computed(_) => true,
75+
Computed(n) => {
76+
!n.expr.is_string_or_number_lit_like() && !n.expr.is_signed_numeric_lit()
77+
}
7678
// TODO: element access
7779
_ => false,
7880
}

crates/ast/src/pprint.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ pub fn print_declaration_name(node: &super::DeclarationName, atoms: &AtomIntern)
1818
pub fn pprint_binding(binding: &super::Binding<'_>, atoms: &AtomIntern) -> String {
1919
match binding.kind {
2020
super::BindingKind::Ident(ident) => pprint_ident(ident, atoms),
21-
super::BindingKind::ObjectPat(n) => todo!(),
22-
crate::BindingKind::ArrayPat(n) => todo!(),
21+
super::BindingKind::ObjectPat(_) => todo!(),
22+
super::BindingKind::ArrayPat(_) => todo!(),
2323
}
2424
}
2525

crates/checker/src/check/check_class_decl_like.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::symbol_info::SymbolInfo;
2+
use super::ty;
3+
use super::ty::TypeFlags;
24
use super::{TyChecker, errors};
3-
use crate::ty;
4-
use crate::ty::TypeFlags;
55

66
use bolt_ts_ast::r#trait::ClassLike;
77
use bolt_ts_ast::{self as ast, pprint_ident};
@@ -100,7 +100,33 @@ impl<'cx> TyChecker<'cx> {
100100
self.check_fn_like_decl(method);
101101
}
102102

103+
pub(super) fn check_invalid_dynamic_name(
104+
&mut self,
105+
name: ast::DeclarationName<'cx>,
106+
push_error: impl FnOnce(&mut Self),
107+
) {
108+
if !self.is_non_bindable_dynamic_name(&name) {
109+
return;
110+
}
111+
let expr = match name {
112+
ast::DeclarationName::Computed(n) => n.expr,
113+
// TODO: element access expr
114+
_ => unreachable!(),
115+
};
116+
if !expr.is_entity_name_expr() {
117+
push_error(self);
118+
}
119+
}
120+
103121
fn check_class_prop_ele(&mut self, prop: &'cx ast::ClassPropElem<'cx>) {
122+
let decl_name = ast::DeclarationName::from_prop_name(prop.name);
123+
self.check_invalid_dynamic_name(decl_name, |this| {
124+
let error = errors::AComputedPropertyNameInAClassPropertyDeclarationMustHaveASimpleLiteralTypeOrAUniqueSymbolType {
125+
span: prop.name.span(),
126+
};
127+
this.push_error(Box::new(error));
128+
});
129+
104130
self.check_var_like_decl(prop);
105131
}
106132

crates/checker/src/check/check_deferred.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use bolt_ts_ast as ast;
22

3-
use crate::check::errors;
4-
use crate::check::relation::RelationKind;
5-
use crate::check::symbol_info::SymbolInfo;
6-
73
use super::NodeCheckFlags;
84
use super::TyChecker;
5+
use super::errors;
6+
use super::relation::RelationKind;
7+
use super::symbol_info::SymbolInfo;
98

109
impl<'cx> TyChecker<'cx> {
1110
pub(super) fn check_node_deferred(&mut self, node: ast::NodeID) {

crates/checker/src/check/check_interface.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,16 @@ impl<'cx> TyChecker<'cx> {
6161

6262
fn check_object_ty_member(&mut self, member: &'cx ast::ObjectTyMember<'cx>) {
6363
match member.kind {
64-
ast::ObjectTyMemberKind::Prop(n) => self.check_var_like_decl(n),
64+
ast::ObjectTyMemberKind::Prop(n) => {
65+
let decl_name = ast::DeclarationName::from_prop_name(n.name);
66+
self.check_invalid_dynamic_name(decl_name, |this| {
67+
let error = errors::AComputedPropertyNameInAnInterfaceMustReferToAnExpressionWhoseTypeIsALiteralTypeOrAUniqueSymbolType {
68+
span: n.name.span(),
69+
};
70+
this.push_error(Box::new(error));
71+
});
72+
self.check_var_like_decl(n)
73+
}
6574
_ => {
6675
// TODO:
6776
}

crates/checker/src/check/errors.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,3 +1099,23 @@ pub(super) struct RestTypesMayOnlyBeCreatedFromObjectTypes {
10991099
#[label(primary)]
11001100
pub span: Span,
11011101
}
1102+
1103+
#[derive(Error, Diagnostic, Debug, DiagnosticExt, Default)]
1104+
#[error(
1105+
"A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type."
1106+
)]
1107+
pub(super) struct AComputedPropertyNameInAClassPropertyDeclarationMustHaveASimpleLiteralTypeOrAUniqueSymbolType
1108+
{
1109+
#[label(primary)]
1110+
pub span: Span,
1111+
}
1112+
1113+
#[derive(Error, Diagnostic, Debug, DiagnosticExt, Default)]
1114+
#[error(
1115+
"A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type."
1116+
)]
1117+
pub(super) struct AComputedPropertyNameInAnInterfaceMustReferToAnExpressionWhoseTypeIsALiteralTypeOrAUniqueSymbolType
1118+
{
1119+
#[label(primary)]
1120+
pub span: Span,
1121+
}

crates/checker/src/check/flow.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::cell::OnceCell;
2-
use std::ptr::read_unaligned;
32

43
use super::FlowLoopTypesArenaId;
54
use super::TyChecker;

0 commit comments

Comments
 (0)