mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor(semantic): update the order of visit_function and Visit fields in the builder to be consistent (#4248)
Same as #4195
This commit is contained in:
parent
8bfeabfe6a
commit
ace4f1ff77
14 changed files with 221 additions and 217 deletions
|
|
@ -1439,7 +1439,7 @@ pub struct BindingRestElement<'a> {
|
|||
#[scope(
|
||||
// TODO: `ScopeFlags::Function` is not correct if this is a `MethodDefinition`
|
||||
flags(flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function),
|
||||
strict_if(self.body.as_ref().is_some_and(|body| body.has_use_strict_directive())),
|
||||
strict_if(self.is_strict()),
|
||||
)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
|
|
@ -1470,8 +1470,8 @@ pub struct Function<'a> {
|
|||
/// ```
|
||||
pub this_param: Option<TSThisParameter<'a>>,
|
||||
pub params: Box<'a, FormalParameters<'a>>,
|
||||
pub body: Option<Box<'a, FunctionBody<'a>>>,
|
||||
pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>,
|
||||
pub body: Option<Box<'a, FunctionBody<'a>>>,
|
||||
pub scope_id: Cell<Option<ScopeId>>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,8 +150,8 @@ impl<'a> AstBuilder<'a> {
|
|||
Option::<TSTypeParameterDeclaration>::None,
|
||||
None,
|
||||
params,
|
||||
body,
|
||||
Option::<TSTypeAnnotation>::None,
|
||||
body,
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -554,14 +554,14 @@ impl<'a> AstBuilder<'a> {
|
|||
type_parameters: T1,
|
||||
this_param: Option<TSThisParameter<'a>>,
|
||||
params: T2,
|
||||
body: T3,
|
||||
return_type: T4,
|
||||
return_type: T3,
|
||||
body: T4,
|
||||
) -> Expression<'a>
|
||||
where
|
||||
T1: IntoIn<'a, Option<Box<'a, TSTypeParameterDeclaration<'a>>>>,
|
||||
T2: IntoIn<'a, Box<'a, FormalParameters<'a>>>,
|
||||
T3: IntoIn<'a, Option<Box<'a, FunctionBody<'a>>>>,
|
||||
T4: IntoIn<'a, Option<Box<'a, TSTypeAnnotation<'a>>>>,
|
||||
T3: IntoIn<'a, Option<Box<'a, TSTypeAnnotation<'a>>>>,
|
||||
T4: IntoIn<'a, Option<Box<'a, FunctionBody<'a>>>>,
|
||||
{
|
||||
Expression::FunctionExpression(self.alloc(self.function(
|
||||
r#type,
|
||||
|
|
@ -573,8 +573,8 @@ impl<'a> AstBuilder<'a> {
|
|||
type_parameters,
|
||||
this_param,
|
||||
params,
|
||||
body,
|
||||
return_type,
|
||||
body,
|
||||
)))
|
||||
}
|
||||
|
||||
|
|
@ -2689,14 +2689,14 @@ impl<'a> AstBuilder<'a> {
|
|||
type_parameters: T1,
|
||||
this_param: Option<TSThisParameter<'a>>,
|
||||
params: T2,
|
||||
body: T3,
|
||||
return_type: T4,
|
||||
return_type: T3,
|
||||
body: T4,
|
||||
) -> Declaration<'a>
|
||||
where
|
||||
T1: IntoIn<'a, Option<Box<'a, TSTypeParameterDeclaration<'a>>>>,
|
||||
T2: IntoIn<'a, Box<'a, FormalParameters<'a>>>,
|
||||
T3: IntoIn<'a, Option<Box<'a, FunctionBody<'a>>>>,
|
||||
T4: IntoIn<'a, Option<Box<'a, TSTypeAnnotation<'a>>>>,
|
||||
T3: IntoIn<'a, Option<Box<'a, TSTypeAnnotation<'a>>>>,
|
||||
T4: IntoIn<'a, Option<Box<'a, FunctionBody<'a>>>>,
|
||||
{
|
||||
Declaration::FunctionDeclaration(self.alloc(self.function(
|
||||
r#type,
|
||||
|
|
@ -2708,8 +2708,8 @@ impl<'a> AstBuilder<'a> {
|
|||
type_parameters,
|
||||
this_param,
|
||||
params,
|
||||
body,
|
||||
return_type,
|
||||
body,
|
||||
)))
|
||||
}
|
||||
|
||||
|
|
@ -3720,14 +3720,14 @@ impl<'a> AstBuilder<'a> {
|
|||
type_parameters: T1,
|
||||
this_param: Option<TSThisParameter<'a>>,
|
||||
params: T2,
|
||||
body: T3,
|
||||
return_type: T4,
|
||||
return_type: T3,
|
||||
body: T4,
|
||||
) -> Function<'a>
|
||||
where
|
||||
T1: IntoIn<'a, Option<Box<'a, TSTypeParameterDeclaration<'a>>>>,
|
||||
T2: IntoIn<'a, Box<'a, FormalParameters<'a>>>,
|
||||
T3: IntoIn<'a, Option<Box<'a, FunctionBody<'a>>>>,
|
||||
T4: IntoIn<'a, Option<Box<'a, TSTypeAnnotation<'a>>>>,
|
||||
T3: IntoIn<'a, Option<Box<'a, TSTypeAnnotation<'a>>>>,
|
||||
T4: IntoIn<'a, Option<Box<'a, FunctionBody<'a>>>>,
|
||||
{
|
||||
Function {
|
||||
r#type,
|
||||
|
|
@ -3739,8 +3739,8 @@ impl<'a> AstBuilder<'a> {
|
|||
type_parameters: type_parameters.into_in(self.allocator),
|
||||
this_param,
|
||||
params: params.into_in(self.allocator),
|
||||
body: body.into_in(self.allocator),
|
||||
return_type: return_type.into_in(self.allocator),
|
||||
body: body.into_in(self.allocator),
|
||||
scope_id: Default::default(),
|
||||
}
|
||||
}
|
||||
|
|
@ -3757,14 +3757,14 @@ impl<'a> AstBuilder<'a> {
|
|||
type_parameters: T1,
|
||||
this_param: Option<TSThisParameter<'a>>,
|
||||
params: T2,
|
||||
body: T3,
|
||||
return_type: T4,
|
||||
return_type: T3,
|
||||
body: T4,
|
||||
) -> Box<'a, Function<'a>>
|
||||
where
|
||||
T1: IntoIn<'a, Option<Box<'a, TSTypeParameterDeclaration<'a>>>>,
|
||||
T2: IntoIn<'a, Box<'a, FormalParameters<'a>>>,
|
||||
T3: IntoIn<'a, Option<Box<'a, FunctionBody<'a>>>>,
|
||||
T4: IntoIn<'a, Option<Box<'a, TSTypeAnnotation<'a>>>>,
|
||||
T3: IntoIn<'a, Option<Box<'a, TSTypeAnnotation<'a>>>>,
|
||||
T4: IntoIn<'a, Option<Box<'a, FunctionBody<'a>>>>,
|
||||
{
|
||||
self.function(
|
||||
r#type,
|
||||
|
|
@ -3776,8 +3776,8 @@ impl<'a> AstBuilder<'a> {
|
|||
type_parameters,
|
||||
this_param,
|
||||
params,
|
||||
body,
|
||||
return_type,
|
||||
body,
|
||||
)
|
||||
.into_in(self.allocator)
|
||||
}
|
||||
|
|
@ -4901,14 +4901,14 @@ impl<'a> AstBuilder<'a> {
|
|||
type_parameters: T1,
|
||||
this_param: Option<TSThisParameter<'a>>,
|
||||
params: T2,
|
||||
body: T3,
|
||||
return_type: T4,
|
||||
return_type: T3,
|
||||
body: T4,
|
||||
) -> ExportDefaultDeclarationKind<'a>
|
||||
where
|
||||
T1: IntoIn<'a, Option<Box<'a, TSTypeParameterDeclaration<'a>>>>,
|
||||
T2: IntoIn<'a, Box<'a, FormalParameters<'a>>>,
|
||||
T3: IntoIn<'a, Option<Box<'a, FunctionBody<'a>>>>,
|
||||
T4: IntoIn<'a, Option<Box<'a, TSTypeAnnotation<'a>>>>,
|
||||
T3: IntoIn<'a, Option<Box<'a, TSTypeAnnotation<'a>>>>,
|
||||
T4: IntoIn<'a, Option<Box<'a, FunctionBody<'a>>>>,
|
||||
{
|
||||
ExportDefaultDeclarationKind::FunctionDeclaration(self.alloc(self.function(
|
||||
r#type,
|
||||
|
|
@ -4920,8 +4920,8 @@ impl<'a> AstBuilder<'a> {
|
|||
type_parameters,
|
||||
this_param,
|
||||
params,
|
||||
body,
|
||||
return_type,
|
||||
body,
|
||||
)))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3038,7 +3038,7 @@ pub mod walk {
|
|||
visitor.enter_scope(
|
||||
{
|
||||
let mut flags = flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function;
|
||||
if it.body.as_ref().is_some_and(|body| body.has_use_strict_directive()) {
|
||||
if it.is_strict() {
|
||||
flags |= ScopeFlags::StrictMode;
|
||||
}
|
||||
flags
|
||||
|
|
@ -3055,12 +3055,12 @@ pub mod walk {
|
|||
visitor.visit_ts_this_parameter(this_param);
|
||||
}
|
||||
visitor.visit_formal_parameters(&it.params);
|
||||
if let Some(body) = &it.body {
|
||||
visitor.visit_function_body(body);
|
||||
}
|
||||
if let Some(return_type) = &it.return_type {
|
||||
visitor.visit_ts_type_annotation(return_type);
|
||||
}
|
||||
if let Some(body) = &it.body {
|
||||
visitor.visit_function_body(body);
|
||||
}
|
||||
visitor.leave_scope();
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3171,7 +3171,7 @@ pub mod walk_mut {
|
|||
visitor.enter_scope(
|
||||
{
|
||||
let mut flags = flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function;
|
||||
if it.body.as_ref().is_some_and(|body| body.has_use_strict_directive()) {
|
||||
if it.is_strict() {
|
||||
flags |= ScopeFlags::StrictMode;
|
||||
}
|
||||
flags
|
||||
|
|
@ -3188,12 +3188,12 @@ pub mod walk_mut {
|
|||
visitor.visit_ts_this_parameter(this_param);
|
||||
}
|
||||
visitor.visit_formal_parameters(&mut it.params);
|
||||
if let Some(body) = &mut it.body {
|
||||
visitor.visit_function_body(body);
|
||||
}
|
||||
if let Some(return_type) = &mut it.return_type {
|
||||
visitor.visit_ts_type_annotation(return_type);
|
||||
}
|
||||
if let Some(body) = &mut it.body {
|
||||
visitor.visit_function_body(body);
|
||||
}
|
||||
visitor.leave_scope();
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,8 +123,8 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
self.ast.copy(&function.type_parameters),
|
||||
self.ast.copy(&function.this_param),
|
||||
params,
|
||||
Option::<FunctionBody>::None,
|
||||
return_type,
|
||||
Option::<FunctionBody>::None,
|
||||
);
|
||||
|
||||
self.ast.class_element_method_definition(
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
self.ast.copy(&func.type_parameters),
|
||||
self.ast.copy(&func.this_param),
|
||||
params,
|
||||
Option::<FunctionBody>::None,
|
||||
return_type,
|
||||
Option::<FunctionBody>::None,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,6 +208,14 @@ source: crates/oxc_linter/src/tester.rs
|
|||
╰────
|
||||
help: The `Function` type accepts any function-like value
|
||||
|
||||
⚠ typescript-eslint(ban-types): Do not use "String" as a type. Use "string" instead
|
||||
╭─[ban_types.tsx:5:24]
|
||||
4 │
|
||||
5 │ arg(): Array<String> {
|
||||
· ──────
|
||||
6 │ const foo: String = 1 as String;
|
||||
╰────
|
||||
|
||||
⚠ typescript-eslint(ban-types): Do not use "String" as a type. Use "string" instead
|
||||
╭─[ban_types.tsx:6:24]
|
||||
5 │ arg(): Array<String> {
|
||||
|
|
@ -224,14 +232,6 @@ source: crates/oxc_linter/src/tester.rs
|
|||
7 │ }
|
||||
╰────
|
||||
|
||||
⚠ typescript-eslint(ban-types): Do not use "String" as a type. Use "string" instead
|
||||
╭─[ban_types.tsx:5:24]
|
||||
4 │
|
||||
5 │ arg(): Array<String> {
|
||||
· ──────
|
||||
6 │ const foo: String = 1 as String;
|
||||
╰────
|
||||
|
||||
⚠ typescript-eslint(ban-types): Don't use `Function` as a type
|
||||
╭─[ban_types.tsx:3:12]
|
||||
2 │ type Props = {
|
||||
|
|
|
|||
|
|
@ -181,8 +181,8 @@ impl<'a> ParserImpl<'a> {
|
|||
type_parameters,
|
||||
this_param,
|
||||
params,
|
||||
body,
|
||||
return_type,
|
||||
body,
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,8 +106,9 @@ fn function_as_var(flags: ScopeFlags, source_type: SourceType) -> bool {
|
|||
impl<'a> Binder for Function<'a> {
|
||||
fn bind(&self, builder: &mut SemanticBuilder) {
|
||||
let current_scope_id = builder.current_scope_id;
|
||||
let scope_flags = builder.current_scope_flags();
|
||||
if let Some(ident) = &self.id {
|
||||
if !builder.current_scope_flags().is_strict_mode()
|
||||
if !scope_flags.is_strict_mode()
|
||||
&& matches!(
|
||||
builder.nodes.parent_kind(builder.current_node_id),
|
||||
Some(AstKind::IfStatement(_))
|
||||
|
|
@ -118,12 +119,10 @@ impl<'a> Binder for Function<'a> {
|
|||
} else if self.r#type == FunctionType::FunctionDeclaration {
|
||||
// The visitor is already inside the function scope,
|
||||
// retrieve the parent scope for the function id to bind to.
|
||||
let parent_scope_id = builder.scope.get_parent_id(current_scope_id).unwrap();
|
||||
let parent_flags = builder.scope.get_flags(parent_scope_id);
|
||||
|
||||
let (includes, excludes) =
|
||||
if (parent_flags.is_strict_mode() || self.r#async || self.generator)
|
||||
&& !function_as_var(parent_flags, builder.source_type)
|
||||
if (scope_flags.is_strict_mode() || self.r#async || self.generator)
|
||||
&& !function_as_var(scope_flags, builder.source_type)
|
||||
{
|
||||
(
|
||||
SymbolFlags::Function | SymbolFlags::BlockScopedVariable,
|
||||
|
|
@ -136,13 +135,7 @@ impl<'a> Binder for Function<'a> {
|
|||
)
|
||||
};
|
||||
|
||||
let symbol_id = builder.declare_symbol_on_scope(
|
||||
ident.span,
|
||||
&ident.name,
|
||||
parent_scope_id,
|
||||
includes,
|
||||
excludes,
|
||||
);
|
||||
let symbol_id = builder.declare_symbol(ident.span, &ident.name, includes, excludes);
|
||||
ident.symbol_id.set(Some(symbol_id));
|
||||
} else if self.r#type == FunctionType::FunctionExpression {
|
||||
// https://tc39.es/ecma262/#sec-runtime-semantics-instantiateordinaryfunctionexpression
|
||||
|
|
@ -158,7 +151,6 @@ impl<'a> Binder for Function<'a> {
|
|||
}
|
||||
|
||||
// bind scope flags: Constructor | GetAccessor | SetAccessor
|
||||
debug_assert!(builder.current_scope_flags().contains(ScopeFlags::Function));
|
||||
if let Some(kind) = builder.nodes.parent_kind(builder.current_node_id) {
|
||||
match kind {
|
||||
AstKind::MethodDefinition(def) => {
|
||||
|
|
|
|||
|
|
@ -414,13 +414,21 @@ impl<'a> SemanticBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_class_expression(&mut self) {
|
||||
if let AstKind::Class(class) = self.nodes.kind(self.current_node_id) {
|
||||
if class.is_expression() {
|
||||
// We must to bind class expression when enter BindingIdentifier,
|
||||
// because we should add binding to current scope
|
||||
class.bind(self);
|
||||
fn bind_function_or_class_expression(&mut self) {
|
||||
match self.nodes.kind(self.current_node_id) {
|
||||
AstKind::Class(class) => {
|
||||
if class.is_expression() {
|
||||
// We need to bind class expression in the class scope,
|
||||
class.bind(self);
|
||||
}
|
||||
}
|
||||
AstKind::Function(func) => {
|
||||
if func.is_expression() {
|
||||
// We need to bind function expression in the function scope,
|
||||
func.bind(self);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -461,8 +469,10 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
}
|
||||
|
||||
if !flags.is_top() {
|
||||
self.bind_class_expression();
|
||||
self.bind_function_or_class_expression();
|
||||
}
|
||||
|
||||
self.add_current_node_id_to_current_scope();
|
||||
}
|
||||
|
||||
fn leave_scope(&mut self) {
|
||||
|
|
@ -1408,18 +1418,6 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
}
|
||||
|
||||
fn visit_function(&mut self, func: &Function<'a>, flags: Option<ScopeFlags>) {
|
||||
let kind = AstKind::Function(self.alloc(func));
|
||||
self.enter_scope(
|
||||
{
|
||||
let mut flags = flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function;
|
||||
if func.is_strict() {
|
||||
flags |= ScopeFlags::StrictMode;
|
||||
}
|
||||
flags
|
||||
},
|
||||
&func.scope_id,
|
||||
);
|
||||
|
||||
/* cfg */
|
||||
let (before_function_graph_ix, error_harness, function_graph_ix) =
|
||||
control_flow!(|self, cfg| {
|
||||
|
|
@ -1434,7 +1432,22 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
|
||||
// We add a new basic block to the cfg before entering the node
|
||||
// so that the correct cfg_ix is associated with the ast node.
|
||||
let kind = AstKind::Function(self.alloc(func));
|
||||
self.enter_node(kind);
|
||||
self.enter_scope(
|
||||
{
|
||||
let mut flags = flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function;
|
||||
if func.is_strict() {
|
||||
flags |= ScopeFlags::StrictMode;
|
||||
}
|
||||
flags
|
||||
},
|
||||
&func.scope_id,
|
||||
);
|
||||
|
||||
if let Some(id) = &func.id {
|
||||
self.visit_binding_identifier(id);
|
||||
}
|
||||
|
||||
/* cfg */
|
||||
control_flow!(|self, cfg| cfg.add_edge(
|
||||
|
|
@ -1444,10 +1457,16 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
));
|
||||
/* cfg */
|
||||
|
||||
if let Some(ident) = &func.id {
|
||||
self.visit_binding_identifier(ident);
|
||||
if let Some(type_parameters) = &func.type_parameters {
|
||||
self.visit_ts_type_parameter_declaration(type_parameters);
|
||||
}
|
||||
if let Some(this_param) = &func.this_param {
|
||||
self.visit_ts_this_parameter(this_param);
|
||||
}
|
||||
self.visit_formal_parameters(&func.params);
|
||||
if let Some(return_type) = &func.return_type {
|
||||
self.visit_ts_type_annotation(return_type);
|
||||
}
|
||||
if let Some(body) = &func.body {
|
||||
self.visit_function_body(body);
|
||||
}
|
||||
|
|
@ -1462,20 +1481,11 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
});
|
||||
/* cfg */
|
||||
|
||||
if let Some(parameters) = &func.type_parameters {
|
||||
self.visit_ts_type_parameter_declaration(parameters);
|
||||
}
|
||||
if let Some(annotation) = &func.return_type {
|
||||
self.visit_ts_type_annotation(annotation);
|
||||
}
|
||||
self.leave_node(kind);
|
||||
self.leave_scope();
|
||||
self.leave_node(kind);
|
||||
}
|
||||
|
||||
fn visit_arrow_function_expression(&mut self, expr: &ArrowFunctionExpression<'a>) {
|
||||
let kind = AstKind::ArrowFunctionExpression(self.alloc(expr));
|
||||
self.enter_scope(ScopeFlags::Function | ScopeFlags::Arrow, &expr.scope_id);
|
||||
|
||||
/* cfg */
|
||||
let (current_node_ix, error_harness, function_graph_ix) = control_flow!(|self, cfg| {
|
||||
let current_node_ix = cfg.current_node_ix;
|
||||
|
|
@ -1489,7 +1499,9 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
|
||||
// We add a new basic block to the cfg before entering the node
|
||||
// so that the correct cfg_ix is associated with the ast node.
|
||||
let kind = AstKind::ArrowFunctionExpression(self.alloc(expr));
|
||||
self.enter_node(kind);
|
||||
self.enter_scope(ScopeFlags::Function | ScopeFlags::Arrow, &expr.scope_id);
|
||||
|
||||
self.visit_formal_parameters(&expr.params);
|
||||
|
||||
|
|
@ -1582,14 +1594,14 @@ impl<'a> SemanticBuilder<'a> {
|
|||
AstKind::StaticBlock(_) => self.label_builder.enter_function_or_static_block(),
|
||||
AstKind::Function(func) => {
|
||||
self.function_stack.push(self.current_node_id);
|
||||
func.bind(self);
|
||||
if func.is_declaration() {
|
||||
func.bind(self);
|
||||
}
|
||||
self.label_builder.enter_function_or_static_block();
|
||||
self.add_current_node_id_to_current_scope();
|
||||
self.make_all_namespaces_valuelike();
|
||||
}
|
||||
AstKind::ArrowFunctionExpression(_) => {
|
||||
self.function_stack.push(self.current_node_id);
|
||||
self.add_current_node_id_to_current_scope();
|
||||
self.make_all_namespaces_valuelike();
|
||||
}
|
||||
AstKind::Class(class) => {
|
||||
|
|
|
|||
|
|
@ -143,8 +143,8 @@ pub(crate) enum AncestorType {
|
|||
FunctionTypeParameters = 111,
|
||||
FunctionThisParam = 112,
|
||||
FunctionParams = 113,
|
||||
FunctionBody = 114,
|
||||
FunctionReturnType = 115,
|
||||
FunctionReturnType = 114,
|
||||
FunctionBody = 115,
|
||||
FormalParametersItems = 116,
|
||||
FormalParametersRest = 117,
|
||||
FormalParameterDecorators = 118,
|
||||
|
|
@ -531,8 +531,8 @@ pub enum Ancestor<'a> {
|
|||
AncestorType::FunctionTypeParameters as u16,
|
||||
FunctionThisParam(FunctionWithoutThisParam<'a>) = AncestorType::FunctionThisParam as u16,
|
||||
FunctionParams(FunctionWithoutParams<'a>) = AncestorType::FunctionParams as u16,
|
||||
FunctionBody(FunctionWithoutBody<'a>) = AncestorType::FunctionBody as u16,
|
||||
FunctionReturnType(FunctionWithoutReturnType<'a>) = AncestorType::FunctionReturnType as u16,
|
||||
FunctionBody(FunctionWithoutBody<'a>) = AncestorType::FunctionBody as u16,
|
||||
FormalParametersItems(FormalParametersWithoutItems<'a>) =
|
||||
AncestorType::FormalParametersItems as u16,
|
||||
FormalParametersRest(FormalParametersWithoutRest<'a>) =
|
||||
|
|
@ -1242,8 +1242,8 @@ impl<'a> Ancestor<'a> {
|
|||
| Self::FunctionTypeParameters(_)
|
||||
| Self::FunctionThisParam(_)
|
||||
| Self::FunctionParams(_)
|
||||
| Self::FunctionBody(_)
|
||||
| Self::FunctionReturnType(_)
|
||||
| Self::FunctionBody(_)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -5194,8 +5194,8 @@ pub(crate) const OFFSET_FUNCTION_DECLARE: usize = offset_of!(Function, declare);
|
|||
pub(crate) const OFFSET_FUNCTION_TYPE_PARAMETERS: usize = offset_of!(Function, type_parameters);
|
||||
pub(crate) const OFFSET_FUNCTION_THIS_PARAM: usize = offset_of!(Function, this_param);
|
||||
pub(crate) const OFFSET_FUNCTION_PARAMS: usize = offset_of!(Function, params);
|
||||
pub(crate) const OFFSET_FUNCTION_BODY: usize = offset_of!(Function, body);
|
||||
pub(crate) const OFFSET_FUNCTION_RETURN_TYPE: usize = offset_of!(Function, return_type);
|
||||
pub(crate) const OFFSET_FUNCTION_BODY: usize = offset_of!(Function, body);
|
||||
pub(crate) const OFFSET_FUNCTION_SCOPE_ID: usize = offset_of!(Function, scope_id);
|
||||
|
||||
#[repr(transparent)]
|
||||
|
|
@ -5252,14 +5252,6 @@ impl<'a> FunctionWithoutId<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn body(&self) -> &Option<Box<'a, FunctionBody<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_BODY)
|
||||
as *const Option<Box<'a, FunctionBody<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn return_type(&self) -> &Option<Box<'a, TSTypeAnnotation<'a>>> {
|
||||
unsafe {
|
||||
|
|
@ -5268,6 +5260,14 @@ impl<'a> FunctionWithoutId<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn body(&self) -> &Option<Box<'a, FunctionBody<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_BODY)
|
||||
as *const Option<Box<'a, FunctionBody<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scope_id(&self) -> &Cell<Option<ScopeId>> {
|
||||
unsafe {
|
||||
|
|
@ -5330,14 +5330,6 @@ impl<'a> FunctionWithoutTypeParameters<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn body(&self) -> &Option<Box<'a, FunctionBody<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_BODY)
|
||||
as *const Option<Box<'a, FunctionBody<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn return_type(&self) -> &Option<Box<'a, TSTypeAnnotation<'a>>> {
|
||||
unsafe {
|
||||
|
|
@ -5346,6 +5338,14 @@ impl<'a> FunctionWithoutTypeParameters<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn body(&self) -> &Option<Box<'a, FunctionBody<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_BODY)
|
||||
as *const Option<Box<'a, FunctionBody<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scope_id(&self) -> &Cell<Option<ScopeId>> {
|
||||
unsafe {
|
||||
|
|
@ -5408,14 +5408,6 @@ impl<'a> FunctionWithoutThisParam<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn body(&self) -> &Option<Box<'a, FunctionBody<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_BODY)
|
||||
as *const Option<Box<'a, FunctionBody<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn return_type(&self) -> &Option<Box<'a, TSTypeAnnotation<'a>>> {
|
||||
unsafe {
|
||||
|
|
@ -5424,6 +5416,14 @@ impl<'a> FunctionWithoutThisParam<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn body(&self) -> &Option<Box<'a, FunctionBody<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_BODY)
|
||||
as *const Option<Box<'a, FunctionBody<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scope_id(&self) -> &Cell<Option<ScopeId>> {
|
||||
unsafe {
|
||||
|
|
@ -5486,6 +5486,14 @@ impl<'a> FunctionWithoutParams<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn return_type(&self) -> &Option<Box<'a, TSTypeAnnotation<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_RETURN_TYPE)
|
||||
as *const Option<Box<'a, TSTypeAnnotation<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn body(&self) -> &Option<Box<'a, FunctionBody<'a>>> {
|
||||
unsafe {
|
||||
|
|
@ -5494,92 +5502,6 @@ impl<'a> FunctionWithoutParams<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn return_type(&self) -> &Option<Box<'a, TSTypeAnnotation<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_RETURN_TYPE)
|
||||
as *const Option<Box<'a, TSTypeAnnotation<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scope_id(&self) -> &Cell<Option<ScopeId>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_SCOPE_ID) as *const Cell<Option<ScopeId>>)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionWithoutBody<'a>(pub(crate) *const Function<'a>);
|
||||
|
||||
impl<'a> FunctionWithoutBody<'a> {
|
||||
#[inline]
|
||||
pub fn r#type(&self) -> &FunctionType {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_TYPE) as *const FunctionType) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn span(&self) -> &Span {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_SPAN) as *const Span) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn id(&self) -> &Option<BindingIdentifier<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_ID)
|
||||
as *const Option<BindingIdentifier<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn generator(&self) -> &bool {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_GENERATOR) as *const bool) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn r#async(&self) -> &bool {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_ASYNC) as *const bool) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn declare(&self) -> &bool {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_DECLARE) as *const bool) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn type_parameters(&self) -> &Option<Box<'a, TSTypeParameterDeclaration<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_TYPE_PARAMETERS)
|
||||
as *const Option<Box<'a, TSTypeParameterDeclaration<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn this_param(&self) -> &Option<TSThisParameter<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_THIS_PARAM)
|
||||
as *const Option<TSThisParameter<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn params(&self) -> &Box<'a, FormalParameters<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_PARAMS)
|
||||
as *const Box<'a, FormalParameters<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn return_type(&self) -> &Option<Box<'a, TSTypeAnnotation<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_RETURN_TYPE)
|
||||
as *const Option<Box<'a, TSTypeAnnotation<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scope_id(&self) -> &Cell<Option<ScopeId>> {
|
||||
unsafe {
|
||||
|
|
@ -5666,6 +5588,84 @@ impl<'a> FunctionWithoutReturnType<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionWithoutBody<'a>(pub(crate) *const Function<'a>);
|
||||
|
||||
impl<'a> FunctionWithoutBody<'a> {
|
||||
#[inline]
|
||||
pub fn r#type(&self) -> &FunctionType {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_TYPE) as *const FunctionType) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn span(&self) -> &Span {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_SPAN) as *const Span) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn id(&self) -> &Option<BindingIdentifier<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_ID)
|
||||
as *const Option<BindingIdentifier<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn generator(&self) -> &bool {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_GENERATOR) as *const bool) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn r#async(&self) -> &bool {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_ASYNC) as *const bool) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn declare(&self) -> &bool {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_DECLARE) as *const bool) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn type_parameters(&self) -> &Option<Box<'a, TSTypeParameterDeclaration<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_TYPE_PARAMETERS)
|
||||
as *const Option<Box<'a, TSTypeParameterDeclaration<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn this_param(&self) -> &Option<TSThisParameter<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_THIS_PARAM)
|
||||
as *const Option<TSThisParameter<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn params(&self) -> &Box<'a, FormalParameters<'a>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_PARAMS)
|
||||
as *const Box<'a, FormalParameters<'a>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn return_type(&self) -> &Option<Box<'a, TSTypeAnnotation<'a>>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_RETURN_TYPE)
|
||||
as *const Option<Box<'a, TSTypeAnnotation<'a>>>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scope_id(&self) -> &Cell<Option<ScopeId>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_FUNCTION_SCOPE_ID) as *const Cell<Option<ScopeId>>)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const OFFSET_FORMAL_PARAMETERS_SPAN: usize = offset_of!(FormalParameters, span);
|
||||
pub(crate) const OFFSET_FORMAL_PARAMETERS_KIND: usize = offset_of!(FormalParameters, kind);
|
||||
pub(crate) const OFFSET_FORMAL_PARAMETERS_ITEMS: usize = offset_of!(FormalParameters, items);
|
||||
|
|
|
|||
|
|
@ -2287,18 +2287,18 @@ pub(crate) unsafe fn walk_function<'a, Tr: Traverse<'a>>(
|
|||
as *mut Box<FormalParameters>)) as *mut _,
|
||||
ctx,
|
||||
);
|
||||
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_FUNCTION_BODY)
|
||||
as *mut Option<Box<FunctionBody>>)
|
||||
{
|
||||
ctx.retag_stack(AncestorType::FunctionBody);
|
||||
walk_function_body(traverser, (&mut **field) as *mut _, ctx);
|
||||
}
|
||||
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_FUNCTION_RETURN_TYPE)
|
||||
as *mut Option<Box<TSTypeAnnotation>>)
|
||||
{
|
||||
ctx.retag_stack(AncestorType::FunctionReturnType);
|
||||
walk_ts_type_annotation(traverser, (&mut **field) as *mut _, ctx);
|
||||
}
|
||||
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_FUNCTION_BODY)
|
||||
as *mut Option<Box<FunctionBody>>)
|
||||
{
|
||||
ctx.retag_stack(AncestorType::FunctionBody);
|
||||
walk_function_body(traverser, (&mut **field) as *mut _, ctx);
|
||||
}
|
||||
ctx.pop_stack();
|
||||
traverser.exit_function(&mut *node, ctx);
|
||||
if let Some(previous_scope_id) = previous_scope_id {
|
||||
|
|
|
|||
|
|
@ -20872,10 +20872,10 @@ Expect to Parse: "conformance/types/typeRelationships/typeAndMemberIdentity/obje
|
|||
17 │ // Type parameters and top-level local types are in same declaration space
|
||||
18 │ function f<T>() {
|
||||
· ┬
|
||||
· ╰── It can not be redeclared here
|
||||
· ╰── `T` has already been declared here
|
||||
19 │ interface T { }
|
||||
· ┬
|
||||
· ╰── `T` has already been declared here
|
||||
· ╰── It can not be redeclared here
|
||||
20 │ return undefined;
|
||||
╰────
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue