0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-08 07:16:56 -05:00

feat(unstable): align lint ast with TSEStree (#27996)

This PR fixes deviations in our AST format compared to TSEStree. They
are mostly a leftover for when I first started working on it and based
it off of babel instead.

One of the key changes why the changeset is a bit bigger is that
TSEStree uses `undefined` instead of `null` as the empty value for type
nodes. This is likely influenced by `tsc` which use `undefined`
everywhere. The rest of the nodes use `null` though. It's a little
weird, but for now it might be better to align.

(extracted from https://github.com/denoland/deno/pull/27977)
This commit is contained in:
Marvin Hagemeister 2025-02-06 21:45:56 +01:00 committed by GitHub
parent 89b1969f02
commit dd1ee5821b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 2085 additions and 891 deletions

View file

@ -485,6 +485,22 @@ impl SerializeCtx {
};
}
/// Helper for writing optional node offsets with undefined as empty value
pub fn write_maybe_undef_ref<P>(
&mut self,
prop: P,
parent: &PendingRef,
value: Option<NodeRef>,
) where
P: Into<u8> + Display + Clone,
{
if let Some(v) = value {
self.write_ref(prop, parent, v);
} else {
self.write_undefined(prop);
};
}
/// Write a vec of node offsets into the property. The necessary space
/// has been reserved earlier.
pub fn write_ref_vec<P>(

View file

@ -80,6 +80,7 @@ use deno_ast::swc::common::SyntaxContext;
use deno_ast::view::Accessibility;
use deno_ast::view::AssignOp;
use deno_ast::view::BinaryOp;
use deno_ast::view::MetaPropKind;
use deno_ast::view::MethodKind;
use deno_ast::view::TsKeywordTypeKind;
use deno_ast::view::TsTypeOperatorOp;
@ -91,8 +92,11 @@ use deno_ast::ParsedSource;
use super::buffer::AstBufSerializer;
use super::buffer::NodeRef;
use super::ts_estree::AstNode;
use super::ts_estree::MethodKind as TsEstreeMethodKind;
use super::ts_estree::PropertyKind;
use super::ts_estree::TsEsTreeBuilder;
use super::ts_estree::TsKeywordKind;
use super::ts_estree::TsModuleKind;
use crate::util::text_encoding::Utf16Map;
pub fn serialize_swc_to_buffer(
@ -175,8 +179,26 @@ fn serialize_module_decl(
ctx.write_import_decl(&node.span, node.type_only, src, specifiers, attrs)
}
ModuleDecl::ExportDecl(node) => {
let is_type_only = match &node.decl {
Decl::Class(_) => false,
Decl::Fn(_) => false,
Decl::Var(_) => false,
Decl::Using(_) => false,
Decl::TsInterface(_) => true,
Decl::TsTypeAlias(_) => true,
Decl::TsEnum(_) => true,
Decl::TsModule(_) => true,
};
let decl = serialize_decl(ctx, &node.decl);
ctx.write_export_decl(&node.span, decl)
ctx.write_export_named_decl(
&node.span,
is_type_only,
vec![],
None,
vec![],
Some(decl),
)
}
ModuleDecl::ExportNamed(node) => {
let attrs = serialize_import_attrs(ctx, &node.with);
@ -224,7 +246,14 @@ fn serialize_module_decl(
})
.collect::<Vec<_>>();
ctx.write_export_named_decl(&node.span, specifiers, source, attrs)
ctx.write_export_named_decl(
&node.span,
node.type_only,
specifiers,
source,
attrs,
None,
)
}
}
ModuleDecl::ExportDefaultDecl(node) => {
@ -293,17 +322,30 @@ fn serialize_module_decl(
.as_ref()
.map(|block| serialize_stmt(ctx, &Stmt::Block(block.clone())));
let decl = ctx.write_fn_decl(
&fn_obj.span,
false,
fn_obj.is_async,
fn_obj.is_generator,
ident,
type_params,
return_type,
body,
params,
);
let decl = if let Some(body) = body {
ctx.write_fn_decl(
&fn_obj.span,
false,
fn_obj.is_async,
fn_obj.is_generator,
ident,
type_params,
return_type,
body,
params,
)
} else {
ctx.write_ts_decl_fn(
&fn_obj.span,
false,
fn_obj.is_async,
fn_obj.is_generator,
ident,
type_params,
return_type,
params,
)
};
(false, decl)
}
@ -797,7 +839,7 @@ fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef {
let options = node
.args
.get(1)
.map_or(NodeRef(0), |arg| serialize_expr_or_spread(ctx, arg));
.map(|arg| serialize_expr_or_spread(ctx, arg));
ctx.write_import_expr(&node.span, source, options)
} else {
@ -919,12 +961,21 @@ fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef {
.as_ref()
.map(|ident| serialize_ident(ctx, ident, None));
let type_params =
maybe_serialize_ts_type_param_decl(ctx, &node.class.type_params);
let super_class = node
.class
.super_class
.as_ref()
.map(|expr| serialize_expr(ctx, expr.as_ref()));
let super_type_args = node
.class
.super_type_params
.as_ref()
.map(|param| serialize_ts_param_inst(ctx, param.as_ref()));
let implements = node
.class
.implements
@ -947,6 +998,8 @@ fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef {
node.class.is_abstract,
ident,
super_class,
super_type_args,
type_params,
implements,
body,
)
@ -960,8 +1013,17 @@ fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef {
ctx.write_yield_expr(&node.span, node.delegate, arg)
}
Expr::MetaProp(node) => {
let prop = ctx.write_identifier(&node.span, "meta", false, None);
ctx.write_meta_prop(&node.span, prop)
let (meta, prop) = match node.kind {
MetaPropKind::NewTarget => (
ctx.write_identifier(&node.span, "new", false, None),
ctx.write_identifier(&node.span, "target", false, None),
),
MetaPropKind::ImportMeta => (
ctx.write_identifier(&node.span, "import", false, None),
ctx.write_identifier(&node.span, "meta", false, None),
),
};
ctx.write_meta_prop(&node.span, meta, prop)
}
Expr::Await(node) => {
let arg = serialize_expr(ctx, node.arg.as_ref());
@ -1001,9 +1063,10 @@ fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef {
ctx.write_ts_as_expr(&node.span, expr, type_ann)
}
Expr::TsInstantiation(_) => {
// Invalid syntax
unreachable!()
Expr::TsInstantiation(node) => {
let expr = serialize_expr(ctx, &node.expr);
let type_args = serialize_ts_param_inst(ctx, node.type_args.as_ref());
ctx.write_ts_inst_expr(&node.span, expr, type_args)
}
Expr::TsSatisfies(node) => {
let expr = serialize_expr(ctx, node.expr.as_ref());
@ -1057,7 +1120,7 @@ fn serialize_prop_or_spread(
let mut shorthand = false;
let mut computed = false;
let mut method = false;
let mut kind = "init";
let mut kind = PropertyKind::Init;
let (key, value) = match prop.as_ref() {
Prop::Shorthand(ident) => {
@ -1086,7 +1149,7 @@ fn serialize_prop_or_spread(
(left, child_pos)
}
Prop::Getter(getter_prop) => {
kind = "get";
kind = PropertyKind::Get;
let key = serialize_prop_name(ctx, &getter_prop.key);
@ -1111,7 +1174,7 @@ fn serialize_prop_or_spread(
(key, value)
}
Prop::Setter(setter_prop) => {
kind = "set";
kind = PropertyKind::Set;
let key_id = serialize_prop_name(ctx, &setter_prop.key);
@ -1280,17 +1343,30 @@ fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef {
.map(|param| serialize_pat(ctx, &param.pat))
.collect::<Vec<_>>();
ctx.write_fn_decl(
&node.function.span,
node.declare,
node.function.is_async,
node.function.is_generator,
Some(ident_id),
type_param_id,
return_type,
body,
params,
)
if let Some(body) = body {
ctx.write_fn_decl(
&node.function.span,
node.declare,
node.function.is_async,
node.function.is_generator,
Some(ident_id),
type_param_id,
return_type,
body,
params,
)
} else {
ctx.write_ts_decl_fn(
&node.function.span,
node.declare,
node.function.is_async,
node.function.is_generator,
Some(ident_id),
type_param_id,
return_type,
params,
)
}
}
Decl::Var(node) => {
let children = node
@ -1303,7 +1379,7 @@ fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef {
.as_ref()
.map(|init| serialize_expr(ctx, init.as_ref()));
ctx.write_var_declarator(&decl.span, ident, init)
ctx.write_var_declarator(&decl.span, ident, init, decl.definite)
})
.collect::<Vec<_>>();
@ -1332,7 +1408,7 @@ fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef {
.as_ref()
.map(|init| serialize_expr(ctx, init.as_ref()));
ctx.write_var_declarator(&decl.span, ident, init)
ctx.write_var_declarator(&decl.span, ident, init, decl.definite)
})
.collect::<Vec<_>>();
@ -1366,7 +1442,7 @@ fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef {
let body_pos =
ctx.write_ts_interface_body(&node.body.span, body_elem_ids);
ctx.write_ts_interface(
ctx.write_ts_interface_decl(
&node.span,
node.declare,
ident_id,
@ -1428,7 +1504,11 @@ fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef {
ctx.write_ts_module_decl(
&node.span,
node.declare,
node.global,
if node.global {
TsModuleKind::Global
} else {
TsModuleKind::Module
},
ident,
body,
)
@ -1460,7 +1540,7 @@ fn serialize_ts_namespace_body(
ctx.write_ts_module_decl(
&node.span,
node.declare,
node.global,
TsModuleKind::Namespace,
ident,
Some(body),
)
@ -1562,7 +1642,13 @@ fn serialize_ts_index_sig(
.collect::<Vec<_>>();
let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann);
ctx.write_ts_index_sig(&node.span, node.readonly, params, type_ann)
ctx.write_ts_index_sig(
&node.span,
node.is_static,
node.readonly,
params,
type_ann,
)
}
fn accessibility_to_str(accessibility: &Accessibility) -> String {
@ -1785,7 +1871,7 @@ fn serialize_pat(ctx: &mut TsEsTreeBuilder, pat: &Pat) -> NodeRef {
false,
computed,
false,
"init",
PropertyKind::Init,
key,
value,
)
@ -1803,7 +1889,7 @@ fn serialize_pat(ctx: &mut TsEsTreeBuilder, pat: &Pat) -> NodeRef {
false,
false,
false,
"init",
PropertyKind::Init,
ident,
value,
)
@ -1995,7 +2081,7 @@ fn serialize_class_member(
node.is_optional,
false,
false,
"constructor",
TsEstreeMethodKind::Constructor,
a11y,
key,
value,
@ -2045,19 +2131,41 @@ fn serialize_class_member(
.map(|deco| serialize_decorator(ctx, deco))
.collect::<Vec<_>>();
Some(ctx.write_class_prop(
&node.span,
node.declare,
false,
node.is_optional,
node.is_override,
node.readonly,
node.is_static,
a11y,
decorators,
key,
value,
))
let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann);
let out = if node.is_abstract {
ctx.write_ts_abstract_prop_def(
&node.span,
false,
node.is_optional,
node.is_override,
node.is_static,
node.definite,
node.readonly,
node.declare,
a11y,
decorators,
key,
type_ann,
)
} else {
ctx.write_class_prop(
&node.span,
node.declare,
false,
node.is_optional,
node.is_override,
node.readonly,
node.is_static,
a11y,
decorators,
key,
value,
type_ann,
)
};
Some(out)
}
ClassMember::PrivateProp(node) => {
let a11y = node.accessibility.as_ref().map(accessibility_to_str);
@ -2072,6 +2180,8 @@ fn serialize_class_member(
let value = node.value.as_ref().map(|expr| serialize_expr(ctx, expr));
let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann);
Some(ctx.write_class_prop(
&node.span,
false,
@ -2084,6 +2194,7 @@ fn serialize_class_member(
decorators,
key,
value,
type_ann,
))
}
ClassMember::TsIndexSignature(node) => {
@ -2140,9 +2251,9 @@ fn serialize_class_method(
function: &Function,
) -> NodeRef {
let kind = match method_kind {
MethodKind::Method => "method",
MethodKind::Getter => "getter",
MethodKind::Setter => "setter",
MethodKind::Method => TsEstreeMethodKind::Method,
MethodKind::Getter => TsEstreeMethodKind::Get,
MethodKind::Setter => TsEstreeMethodKind::Set,
};
let type_params =
@ -2178,7 +2289,6 @@ fn serialize_class_method(
false,
function.is_async,
function.is_generator,
None,
type_params,
params,
return_type,
@ -2283,7 +2393,18 @@ fn serialize_ts_type(ctx: &mut TsEsTreeBuilder, node: &TsType) -> NodeRef {
.map(|param| serialize_ts_fn_param(ctx, param))
.collect::<Vec<_>>();
ctx.write_ts_fn_type(&node.span, param_ids)
let type_params = node
.type_params
.as_ref()
.map(|param| serialize_ts_type_param_decl(ctx, param));
let return_type = serialize_ts_type_ann(ctx, node.type_ann.as_ref());
ctx.write_ts_fn_type(
&node.span,
type_params,
param_ids,
Some(return_type),
)
}
TsFnOrConstructorType::TsConstructorType(node) => {
// interface Foo { new<T>(arg1: any): any }
@ -2349,10 +2470,17 @@ fn serialize_ts_type(ctx: &mut TsEsTreeBuilder, node: &TsType) -> NodeRef {
.iter()
.map(|elem| {
if let Some(label) = &elem.label {
let optional = match label {
Pat::Ident(binding_ident) => binding_ident.optional,
Pat::Array(array_pat) => array_pat.optional,
Pat::Object(object_pat) => object_pat.optional,
_ => false,
};
let label = serialize_pat(ctx, label);
let type_id = serialize_ts_type(ctx, elem.ty.as_ref());
ctx.write_ts_named_tuple_member(&elem.span, label, type_id)
ctx
.write_ts_named_tuple_member(&elem.span, label, type_id, optional)
} else {
serialize_ts_type(ctx, elem.ty.as_ref())
}
@ -2425,7 +2553,12 @@ fn serialize_ts_type(ctx: &mut TsEsTreeBuilder, node: &TsType) -> NodeRef {
TsType::TsMappedType(node) => {
let name = maybe_serialize_ts_type(ctx, &node.name_type);
let type_ann = maybe_serialize_ts_type(ctx, &node.type_ann);
let type_param = serialize_ts_type_param(ctx, &node.type_param);
let key = serialize_ident(ctx, &node.type_param.name, None);
let constraint = node
.type_param
.constraint
.as_ref()
.map_or(NodeRef(0), |node| serialize_ts_type(ctx, node));
ctx.write_ts_mapped_type(
&node.span,
@ -2433,7 +2566,8 @@ fn serialize_ts_type(ctx: &mut TsEsTreeBuilder, node: &TsType) -> NodeRef {
node.optional,
name,
type_ann,
type_param,
key,
constraint,
)
}
TsType::TsLitType(node) => serialize_ts_lit_type(ctx, node),

View file

@ -173,12 +173,15 @@ pub enum AstNode {
TSArrayType,
TSClassImplements,
TSAbstractMethodDefinition,
TSAbstractPropertyDefinition,
TSEmptyBodyFunctionExpression,
TSParameterProperty,
TSConstructSignatureDeclaration,
TSQualifiedName,
TSOptionalType,
TSTemplateLiteralType,
TSDeclareFunction,
TSInstantiationExpression,
TSAnyKeyword,
TSBigIntKeyword,
@ -582,12 +585,6 @@ impl TsEsTreeBuilder {
self.ctx.commit_node(id)
}
pub fn write_export_decl(&mut self, span: &Span, decl: NodeRef) -> NodeRef {
let id = self.ctx.append_node(AstNode::ExportNamedDeclaration, span);
self.ctx.write_ref(AstProp::Declaration, &id, decl);
self.ctx.commit_node(id)
}
pub fn write_export_all_decl(
&mut self,
span: &Span,
@ -626,14 +623,21 @@ impl TsEsTreeBuilder {
pub fn write_export_named_decl(
&mut self,
span: &Span,
is_type_only: bool,
specifiers: Vec<NodeRef>,
source: Option<NodeRef>,
attributes: Vec<NodeRef>,
declaration: Option<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::ExportNamedDeclaration, span);
let value = if is_type_only { "type" } else { "value" };
self.ctx.write_str(AstProp::ExportKind, value);
self.ctx.write_ref_vec(AstProp::Specifiers, &id, specifiers);
self.ctx.write_maybe_ref(AstProp::Source, &id, source);
self
.ctx
.write_maybe_ref(AstProp::Declaration, &id, declaration);
self.ctx.write_ref_vec(AstProp::Attributes, &id, attributes);
self.ctx.commit_node(id)
@ -721,11 +725,43 @@ impl TsEsTreeBuilder {
span: &Span,
ident: NodeRef,
init: Option<NodeRef>,
definite: bool,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::VariableDeclarator, span);
self.ctx.write_ref(AstProp::Id, &id, ident);
self.ctx.write_maybe_ref(AstProp::Init, &id, init);
self.ctx.write_bool(AstProp::Definite, definite);
self.ctx.commit_node(id)
}
#[allow(clippy::too_many_arguments)]
pub fn write_ts_decl_fn(
&mut self,
span: &Span,
is_declare: bool,
is_async: bool,
is_generator: bool,
ident: Option<NodeRef>,
type_param: Option<NodeRef>,
return_type: Option<NodeRef>,
params: Vec<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSDeclareFunction, span);
self.ctx.write_bool(AstProp::Declare, is_declare);
self.ctx.write_bool(AstProp::Async, is_async);
self.ctx.write_bool(AstProp::Generator, is_generator);
self.ctx.write_maybe_ref(AstProp::Id, &id, ident);
self
.ctx
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_param);
self
.ctx
.write_maybe_undef_ref(AstProp::ReturnType, &id, return_type);
self.ctx.write_undefined(AstProp::Body);
self.ctx.write_ref_vec(AstProp::Params, &id, params);
self.ctx.commit_node(id)
}
@ -742,7 +778,7 @@ impl TsEsTreeBuilder {
ident: Option<NodeRef>,
type_param: Option<NodeRef>,
return_type: Option<NodeRef>,
body: Option<NodeRef>,
body: NodeRef,
params: Vec<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::FunctionDeclaration, span);
@ -753,11 +789,11 @@ impl TsEsTreeBuilder {
self.ctx.write_maybe_ref(AstProp::Id, &id, ident);
self
.ctx
.write_maybe_ref(AstProp::TypeParameters, &id, type_param);
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_param);
self
.ctx
.write_maybe_ref(AstProp::ReturnType, &id, return_type);
self.ctx.write_maybe_ref(AstProp::Body, &id, body);
.write_maybe_undef_ref(AstProp::ReturnType, &id, return_type);
self.ctx.write_ref(AstProp::Body, &id, body);
self.ctx.write_ref_vec(AstProp::Params, &id, params);
self.ctx.commit_node(id)
@ -803,6 +839,8 @@ impl TsEsTreeBuilder {
is_abstract: bool,
ident: Option<NodeRef>,
super_class: Option<NodeRef>,
super_type_args: Option<NodeRef>,
type_params: Option<NodeRef>,
implements: Vec<NodeRef>,
body: NodeRef,
) -> NodeRef {
@ -813,6 +851,14 @@ impl TsEsTreeBuilder {
self
.ctx
.write_maybe_ref(AstProp::SuperClass, &id, super_class);
self.ctx.write_maybe_undef_ref(
AstProp::SuperTypeArguments,
&id,
super_type_args,
);
self
.ctx
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_params);
self.ctx.write_ref_vec(AstProp::Implements, &id, implements);
self.ctx.write_ref(AstProp::Body, &id, body);
@ -880,6 +926,7 @@ impl TsEsTreeBuilder {
decorators: Vec<NodeRef>,
key: NodeRef,
value: Option<NodeRef>,
type_ann: Option<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::PropertyDefinition, span);
@ -895,6 +942,9 @@ impl TsEsTreeBuilder {
self.ctx.write_ref(AstProp::Key, &id, key);
self.ctx.write_maybe_ref(AstProp::Value, &id, value);
self
.ctx
.write_maybe_undef_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.commit_node(id)
}
@ -908,7 +958,7 @@ impl TsEsTreeBuilder {
is_optional: bool,
is_override: bool,
is_static: bool,
kind: &str,
kind: MethodKind,
accessibility: Option<String>,
key: NodeRef,
value: NodeRef,
@ -920,10 +970,17 @@ impl TsEsTreeBuilder {
self.ctx.write_bool(AstProp::Optional, is_optional);
self.ctx.write_bool(AstProp::Override, is_override);
self.ctx.write_bool(AstProp::Static, is_static);
self.ctx.write_str(AstProp::Kind, kind);
let kind_str = match kind {
MethodKind::Constructor => "constructor",
MethodKind::Get => "get",
MethodKind::Method => "method",
MethodKind::Set => "set",
};
self.ctx.write_str(AstProp::Kind, kind_str);
self.write_accessibility(accessibility);
self.ctx.write_ref(AstProp::Key, &id, key);
self.ctx.write_ref(AstProp::Value, &id, value);
self.ctx.write_ref_vec(AstProp::Decorators, &id, vec![]);
self.ctx.commit_node(id)
}
@ -1238,11 +1295,11 @@ impl TsEsTreeBuilder {
self.ctx.write_maybe_ref(AstProp::Id, &id, ident);
self
.ctx
.write_maybe_ref(AstProp::TypeParameters, &id, type_params);
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_params);
self.ctx.write_ref_vec(AstProp::Params, &id, params);
self
.ctx
.write_maybe_ref(AstProp::ReturnType, &id, return_type);
.write_maybe_undef_ref(AstProp::ReturnType, &id, return_type);
self.ctx.write_maybe_ref(AstProp::Body, &id, body);
self.ctx.commit_node(id)
@ -1265,11 +1322,11 @@ impl TsEsTreeBuilder {
self.ctx.write_bool(AstProp::Generator, is_generator);
self
.ctx
.write_maybe_ref(AstProp::TypeParameters, &id, type_params);
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_params);
self.ctx.write_ref_vec(AstProp::Params, &id, params);
self
.ctx
.write_maybe_ref(AstProp::ReturnType, &id, return_type);
.write_maybe_undef_ref(AstProp::ReturnType, &id, return_type);
self.ctx.write_ref(AstProp::Body, &id, body);
self.ctx.commit_node(id)
@ -1311,7 +1368,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref(AstProp::Callee, &id, callee);
self
.ctx
.write_maybe_ref(AstProp::TypeArguments, &id, type_args);
.write_maybe_undef_ref(AstProp::TypeArguments, &id, type_args);
self.ctx.write_ref_vec(AstProp::Arguments, &id, args);
self.ctx.commit_node(id)
@ -1321,12 +1378,12 @@ impl TsEsTreeBuilder {
&mut self,
span: &Span,
source: NodeRef,
options: NodeRef,
options: Option<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::ImportExpression, span);
self.ctx.write_ref(AstProp::Source, &id, source);
self.ctx.write_ref(AstProp::Options, &id, options);
self.ctx.write_maybe_ref(AstProp::Options, &id, options);
self.ctx.commit_node(id)
}
@ -1477,7 +1534,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref(AstProp::Tag, &id, tag);
self
.ctx
.write_maybe_ref(AstProp::TypeArguments, &id, type_args);
.write_maybe_undef_ref(AstProp::TypeArguments, &id, type_args);
self.ctx.write_ref(AstProp::Quasi, &id, quasi);
self.ctx.commit_node(id)
@ -1503,8 +1560,14 @@ impl TsEsTreeBuilder {
self.ctx.commit_node(id)
}
pub fn write_meta_prop(&mut self, span: &Span, prop: NodeRef) -> NodeRef {
pub fn write_meta_prop(
&mut self,
span: &Span,
meta: NodeRef,
prop: NodeRef,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::MetaProperty, span);
self.ctx.write_ref(AstProp::Meta, &id, meta);
self.ctx.write_ref(AstProp::Property, &id, prop);
self.ctx.commit_node(id)
}
@ -1520,9 +1583,11 @@ impl TsEsTreeBuilder {
self.ctx.write_str(AstProp::Name, name);
self.ctx.write_bool(AstProp::Optional, optional);
self
.ctx
.write_maybe_ref(AstProp::TypeAnnotation, &id, type_annotation);
self.ctx.write_maybe_undef_ref(
AstProp::TypeAnnotation,
&id,
type_annotation,
);
self.ctx.commit_node(id)
}
@ -1563,7 +1628,7 @@ impl TsEsTreeBuilder {
self.ctx.write_bool(AstProp::Optional, optional);
self
.ctx
.write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann);
.write_maybe_undef_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.write_ref_vec(AstProp::Elements, &id, elems);
self.ctx.commit_node(id)
@ -1581,7 +1646,7 @@ impl TsEsTreeBuilder {
self.ctx.write_bool(AstProp::Optional, optional);
self
.ctx
.write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann);
.write_maybe_undef_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.write_ref_vec(AstProp::Properties, &id, props);
self.ctx.commit_node(id)
@ -1597,7 +1662,7 @@ impl TsEsTreeBuilder {
self
.ctx
.write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann);
.write_maybe_undef_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.write_ref(AstProp::Argument, &id, arg);
self.ctx.commit_node(id)
@ -1616,7 +1681,7 @@ impl TsEsTreeBuilder {
shorthand: bool,
computed: bool,
method: bool,
kind: &str,
kind: PropertyKind,
key: NodeRef,
value: NodeRef,
) -> NodeRef {
@ -1625,7 +1690,12 @@ impl TsEsTreeBuilder {
self.ctx.write_bool(AstProp::Shorthand, shorthand);
self.ctx.write_bool(AstProp::Computed, computed);
self.ctx.write_bool(AstProp::Method, method);
self.ctx.write_str(AstProp::Kind, kind);
let kind_str = match kind {
PropertyKind::Get => "get",
PropertyKind::Init => "init",
PropertyKind::Set => "set",
};
self.ctx.write_str(AstProp::Kind, kind_str);
self.ctx.write_ref(AstProp::Key, &id, key);
self.ctx.write_ref(AstProp::Value, &id, value);
@ -1773,7 +1843,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref_vec(AstProp::Attributes, &id, attrs);
self
.ctx
.write_maybe_ref(AstProp::TypeArguments, &id, type_args);
.write_maybe_undef_ref(AstProp::TypeArguments, &id, type_args);
self.ctx.commit_node(id)
}
@ -1880,16 +1950,21 @@ impl TsEsTreeBuilder {
&mut self,
span: &Span,
is_declare: bool,
is_global: bool,
kind: TsModuleKind,
ident: NodeRef,
body: Option<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSModuleDeclaration, span);
self.ctx.write_bool(AstProp::Declare, is_declare);
self.ctx.write_bool(AstProp::Global, is_global);
let kind_str = match kind {
TsModuleKind::Global => "global",
TsModuleKind::Namespace => "namespace",
TsModuleKind::Module => "module",
};
self.ctx.write_str(AstProp::Kind, kind_str);
self.ctx.write_ref(AstProp::Id, &id, ident);
self.ctx.write_maybe_ref(AstProp::Body, &id, body);
self.ctx.write_maybe_undef_ref(AstProp::Body, &id, body);
self.ctx.commit_node(id)
}
@ -1914,7 +1989,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref(AstProp::Expression, &id, expr);
self
.ctx
.write_maybe_ref(AstProp::TypeArguments, &id, type_args);
.write_maybe_undef_ref(AstProp::TypeArguments, &id, type_args);
self.ctx.commit_node(id)
}
@ -1944,7 +2019,47 @@ impl TsEsTreeBuilder {
self.ctx.write_str(AstProp::Kind, "method");
self.ctx.write_ref(AstProp::Key, &id, key);
self.ctx.write_ref(AstProp::Key, &id, value);
self.ctx.write_ref(AstProp::Value, &id, value);
self.ctx.commit_node(id)
}
#[allow(clippy::too_many_arguments)]
pub fn write_ts_abstract_prop_def(
&mut self,
span: &Span,
is_computed: bool,
is_optional: bool,
is_override: bool,
is_static: bool,
is_definite: bool,
is_readonly: bool,
is_declare: bool,
accessibility: Option<String>,
decorators: Vec<NodeRef>,
key: NodeRef,
type_ann: Option<NodeRef>,
) -> NodeRef {
let id = self
.ctx
.append_node(AstNode::TSAbstractPropertyDefinition, span);
self.ctx.write_bool(AstProp::Computed, is_computed);
self.ctx.write_bool(AstProp::Optional, is_optional);
self.ctx.write_bool(AstProp::Override, is_override);
self.ctx.write_bool(AstProp::Static, is_static);
self.ctx.write_bool(AstProp::Definite, is_definite);
self.ctx.write_bool(AstProp::Declare, is_declare);
self.ctx.write_bool(AstProp::Readonly, is_readonly);
self.write_accessibility(accessibility);
self.ctx.write_ref_vec(AstProp::Decorators, &id, decorators);
self.ctx.write_ref(AstProp::Key, &id, key);
self.ctx.write_null(AstProp::Value);
self
.ctx
.write_maybe_undef_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.commit_node(id)
}
@ -1957,7 +2072,6 @@ impl TsEsTreeBuilder {
is_expression: bool,
is_async: bool,
is_generator: bool,
ident: Option<NodeRef>,
type_params: Option<NodeRef>,
params: Vec<NodeRef>,
return_type: Option<NodeRef>,
@ -1970,14 +2084,15 @@ impl TsEsTreeBuilder {
self.ctx.write_bool(AstProp::Expression, is_expression);
self.ctx.write_bool(AstProp::Async, is_async);
self.ctx.write_bool(AstProp::Generator, is_generator);
self.ctx.write_maybe_ref(AstProp::Id, &id, ident);
self.ctx.write_null(AstProp::Id);
self
.ctx
.write_maybe_ref(AstProp::TypeParameters, &id, type_params);
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_params);
self.ctx.write_ref_vec(AstProp::Params, &id, params);
self
.ctx
.write_maybe_ref(AstProp::ReturnType, &id, return_type);
.write_maybe_undef_ref(AstProp::ReturnType, &id, return_type);
self.ctx.write_null(AstProp::Body);
self.ctx.commit_node(id)
}
@ -2016,11 +2131,11 @@ impl TsEsTreeBuilder {
self
.ctx
.write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann);
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_ann);
self.ctx.write_ref_vec(AstProp::Params, &id, params);
self
.ctx
.write_maybe_ref(AstProp::ReturnType, &id, return_type);
.write_maybe_undef_ref(AstProp::ReturnType, &id, return_type);
self.ctx.commit_node(id)
}
@ -2045,7 +2160,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref(AstProp::Key, &id, key);
self
.ctx
.write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann);
.write_maybe_undef_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.commit_node(id)
}
@ -2087,7 +2202,9 @@ impl TsEsTreeBuilder {
let id = self.ctx.append_node(AstNode::TSEnumMember, span);
self.ctx.write_ref(AstProp::Id, &id, ident);
self.ctx.write_maybe_ref(AstProp::Initializer, &id, init);
self
.ctx
.write_maybe_undef_ref(AstProp::Initializer, &id, init);
self.ctx.commit_node(id)
}
@ -2134,7 +2251,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref(AstProp::Id, &id, ident);
self
.ctx
.write_maybe_ref(AstProp::TypeParameters, &id, type_param);
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_param);
self.ctx.write_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.commit_node(id)
@ -2154,6 +2271,22 @@ impl TsEsTreeBuilder {
self.ctx.commit_node(id)
}
pub fn write_ts_inst_expr(
&mut self,
span: &Span,
expr: NodeRef,
type_arg: NodeRef,
) -> NodeRef {
let id = self
.ctx
.append_node(AstNode::TSInstantiationExpression, span);
self.ctx.write_ref(AstProp::Expression, &id, expr);
self.ctx.write_ref(AstProp::TypeArguments, &id, type_arg);
self.ctx.commit_node(id)
}
pub fn write_ts_as_expr(
&mut self,
span: &Span,
@ -2179,28 +2312,6 @@ impl TsEsTreeBuilder {
self.ctx.commit_node(id)
}
pub fn write_ts_interface(
&mut self,
span: &Span,
declare: bool,
ident: NodeRef,
type_param: Option<NodeRef>,
extends: Vec<NodeRef>,
body: NodeRef,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSInterface, span);
self.ctx.write_bool(AstProp::Declare, declare);
self.ctx.write_ref(AstProp::Id, &id, ident);
self.ctx.write_maybe_ref(AstProp::Extends, &id, type_param);
self
.ctx
.write_ref_vec(AstProp::TypeParameters, &id, extends);
self.ctx.write_ref(AstProp::Body, &id, body);
self.ctx.commit_node(id)
}
pub fn write_ts_interface_decl(
&mut self,
span: &Span,
@ -2214,10 +2325,10 @@ impl TsEsTreeBuilder {
self.ctx.write_bool(AstProp::Declare, declare);
self.ctx.write_ref(AstProp::Id, &id, ident);
self.ctx.write_maybe_ref(AstProp::Extends, &id, type_param);
self
.ctx
.write_ref_vec(AstProp::TypeParameters, &id, extends);
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_param);
self.ctx.write_ref_vec(AstProp::Extends, &id, extends);
self.ctx.write_ref(AstProp::Body, &id, body);
self.ctx.commit_node(id)
@ -2245,7 +2356,7 @@ impl TsEsTreeBuilder {
.append_node(AstNode::TSConstructSignatureDeclaration, span);
self
.ctx
.write_maybe_ref(AstProp::TypeParameters, &id, type_params);
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_params);
self.ctx.write_ref_vec(AstProp::Params, &id, params);
self.ctx.write_ref(AstProp::ReturnType, &id, return_type);
self.ctx.commit_node(id)
@ -2263,11 +2374,13 @@ impl TsEsTreeBuilder {
self.ctx.write_bool(AstProp::Optional, false);
self.ctx.write_bool(AstProp::Readonly, false);
self.ctx.write_bool(AstProp::Static, false);
self.ctx.write_str(AstProp::Kind, "getter");
self.ctx.write_str(AstProp::Kind, "get");
self.ctx.write_ref(AstProp::Key, &id, key);
self.ctx.write_ref_vec(AstProp::Params, &id, vec![]);
self
.ctx
.write_maybe_ref(AstProp::ReturnType, &id, return_type);
.write_maybe_undef_ref(AstProp::ReturnType, &id, return_type);
self.ctx.write_undefined(AstProp::TypeParameters);
self.ctx.commit_node(id)
}
@ -2284,9 +2397,11 @@ impl TsEsTreeBuilder {
self.ctx.write_bool(AstProp::Optional, false);
self.ctx.write_bool(AstProp::Readonly, false);
self.ctx.write_bool(AstProp::Static, false);
self.ctx.write_str(AstProp::Kind, "setter");
self.ctx.write_str(AstProp::Kind, "set");
self.ctx.write_ref(AstProp::Key, &id, key);
self.ctx.write_ref_vec(AstProp::Params, &id, vec![param]);
self.ctx.write_undefined(AstProp::ReturnType);
self.ctx.write_undefined(AstProp::TypeParameters);
self.ctx.commit_node(id)
}
@ -2316,7 +2431,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref_vec(AstProp::Params, &id, params);
self
.ctx
.write_maybe_ref(AstProp::ReturnType, &id, return_type);
.write_maybe_undef_ref(AstProp::ReturnType, &id, return_type);
self.ctx.commit_node(id)
}
@ -2332,7 +2447,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref(AstProp::Expression, &id, expr);
self
.ctx
.write_maybe_ref(AstProp::TypeArguments, &id, type_args);
.write_maybe_undef_ref(AstProp::TypeArguments, &id, type_args);
self.ctx.commit_node(id)
}
@ -2340,17 +2455,19 @@ impl TsEsTreeBuilder {
pub fn write_ts_index_sig(
&mut self,
span: &Span,
is_static: bool,
is_readonly: bool,
params: Vec<NodeRef>,
type_ann: Option<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSIndexSignature, span);
self.ctx.write_bool(AstProp::Static, is_static);
self.ctx.write_bool(AstProp::Readonly, is_readonly);
self.ctx.write_ref_vec(AstProp::Parameters, &id, params);
self
.ctx
.write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann);
.write_maybe_undef_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.commit_node(id)
}
@ -2466,6 +2583,7 @@ impl TsEsTreeBuilder {
self.ctx.commit_node(id)
}
#[allow(clippy::too_many_arguments)]
pub fn write_ts_mapped_type(
&mut self,
span: &Span,
@ -2473,7 +2591,8 @@ impl TsEsTreeBuilder {
optional: Option<TruePlusMinus>,
name: Option<NodeRef>,
type_ann: Option<NodeRef>,
type_param: NodeRef,
key: NodeRef,
constraint: NodeRef,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSMappedType, span);
@ -2482,8 +2601,9 @@ impl TsEsTreeBuilder {
self.ctx.write_maybe_ref(AstProp::NameType, &id, name);
self
.ctx
.write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.write_ref(AstProp::TypeParameter, &id, type_param);
.write_maybe_undef_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.write_ref(AstProp::Key, &id, key);
self.ctx.write_ref(AstProp::Constraint, &id, constraint);
self.ctx.commit_node(id)
}
@ -2559,7 +2679,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref(AstProp::ExprName, &id, expr_name);
self
.ctx
.write_maybe_ref(AstProp::TypeArguments, &id, type_arg);
.write_maybe_undef_ref(AstProp::TypeArguments, &id, type_arg);
self.ctx.commit_node(id)
}
@ -2575,7 +2695,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref(AstProp::TypeName, &id, type_name);
self
.ctx
.write_maybe_ref(AstProp::TypeArguments, &id, type_arg);
.write_maybe_undef_ref(AstProp::TypeArguments, &id, type_arg);
self.ctx.commit_node(id)
}
@ -2593,7 +2713,7 @@ impl TsEsTreeBuilder {
self.ctx.write_ref(AstProp::ParameterName, &id, param_name);
self
.ctx
.write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann);
.write_maybe_undef_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.commit_node(id)
}
@ -2617,9 +2737,11 @@ impl TsEsTreeBuilder {
span: &Span,
label: NodeRef,
elem_type: NodeRef,
optional: bool,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSNamedTupleMember, span);
self.ctx.write_bool(AstProp::Optional, optional);
self.ctx.write_ref(AstProp::Label, &id, label);
self.ctx.write_ref(AstProp::ElementType, &id, elem_type);
@ -2692,10 +2814,18 @@ impl TsEsTreeBuilder {
pub fn write_ts_fn_type(
&mut self,
span: &Span,
type_params: Option<NodeRef>,
params: Vec<NodeRef>,
return_type: Option<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSFunctionType, span);
self.ctx.write_ref_vec(AstProp::Params, &id, params);
self
.ctx
.write_maybe_undef_ref(AstProp::ReturnType, &id, return_type);
self
.ctx
.write_maybe_undef_ref(AstProp::TypeParameters, &id, type_params);
self.ctx.commit_node(id)
}
@ -2751,3 +2881,25 @@ pub enum TsKeywordKind {
Never,
Intrinsic,
}
#[derive(Debug)]
pub enum TsModuleKind {
Global,
Namespace,
Module,
}
#[derive(Debug)]
pub enum PropertyKind {
Get,
Init,
Set,
}
#[derive(Debug)]
pub enum MethodKind {
Constructor,
Get,
Method,
Set,
}

File diff suppressed because it is too large Load diff

View file

@ -550,6 +550,11 @@ Deno.test("Plugin - ClassExpression", async (t) => {
);
await testSnapshot(t, "a = class { #foo: number = bar }", "ClassExpression");
await testSnapshot(t, "a = class { static foo = bar }", "ClassExpression");
await testSnapshot(
t,
"a = class { static [key: string]: any }",
"ClassExpression",
);
await testSnapshot(
t,
"a = class { static foo; static { foo = bar } }",
@ -597,6 +602,7 @@ Deno.test("Plugin - MemberExpression", async (t) => {
Deno.test("Plugin - MetaProperty", async (t) => {
await testSnapshot(t, "import.meta", "MetaProperty");
await testSnapshot(t, "new.target", "MetaProperty");
});
Deno.test("Plugin - NewExpression", async (t) => {
@ -680,6 +686,36 @@ Deno.test("Plugin - Literal", async (t) => {
await testSnapshot(t, "/foo/g", "Literal");
});
// Stage 1 Proposal: https://github.com/tc39/proposal-grouped-and-auto-accessors
Deno.test.ignore(
"Plugin - AccessorProperty + TSAbstractAccessorProperty",
async (t) => {
await testSnapshot(
t,
`class Foo { accessor foo = 1; }`,
"AccessorProperty",
);
await testSnapshot(
t,
`abstract class Foo { abstract accessor foo: number = 1; }`,
"TSAbstractAccessorProperty",
);
},
);
Deno.test("Plugin - Abstract class", async (t) => {
await testSnapshot(
t,
`abstract class SomeClass { abstract prop: string; }`,
"ClassDeclaration",
);
await testSnapshot(
t,
`abstract class SomeClass { abstract method(): string; }`,
"ClassDeclaration",
);
});
Deno.test("Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr", async (t) => {
await testSnapshot(t, "<div />", "JSXElement");
await testSnapshot(t, "<div></div>", "JSXElement");
@ -715,28 +751,60 @@ Deno.test("Plugin - TSEnumDeclaration", async (t) => {
);
});
Deno.test("Plugin - TSInterface", async (t) => {
await testSnapshot(t, "interface A {}", "TSInterface");
await testSnapshot(t, "interface A<T> {}", "TSInterface");
await testSnapshot(t, "interface A extends Foo<T>, Bar<T> {}", "TSInterface");
await testSnapshot(t, "interface A { foo: any, bar?: any }", "TSInterface");
Deno.test("Plugin - TSInterfaceDeclaration", async (t) => {
await testSnapshot(t, "interface A {}", "TSInterfaceDeclaration");
await testSnapshot(t, "interface A<T> {}", "TSInterfaceDeclaration");
await testSnapshot(
t,
"interface A extends Foo<T>, Bar<T> {}",
"TSInterfaceDeclaration",
);
await testSnapshot(
t,
"interface A { foo: any, bar?: any }",
"TSInterfaceDeclaration",
);
await testSnapshot(
t,
"interface A { readonly [key: string]: any }",
"TSInterface",
"TSInterfaceDeclaration",
);
await testSnapshot(t, "interface A { readonly a: any }", "TSInterface");
await testSnapshot(t, "interface A { <T>(a: T): T }", "TSInterface");
await testSnapshot(t, "interface A { new <T>(a: T): T }", "TSInterface");
await testSnapshot(t, "interface A { a: new <T>(a: T) => T }", "TSInterface");
await testSnapshot(t, "interface A { get a(): string }", "TSInterface");
await testSnapshot(t, "interface A { set a(v: string) }", "TSInterface");
await testSnapshot(
t,
"interface A { readonly a: any }",
"TSInterfaceDeclaration",
);
await testSnapshot(
t,
"interface A { <T>(a: T): T }",
"TSInterfaceDeclaration",
);
await testSnapshot(
t,
"interface A { new <T>(a: T): T }",
"TSInterfaceDeclaration",
);
await testSnapshot(
t,
"interface A { a: new <T>(a: T) => T }",
"TSInterfaceDeclaration",
);
await testSnapshot(
t,
"interface A { get a(): string }",
"TSInterfaceDeclaration",
);
await testSnapshot(
t,
"interface A { set a(v: string) }",
"TSInterfaceDeclaration",
);
await testSnapshot(
t,
"interface A { a<T>(arg?: any, ...args: any[]): any }",
"TSInterface",
"TSInterfaceDeclaration",
);
});
@ -762,6 +830,16 @@ Deno.test("Plugin - TSIntersectionType", async (t) => {
await testSnapshot(t, "type A = B & C", "TSIntersectionType");
});
Deno.test("Plugin - TSInstantiationExpression", async (t) => {
await testSnapshot(t, "a<b>;", "TSInstantiationExpression");
await testSnapshot(t, "(a<b>)<c>;", "TSInstantiationExpression");
await testSnapshot(t, "(a<b>)<c>();", "TSInstantiationExpression");
await testSnapshot(t, "(a<b>)<c>();", "TSInstantiationExpression");
await testSnapshot(t, "(a<b>)<c>?.();", "TSInstantiationExpression");
await testSnapshot(t, "(a?.b<c>)<d>();", "TSInstantiationExpression");
await testSnapshot(t, "new (a<b>)<c>();", "TSInstantiationExpression");
});
Deno.test("Plugin - TSModuleDeclaration", async (t) => {
await testSnapshot(t, "module A {}", "TSModuleDeclaration");
await testSnapshot(
@ -771,6 +849,15 @@ Deno.test("Plugin - TSModuleDeclaration", async (t) => {
);
});
Deno.test("Plugin - TSDeclareFunction", async (t) => {
await testSnapshot(
t,
`async function foo(): any;
async function foo(): any {}`,
"TSDeclareFunction",
);
});
Deno.test("Plugin - TSModuleDeclaration + TSModuleBlock", async (t) => {
await testSnapshot(t, "module A {}", "TSModuleDeclaration");
await testSnapshot(
@ -871,6 +958,7 @@ Deno.test("Plugin - TSTupleType + TSArrayType", async (t) => {
await testSnapshot(t, "type A = [number]", "TSTupleType");
await testSnapshot(t, "type A = [x: number]", "TSTupleType");
await testSnapshot(t, "type A = [x: number]", "TSTupleType");
await testSnapshot(t, "type A = [x?: number]", "TSTupleType");
await testSnapshot(t, "type A = [...x: number[]]", "TSTupleType");
});