From 91f14e26c0cc66a05e399fbf4487e51c49e65469 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 23 May 2024 14:03:00 +0200 Subject: [PATCH] feat(symbols): collect symbols for params This includes type params, function params, and params declared through `infer X` in type annotations. --- src/fast_check/swc_helpers.rs | 97 --- src/fast_check/transform.rs | 16 +- src/lib.rs | 1 + src/swc_helpers.rs | 112 +++ src/symbols/analyzer.rs | 280 +++++++- src/symbols/dep_analyzer.rs | 1 + tests/helpers/mod.rs | 56 +- tests/specs/symbols/Classes01.txt | 640 +++++++++++++++--- tests/specs/symbols/Functions01.txt | 288 ++++++-- .../class_private_ctor_param_props.txt | 44 +- tests/specs/symbols/declaration_merging01.txt | 68 +- tests/specs/symbols/function_overloads01.txt | 232 ++++++- tests/specs/symbols/ts_namespace_export01.txt | 34 + 13 files changed, 1531 insertions(+), 338 deletions(-) create mode 100644 src/swc_helpers.rs diff --git a/src/fast_check/swc_helpers.rs b/src/fast_check/swc_helpers.rs index e2fe1fead..5b501eb65 100644 --- a/src/fast_check/swc_helpers.rs +++ b/src/fast_check/swc_helpers.rs @@ -1,7 +1,5 @@ // Copyright 2018-2024 the Deno authors. MIT license. -use std::ops::ControlFlow; - use deno_ast::swc::ast::*; use deno_ast::swc::common::DUMMY_SP; @@ -20,101 +18,6 @@ pub fn ts_keyword_type(kind: TsKeywordTypeKind) -> TsType { }) } -#[derive(Debug)] -pub enum ReturnStatementAnalysis { - /// There are no return statements in the function body. - None, - /// There are only return statements without arguments in the function body, - /// or if the function body is empty. - Void, - /// There is only a single return statement in the function body, and it has - /// an argument. - Single(ReturnStmt), - /// There are multiple return statements in the function body, and at least - /// one of them has an argument. - Multiple, -} - -pub fn analyze_return_stmts_in_function_body( - body: &deno_ast::swc::ast::BlockStmt, -) -> ReturnStatementAnalysis { - if body.stmts.is_empty() { - ReturnStatementAnalysis::Void - } else { - let mut analysis = ReturnStatementAnalysis::None; - analyze_return_stmts_from_stmts(&body.stmts, &mut analysis); - analysis - } -} - -fn analyze_return_stmts_from_stmts( - stmts: &[Stmt], - analysis: &mut ReturnStatementAnalysis, -) -> ControlFlow<(), ()> { - for stmt in stmts { - analyze_return_stmts_from_stmt(stmt, analysis)?; - } - ControlFlow::Continue(()) -} - -fn analyze_return_stmts_from_stmt( - stmt: &Stmt, - analysis: &mut ReturnStatementAnalysis, -) -> ControlFlow<(), ()> { - match stmt { - Stmt::Block(n) => analyze_return_stmts_from_stmts(&n.stmts, analysis), - Stmt::With(n) => analyze_return_stmts_from_stmt(&n.body, analysis), - Stmt::Return(n) => { - match (&n.arg, &*analysis) { - (None, ReturnStatementAnalysis::None) => { - *analysis = ReturnStatementAnalysis::Void; - } - (None, ReturnStatementAnalysis::Void) => {} - (Some(_), ReturnStatementAnalysis::None) - | (Some(_), ReturnStatementAnalysis::Void) => { - *analysis = ReturnStatementAnalysis::Single(n.clone()); - } - (_, ReturnStatementAnalysis::Single(_)) => { - *analysis = ReturnStatementAnalysis::Multiple; - return ControlFlow::Break(()); - } - (_, ReturnStatementAnalysis::Multiple) => unreachable!(), // we break early when analysis is Multiple - } - ControlFlow::Continue(()) - } - Stmt::Labeled(n) => analyze_return_stmts_from_stmt(&n.body, analysis), - Stmt::If(n) => analyze_return_stmts_from_stmt(&n.cons, analysis), - Stmt::Switch(n) => { - for case in &n.cases { - analyze_return_stmts_from_stmts(&case.cons, analysis)?; - } - ControlFlow::Continue(()) - } - Stmt::Try(n) => { - analyze_return_stmts_from_stmts(&n.block.stmts, analysis)?; - if let Some(n) = &n.handler { - analyze_return_stmts_from_stmts(&n.body.stmts, analysis)?; - } - if let Some(n) = &n.finalizer { - analyze_return_stmts_from_stmts(&n.stmts, analysis)?; - } - ControlFlow::Continue(()) - } - Stmt::While(n) => analyze_return_stmts_from_stmt(&n.body, analysis), - Stmt::DoWhile(n) => analyze_return_stmts_from_stmt(&n.body, analysis), - Stmt::For(n) => analyze_return_stmts_from_stmt(&n.body, analysis), - Stmt::ForIn(n) => analyze_return_stmts_from_stmt(&n.body, analysis), - Stmt::ForOf(n) => analyze_return_stmts_from_stmt(&n.body, analysis), - Stmt::Break(_) - | Stmt::Continue(_) - | Stmt::Throw(_) - | Stmt::Debugger(_) - | Stmt::Decl(_) - | Stmt::Expr(_) - | Stmt::Empty(_) => ControlFlow::Continue(()), - } -} - pub fn is_void_type(return_type: &TsType) -> bool { is_keyword_type(return_type, TsKeywordTypeKind::TsVoidKeyword) } diff --git a/src/fast_check/transform.rs b/src/fast_check/transform.rs index 12446970d..6a9bc6323 100644 --- a/src/fast_check/transform.rs +++ b/src/fast_check/transform.rs @@ -25,6 +25,9 @@ use deno_ast::SourceRange; use deno_ast::SourceRangedForSpanned; use indexmap::IndexMap; +use crate::swc_helpers::analyze_return_stmts_in_function_body; +use crate::swc_helpers::FunctionKind; +use crate::swc_helpers::ReturnStatementAnalysis; use crate::symbols::EsModuleInfo; use crate::symbols::ExpandoPropertyRef; use crate::symbols::Symbol; @@ -34,13 +37,11 @@ use crate::ParserModuleAnalyzer; use crate::WorkspaceMember; use super::range_finder::ModulePublicRanges; -use super::swc_helpers::analyze_return_stmts_in_function_body; use super::swc_helpers::any_type_ann; use super::swc_helpers::ident; use super::swc_helpers::is_void_type; use super::swc_helpers::maybe_lit_to_ts_type; use super::swc_helpers::ts_keyword_type; -use super::swc_helpers::ReturnStatementAnalysis; use super::transform_dts::FastCheckDtsDiagnostic; use super::transform_dts::FastCheckDtsTransformer; use super::FastCheckDiagnostic; @@ -1898,17 +1899,6 @@ impl<'a> FastCheckTransformer<'a> { } } -enum FunctionKind { - /// function declarations, class method declarations (both class decl and class expr) - DeclarationLike, - /// function expressions, arrow functions, object method shorthand properties - ExpressionLike, - /// getters, both on classes and object literals - Getter, - /// setters, both on classes and object literals - Setter, -} - fn is_ts_private_computed_class_member(m: &ClassMember) -> bool { match m { ClassMember::Method(m) => { diff --git a/src/lib.rs b/src/lib.rs index fc7980ef3..2d0b484bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,7 @@ mod fast_check; pub mod packages; pub mod source; mod text_encoding; +mod swc_helpers; use source::FileSystem; use source::JsrUrlProvider; diff --git a/src/swc_helpers.rs b/src/swc_helpers.rs new file mode 100644 index 000000000..a8b33984a --- /dev/null +++ b/src/swc_helpers.rs @@ -0,0 +1,112 @@ +// Copyright 2018-2024 the Deno authors. MIT license. + +use std::ops::ControlFlow; + +use deno_ast::swc::ast::ReturnStmt; +use deno_ast::swc::ast::Stmt; + +pub enum FunctionKind { + /// function declarations, class method declarations (both class decl and class expr) + DeclarationLike, + /// function expressions, arrow functions, object method shorthand properties + ExpressionLike, + /// getters, both on classes and object literals + Getter, + /// setters, both on classes and object literals + Setter, +} + +#[derive(Debug)] +pub enum ReturnStatementAnalysis { + /// There are no return statements in the function body. + None, + /// There are only return statements without arguments in the function body, + /// or if the function body is empty. + Void, + /// There is only a single return statement in the function body, and it has + /// an argument. + Single(ReturnStmt), + /// There are multiple return statements in the function body, and at least + /// one of them has an argument. + Multiple, +} + +pub fn analyze_return_stmts_in_function_body( + body: &deno_ast::swc::ast::BlockStmt, +) -> ReturnStatementAnalysis { + if body.stmts.is_empty() { + ReturnStatementAnalysis::Void + } else { + let mut analysis = ReturnStatementAnalysis::None; + analyze_return_stmts_from_stmts(&body.stmts, &mut analysis); + analysis + } +} + +fn analyze_return_stmts_from_stmts( + stmts: &[Stmt], + analysis: &mut ReturnStatementAnalysis, +) -> ControlFlow<(), ()> { + for stmt in stmts { + analyze_return_stmts_from_stmt(stmt, analysis)?; + } + ControlFlow::Continue(()) +} + +fn analyze_return_stmts_from_stmt( + stmt: &Stmt, + analysis: &mut ReturnStatementAnalysis, +) -> ControlFlow<(), ()> { + match stmt { + Stmt::Block(n) => analyze_return_stmts_from_stmts(&n.stmts, analysis), + Stmt::With(n) => analyze_return_stmts_from_stmt(&n.body, analysis), + Stmt::Return(n) => { + match (&n.arg, &*analysis) { + (None, ReturnStatementAnalysis::None) => { + *analysis = ReturnStatementAnalysis::Void; + } + (None, ReturnStatementAnalysis::Void) => {} + (Some(_), ReturnStatementAnalysis::None) + | (Some(_), ReturnStatementAnalysis::Void) => { + *analysis = ReturnStatementAnalysis::Single(n.clone()); + } + (_, ReturnStatementAnalysis::Single(_)) => { + *analysis = ReturnStatementAnalysis::Multiple; + return ControlFlow::Break(()); + } + (_, ReturnStatementAnalysis::Multiple) => unreachable!(), // we break early when analysis is Multiple + } + ControlFlow::Continue(()) + } + Stmt::Labeled(n) => analyze_return_stmts_from_stmt(&n.body, analysis), + Stmt::If(n) => analyze_return_stmts_from_stmt(&n.cons, analysis), + Stmt::Switch(n) => { + for case in &n.cases { + analyze_return_stmts_from_stmts(&case.cons, analysis)?; + } + ControlFlow::Continue(()) + } + Stmt::Try(n) => { + analyze_return_stmts_from_stmts(&n.block.stmts, analysis)?; + if let Some(n) = &n.handler { + analyze_return_stmts_from_stmts(&n.body.stmts, analysis)?; + } + if let Some(n) = &n.finalizer { + analyze_return_stmts_from_stmts(&n.stmts, analysis)?; + } + ControlFlow::Continue(()) + } + Stmt::While(n) => analyze_return_stmts_from_stmt(&n.body, analysis), + Stmt::DoWhile(n) => analyze_return_stmts_from_stmt(&n.body, analysis), + Stmt::For(n) => analyze_return_stmts_from_stmt(&n.body, analysis), + Stmt::ForIn(n) => analyze_return_stmts_from_stmt(&n.body, analysis), + Stmt::ForOf(n) => analyze_return_stmts_from_stmt(&n.body, analysis), + Stmt::Break(_) + | Stmt::Continue(_) + | Stmt::Throw(_) + | Stmt::Debugger(_) + | Stmt::Decl(_) + | Stmt::Expr(_) + | Stmt::Empty(_) => ControlFlow::Continue(()), + } +} diff --git a/src/symbols/analyzer.rs b/src/symbols/analyzer.rs index a8fc4ee9a..f327ad1bd 100644 --- a/src/symbols/analyzer.rs +++ b/src/symbols/analyzer.rs @@ -10,6 +10,8 @@ use deno_ast::swc::ast::*; use deno_ast::swc::atoms::Atom; use deno_ast::swc::utils::find_pat_ids; use deno_ast::swc::utils::is_valid_ident; +use deno_ast::swc::visit::Visit; +use deno_ast::swc::visit::VisitWith as _; use deno_ast::ModuleSpecifier; use deno_ast::ParsedSource; use deno_ast::SourceRange; @@ -18,6 +20,9 @@ use deno_ast::SourceTextInfo; use indexmap::IndexMap; use indexmap::IndexSet; +use crate::swc_helpers::analyze_return_stmts_in_function_body; +use crate::swc_helpers::FunctionKind; +use crate::swc_helpers::ReturnStatementAnalysis; use crate::JsModule; use crate::JsonModule; use crate::ModuleGraph; @@ -368,6 +373,7 @@ impl std::fmt::Debug for SymbolNode { SymbolNodeInner::FnDecl(d) => { d.value().text_fast(d.source.text_info()).to_string() } + SymbolNodeInner::Param { ident, .. } => ident.sym.to_string(), SymbolNodeInner::TsEnum(d) => { d.value().text_fast(d.source.text_info()).to_string() } @@ -492,6 +498,9 @@ impl SymbolNode { SymbolNodeInner::FnDecl(n) => { Some((SymbolNodeRef::FnDecl(n.value()), n.source())) } + SymbolNodeInner::Param { ident, source } => { + Some((SymbolNodeRef::Param(ident), source)) + } SymbolNodeInner::TsEnum(n) => { Some((SymbolNodeRef::TsEnum(n.value()), n.source())) } @@ -577,6 +586,7 @@ enum SymbolNodeInner { ExportDefaultDecl(NodeRefBox), ExportDefaultExpr(NodeRefBox), FnDecl(NodeRefBox), + Param { ident: Ident, source: ParsedSource }, TsEnum(NodeRefBox), TsNamespace(NodeRefBox), TsTypeAlias(NodeRefBox), @@ -617,6 +627,7 @@ pub enum SymbolNodeRef<'a> { ExportDefaultExpr(&'a ExportDefaultExpr), ClassDecl(&'a ClassDecl), FnDecl(&'a FnDecl), + Param(&'a Ident), TsEnum(&'a TsEnumDecl), TsInterface(&'a TsInterfaceDecl), TsNamespace(&'a TsModuleDecl), @@ -715,6 +726,7 @@ impl<'a> SymbolNodeRef<'a> { }, Self::ExportDefaultExpr(_) => None, Self::FnDecl(n) => Some(Cow::Borrowed(&n.ident.sym)), + Self::Param(n) => Some(Cow::Borrowed(&n.sym)), Self::TsEnum(n) => Some(Cow::Borrowed(&n.id.sym)), Self::TsInterface(n) => Some(Cow::Borrowed(&n.id.sym)), Self::TsNamespace(n) => { @@ -829,7 +841,8 @@ impl<'a> SymbolNodeRef<'a> { | SymbolNodeRef::ClassDecl(_) | SymbolNodeRef::TsEnum(_) | SymbolNodeRef::TsInterface(_) => true, - SymbolNodeRef::TsTypeAlias(_) + SymbolNodeRef::Param(_) + | SymbolNodeRef::TsTypeAlias(_) | SymbolNodeRef::ExportDefaultExpr(_) | SymbolNodeRef::Var(..) | SymbolNodeRef::UsingVar(..) @@ -859,6 +872,7 @@ impl<'a> SymbolNodeRef<'a> { SymbolNodeRef::Module(_) | SymbolNodeRef::ClassDecl(_) | SymbolNodeRef::FnDecl(_) + | SymbolNodeRef::Param(_) | SymbolNodeRef::TsEnum(_) | SymbolNodeRef::TsInterface(_) | SymbolNodeRef::TsNamespace(_) @@ -902,6 +916,7 @@ impl<'a> SymbolNodeRef<'a> { | SymbolNodeRef::ClassParamProp(_) | SymbolNodeRef::Constructor(_) | SymbolNodeRef::ExpandoProperty(..) + | SymbolNodeRef::Param(_) | SymbolNodeRef::TsIndexSignature(_) | SymbolNodeRef::TsCallSignatureDecl(_) | SymbolNodeRef::TsConstructSignatureDecl(_) @@ -921,6 +936,7 @@ impl<'a> SymbolNodeRef<'a> { | SymbolNodeRef::ExportDefaultDecl(_) | SymbolNodeRef::ExportDefaultExpr(_) | SymbolNodeRef::FnDecl(_) + | SymbolNodeRef::Param(_) | SymbolNodeRef::TsEnum(_) | SymbolNodeRef::TsInterface(_) | SymbolNodeRef::TsNamespace(_) @@ -952,6 +968,7 @@ impl<'a> SymbolNodeRef<'a> { | SymbolNodeRef::ExportDefaultDecl(_) | SymbolNodeRef::ExportDefaultExpr(_) | SymbolNodeRef::FnDecl(_) + | SymbolNodeRef::Param(_) | SymbolNodeRef::TsEnum(_) | SymbolNodeRef::TsInterface(_) | SymbolNodeRef::TsNamespace(_) @@ -1335,6 +1352,16 @@ impl Symbol { .map(|n| n.is_private_member()) .unwrap_or(false) } + + /// If the symbol is a parameter. + pub fn is_param(&self) -> bool { + self + .decls() + .first() + .and_then(|d| d.maybe_node()) + .map(|n| matches!(n, SymbolNodeRef::Param(_))) + .unwrap_or(false) + } } /// A unique identifier for a symbol, which consists of the module id and symbol id. @@ -1989,6 +2016,11 @@ impl<'a> SymbolFiller<'a> { ); module_symbol.add_export(n.ident.sym.to_string(), symbol_id); module_symbol.add_child_id(symbol_id); + self.fill_function( + symbol_id, + &n.function, + FunctionKind::DeclarationLike, + ); } Decl::Var(n) => { for decl in &n.decls { @@ -2015,6 +2047,7 @@ impl<'a> SymbolFiller<'a> { module_symbol.add_child_id(symbol_id); module_symbol.add_export(export_name, symbol_id); } + self.fill_var_decl(module_symbol.symbol_id(), decl); } } Decl::TsInterface(n) => { @@ -2261,8 +2294,12 @@ impl<'a> SymbolFiller<'a> { DefaultDecl::Class(n) => { self.fill_class(symbol, &n.class); } - DefaultDecl::Fn(_) => { - // nothing to fill + DefaultDecl::Fn(n) => { + self.fill_function( + symbol.symbol_id(), + &n.function, + FunctionKind::DeclarationLike, + ); } DefaultDecl::TsInterfaceDecl(n) => { self.fill_ts_interface(symbol, n) @@ -2394,6 +2431,11 @@ impl<'a> SymbolFiller<'a> { if decls_are_exports { module_symbol.add_export(n.ident.sym.to_string(), symbol_id); } + self.fill_function( + symbol_id, + &n.function, + FunctionKind::DeclarationLike, + ); } Decl::Var(var_decl) => { for decl in &var_decl.decls { @@ -2419,6 +2461,7 @@ impl<'a> SymbolFiller<'a> { module_symbol.add_export(export_name, symbol_id); } } + self.fill_var_decl(module_symbol.symbol_id(), decl); } } Decl::TsInterface(n) => { @@ -2534,6 +2577,7 @@ impl<'a> SymbolFiller<'a> { module_symbol.add_export(export_name, symbol_id); } } + self.fill_var_decl(module_symbol.symbol_id(), decl); } } }; @@ -2620,6 +2664,11 @@ impl<'a> SymbolFiller<'a> { } fn fill_class(&self, symbol: &SymbolMut, n: &Class) { + if let Some(type_params) = n.type_params.as_ref() { + for param in &type_params.params { + self.add_param(symbol.symbol_id(), param.name.clone()); + } + } self.fill_ts_class_members(symbol, &n.body); } @@ -2732,33 +2781,49 @@ impl<'a> SymbolFiller<'a> { for member in members { match member { ClassMember::Constructor(ctor) => { - self.create_symbol_member_or_export( + let ctor_symbol = self.create_symbol_member_or_export( symbol, SymbolNodeRef::Constructor(ctor), ); for param in &ctor.params { - if let ParamOrTsParamProp::TsParamProp(prop) = param { - self.create_symbol_member_or_export( - symbol, - SymbolNodeRef::ClassParamProp(prop), - ); + match param { + ParamOrTsParamProp::TsParamProp(prop) => { + self.create_symbol_member_or_export( + symbol, + SymbolNodeRef::ClassParamProp(prop), + ); + } + ParamOrTsParamProp::Param(param) => self.fill_fn_params( + ctor_symbol.symbol_id(), + [¶m.pat].into_iter(), + ), } } } ClassMember::Method(method) => { - self.create_symbol_member_or_export( + let method_symbol = self.create_symbol_member_or_export( symbol, SymbolNodeRef::ClassMethod(method), ); + self.fill_function( + method_symbol.symbol_id(), + &method.function, + FunctionKind::DeclarationLike, + ); } ClassMember::PrivateMethod(_) => { // todo(dsherret): add private methods } ClassMember::ClassProp(prop) => { - self.create_symbol_member_or_export( + let prop_symbol = self.create_symbol_member_or_export( symbol, SymbolNodeRef::ClassProp(prop), ); + if prop.type_ann.is_none() { + if let Some(value) = &prop.value { + self.fill_expr(prop_symbol.symbol_id(), value); + } + } } ClassMember::PrivateProp(_) => { // todo(dsherret): add private properties @@ -2883,6 +2948,7 @@ impl<'a> SymbolFiller<'a> { | SymbolNodeRef::ExportDefaultDecl(_) | SymbolNodeRef::ExportDefaultExpr(_) | SymbolNodeRef::FnDecl(_) + | SymbolNodeRef::Param(_) | SymbolNodeRef::TsEnum(_) | SymbolNodeRef::TsInterface(_) | SymbolNodeRef::TsNamespace(_) @@ -2978,4 +3044,196 @@ impl<'a> SymbolFiller<'a> { } None } + + fn fill_function( + &self, + symbol_id: SymbolId, + n: &Function, + fn_kind: FunctionKind, + ) { + if let Some(type_params) = n.type_params.as_ref() { + for param in &type_params.params { + self.add_param(symbol_id, param.name.clone()); + } + } + self.fill_fn_params(symbol_id, n.params.iter().map(|p| &p.pat)); + if let Some(type_ann) = n.return_type.as_ref() { + self.fill_ts_type(symbol_id, &type_ann.type_ann); + } else if let Some(body) = n.body.as_ref() { + self.fill_fn_body(symbol_id, body, fn_kind); + } + } + + fn fill_arrow_expr(&self, symbol_id: SymbolId, n: &ArrowExpr) { + if let Some(type_params) = n.type_params.as_ref() { + for param in &type_params.params { + self.add_param(symbol_id, param.name.clone()); + } + } + self.fill_fn_params(symbol_id, n.params.iter()); + if let Some(type_ann) = n.return_type.as_ref() { + self.fill_ts_type(symbol_id, &type_ann.type_ann); + } else { + match &*n.body { + BlockStmtOrExpr::BlockStmt(block) => { + self.fill_fn_body(symbol_id, block, FunctionKind::ExpressionLike); + } + BlockStmtOrExpr::Expr(expr) => { + self.fill_expr(symbol_id, expr); + } + } + } + } + + fn fill_fn_params<'b>( + &self, + symbol_id: SymbolId, + params: impl Iterator, + ) { + for param in params { + let (pat, default_value) = match param { + Pat::Assign(pat) => (&*pat.left, Some(&pat.right)), + _ => (param, None), + }; + + let type_ann = match pat { + Pat::Ident(n) => n.type_ann.as_ref(), + Pat::Array(n) => n.type_ann.as_ref(), + Pat::Object(n) => n.type_ann.as_ref(), + Pat::Rest(n) => n.type_ann.as_ref(), + Pat::Invalid(_) | Pat::Expr(_) | Pat::Assign(_) => unreachable!(), + }; + + if let Some(type_ann) = type_ann { + self.fill_ts_type(symbol_id, &type_ann.type_ann); + } else if let Some(default_value) = default_value { + self.fill_expr(symbol_id, default_value); + } + + for ident in find_pat_ids::<_, Ident>(pat) { + self.add_param(symbol_id, ident); + } + } + } + + fn add_param(&self, parent_id: SymbolId, ident: Ident) { + let range = ident.range(); + self.builder.ensure_symbol_for_swc_id( + ident.to_id(), + SymbolDecl::new( + SymbolDeclKind::Definition(SymbolNode(SymbolNodeInner::Param { + ident, + source: self.source.clone(), + })), + range, + ), + parent_id, + ); + } + + fn fill_ts_type(&self, symbol_id: SymbolId, type_ann: &TsType) { + struct TsTypeVisitor { + idents: I, + } + impl Visit for TsTypeVisitor { + fn visit_ts_infer_type(&mut self, n: &TsInferType) { + (self.idents)(&n.type_param.name); + } + + fn visit_ts_type_param(&mut self, n: &TsTypeParam) { + (self.idents)(&n.name); + } + + fn visit_ts_fn_param(&mut self, n: &TsFnParam) { + match n { + TsFnParam::Ident(ident) => { + (self.idents)(&ident.id); + } + TsFnParam::Array(n) => { + for ident in find_pat_ids::<_, Ident>(n) { + (self.idents)(&ident); + } + } + TsFnParam::Rest(n) => { + for ident in find_pat_ids::<_, Ident>(n) { + (self.idents)(&ident); + } + } + TsFnParam::Object(n) => { + for ident in find_pat_ids::<_, Ident>(n) { + (self.idents)(&ident); + } + } + } + } + } + + let mut visitor = TsTypeVisitor { + idents: |ident| { + self.add_param(symbol_id, ident.clone()); + }, + }; + type_ann.visit_with(&mut visitor); + } + + fn fill_fn_body( + &self, + symbol_id: SymbolId, + body: &BlockStmt, + fn_kind: FunctionKind, + ) { + let analysis = analyze_return_stmts_in_function_body(body); + if let ( + FunctionKind::DeclarationLike | FunctionKind::ExpressionLike, + ReturnStatementAnalysis::Single(stmt), + ) = (fn_kind, analysis) + { + self.fill_expr(symbol_id, stmt.arg.as_ref().unwrap()); + } + } + + fn fill_expr(&self, symbol_id: SymbolId, expr: &Expr) { + struct ExprVisitor { + fn_exprs: F, + arrow_exprs: A, + } + impl Visit for ExprVisitor { + fn visit_fn_expr(&mut self, n: &FnExpr) { + (self.fn_exprs)(n); + } + fn visit_arrow_expr(&mut self, n: &ArrowExpr) { + (self.arrow_exprs)(n); + } + } + + let mut visitor = ExprVisitor { + fn_exprs: |n| { + self.fill_function( + symbol_id, + &n.function, + FunctionKind::ExpressionLike, + ); + }, + arrow_exprs: |n| { + self.fill_arrow_expr(symbol_id, n); + }, + }; + expr.visit_with(&mut visitor); + } + + fn fill_var_decl(&self, symbol_id: SymbolId, decl: &VarDeclarator) { + let type_ann = match &decl.name { + Pat::Ident(n) => n.type_ann.as_ref(), + Pat::Array(n) => n.type_ann.as_ref(), + Pat::Object(n) => n.type_ann.as_ref(), + Pat::Rest(_) | Pat::Invalid(_) | Pat::Expr(_) | Pat::Assign(_) => { + unreachable!() + } + }; + if let Some(type_ann) = type_ann { + self.fill_ts_type(symbol_id, &type_ann.type_ann); + } else if let Some(init) = decl.init.as_ref() { + self.fill_expr(symbol_id, init); + } + } } diff --git a/src/symbols/dep_analyzer.rs b/src/symbols/dep_analyzer.rs index c2867d953..5cf99d2c0 100644 --- a/src/symbols/dep_analyzer.rs +++ b/src/symbols/dep_analyzer.rs @@ -127,6 +127,7 @@ impl DepsFiller { self.visit_expr(&n.expr); } SymbolNodeRef::FnDecl(n) => self.visit_function(&n.function), + SymbolNodeRef::Param(_) => {} SymbolNodeRef::TsEnum(n) => { self.visit_ts_enum_decl(n); } diff --git a/tests/helpers/mod.rs b/tests/helpers/mod.rs index af1fa7889..b250619c9 100644 --- a/tests/helpers/mod.rs +++ b/tests/helpers/mod.rs @@ -300,39 +300,41 @@ impl TestBuilder { } } - if let Some(parent_id) = symbol.parent_id() { - let parent_symbol = module.symbol(parent_id).unwrap(); - let has_child = - parent_symbol.child_ids().any(|id| id == symbol.symbol_id()); - let has_member = parent_symbol - .members() - .iter() - .any(|id| *id == symbol.symbol_id()); - let is_definition_decl = - symbol.decls().iter().all(|d| d.kind.is_definition()); - if is_definition_decl { - // ensure it's possible to go from a parent to its child - if !has_child && !has_member { + if !symbol.is_param() { + if let Some(parent_id) = symbol.parent_id() { + let parent_symbol = module.symbol(parent_id).unwrap(); + let has_child = + parent_symbol.child_ids().any(|id| id == symbol.symbol_id()); + let has_member = parent_symbol + .members() + .iter() + .any(|id| *id == symbol.symbol_id()); + let is_definition_decl = + symbol.decls().iter().all(|d| d.kind.is_definition()); + if is_definition_decl { + // ensure it's possible to go from a parent to its child + if !has_child && !has_member { + results.push(format!( + "Parent {:#?} does not have child {:#?}", + parent_symbol.symbol_id(), + symbol.symbol_id() + )); + } + } else if has_child || has_member { results.push(format!( - "Parent {:#?} does not have child {:#?}", + "Parent {:#?} should not have the child or member {:#?}", parent_symbol.symbol_id(), symbol.symbol_id() )); } - } else if has_child || has_member { - results.push(format!( - "Parent {:#?} should not have the child or member {:#?}", - parent_symbol.symbol_id(), - symbol.symbol_id() - )); - } - if has_child && has_member { - results.push(format!( - "Parent {:?} should not have both a child and a member {:?}", - parent_symbol.symbol_id(), - symbol.symbol_id() - )); + if has_child && has_member { + results.push(format!( + "Parent {:?} should not have both a child and a member {:?}", + parent_symbol.symbol_id(), + symbol.symbol_id() + )); + } } } diff --git a/tests/specs/symbols/Classes01.txt b/tests/specs/symbols/Classes01.txt index 770d7275e..f808ce5a8 100644 --- a/tests/specs/symbols/Classes01.txt +++ b/tests/specs/symbols/Classes01.txt @@ -59,6 +59,14 @@ class ClassWithIndexSignatures { [value: string]: number; } +class ClassWithTypeParams { + prop: T; + + method(a: T): X { + return null as any; + } +} + # output file:///mod.ts: EsModuleInfo { module_id: ModuleId( @@ -71,74 +79,114 @@ file:///mod.ts: EsModuleInfo { "A", #2, ): 1, + ( + "c", + #3, + ): 4, ( "C", #2, - ): 4, + ): 5, ( "BBase", #2, - ): 5, + ): 6, ( "IBase", #2, - ): 6, + ): 7, ( "B", #2, - ): 7, + ): 8, + ( + "prop", + #4, + ): 10, + ( + "other", + #6, + ): 14, + ( + "private", + #7, + ): 16, + ( + "param", + #8, + ): 18, + ( + "param", + #9, + ): 19, ( "PropValue", #2, - ): 14, + ): 20, ( "ReturnValue", #2, - ): 15, + ): 21, ( "Param", #2, - ): 16, + ): 22, ( "PrivateParam", #2, - ): 17, + ): 23, ( "PrivateReturn", #2, - ): 18, + ): 24, ( "PrivateProp", #2, - ): 19, + ): 25, ( "CtorProp", #2, - ): 20, + ): 26, ( "OverloadParam", #2, - ): 21, + ): 27, ( "OverloadReturn", #2, - ): 22, + ): 28, ( "PrivateImplementationParam", #2, - ): 23, + ): 29, ( "PrivateImplementationReturn", #2, - ): 24, + ): 30, ( "ClassWithStatic", #2, - ): 25, + ): 31, ( "ClassWithIndexSignatures", #2, - ): 27, + ): 33, + ( + "ClassWithTypeParams", + #2, + ): 36, + ( + "T", + #11, + ): 37, + ( + "X", + #12, + ): 40, + ( + "a", + #12, + ): 41, }, symbols: { 0: Symbol { @@ -151,7 +199,7 @@ file:///mod.ts: EsModuleInfo { SymbolDecl { kind: Definition( SymbolNode( - "export class A {\n b: B;\n constructor(c: C) {\n }\n}\n\ninterface C {}\n\nclass BBase {\n\n}\n\ninterface IBase {\n}\n\nclass B extends BBase implements IBase {\n private constructor(prop: CtorProp) {}\n prop: PropValue;\n method(): ReturnValue {\n }\n\n method2(other: Param): void {\n }\n\n private asdf(private: PrivateParam): PrivateReturn {\n }\n\n private prop: PrivateProp;\n\n methodOverload(param: OverloadParam): OverloadReturn;\n methodOverload(param: PrivateImplementationParam): PrivateImplementationReturn {\n }\n\n #private: PrivateProp;\n #privateMethod(private: PrivateParam): PrivateReturn {\n }\n}\n\nclass PropValue {}\nclass ReturnValue {}\nclass Param {}\nclass PrivateParam {}\nclass PrivateReturn {}\nclass PrivateProp {}\nclass CtorProp {}\nclass OverloadParam {}\nclass OverloadReturn {}\nclass PrivateImplementationParam {}\nclass PrivateImplementationReturn {}\n\nclass ClassWithStatic {\n static prop: string;\n}\n\nclass ClassWithIndexSignatures {\n static [value: string]: number;\n [value: number]: string;\n [value: string]: number;\n}", + "export class A {\n b: B;\n constructor(c: C) {\n }\n}\n\ninterface C {}\n\nclass BBase {\n\n}\n\ninterface IBase {\n}\n\nclass B extends BBase implements IBase {\n private constructor(prop: CtorProp) {}\n prop: PropValue;\n method(): ReturnValue {\n }\n\n method2(other: Param): void {\n }\n\n private asdf(private: PrivateParam): PrivateReturn {\n }\n\n private prop: PrivateProp;\n\n methodOverload(param: OverloadParam): OverloadReturn;\n methodOverload(param: PrivateImplementationParam): PrivateImplementationReturn {\n }\n\n #private: PrivateProp;\n #privateMethod(private: PrivateParam): PrivateReturn {\n }\n}\n\nclass PropValue {}\nclass ReturnValue {}\nclass Param {}\nclass PrivateParam {}\nclass PrivateReturn {}\nclass PrivateProp {}\nclass CtorProp {}\nclass OverloadParam {}\nclass OverloadReturn {}\nclass PrivateImplementationParam {}\nclass PrivateImplementationReturn {}\n\nclass ClassWithStatic {\n static prop: string;\n}\n\nclass ClassWithIndexSignatures {\n static [value: string]: number;\n [value: number]: string;\n [value: string]: number;\n}\n\nclass ClassWithTypeParams {\n prop: T;\n\n method(a: T): X {\n return null as any;\n }\n}", ), ), range: SourceRange { @@ -159,7 +207,7 @@ file:///mod.ts: EsModuleInfo { 0, ), end: SourcePos( - 1033, + 1130, ), }, flags: 0, @@ -167,23 +215,24 @@ file:///mod.ts: EsModuleInfo { ], child_ids: { 1, - 4, 5, 6, 7, - 14, - 15, - 16, - 17, - 18, - 19, + 8, 20, 21, 22, 23, 24, 25, + 26, 27, + 28, + 29, + 30, + 31, + 33, + 36, }, exports: { "A": 1, @@ -291,6 +340,36 @@ file:///mod.ts: EsModuleInfo { 0, ), symbol_id: 4, + parent_id: Some( + 3, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "c", + ), + ), + range: SourceRange { + start: SourcePos( + 39, + ), + end: SourcePos( + 40, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 5: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 5, parent_id: Some( 0, ), @@ -316,11 +395,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 5: Symbol { + 6: Symbol { module_id: ModuleId( 0, ), - symbol_id: 5, + symbol_id: 6, parent_id: Some( 0, ), @@ -346,11 +425,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 6: Symbol { + 7: Symbol { module_id: ModuleId( 0, ), - symbol_id: 6, + symbol_id: 7, parent_id: Some( 0, ), @@ -376,11 +455,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 7: Symbol { + 8: Symbol { module_id: ModuleId( 0, ), - symbol_id: 7, + symbol_id: 8, parent_id: Some( 0, ), @@ -403,26 +482,26 @@ file:///mod.ts: EsModuleInfo { }, ], child_ids: { - 8, + 9, }, exports: { - "%%dg_ctor%%": 8, + "%%dg_ctor%%": 9, }, members: { - 9, - 10, 11, 12, 13, + 15, + 17, }, }, - 8: Symbol { + 9: Symbol { module_id: ModuleId( 0, ), - symbol_id: 8, + symbol_id: 9, parent_id: Some( - 7, + 8, ), decls: [ SymbolDecl { @@ -446,13 +525,43 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 9: Symbol { + 10: Symbol { module_id: ModuleId( 0, ), - symbol_id: 9, + symbol_id: 10, parent_id: Some( - 7, + 9, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "prop", + ), + ), + range: SourceRange { + start: SourcePos( + 172, + ), + end: SourcePos( + 176, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 11: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 11, + parent_id: Some( + 8, ), decls: [ SymbolDecl { @@ -492,13 +601,13 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 10: Symbol { + 12: Symbol { module_id: ModuleId( 0, ), - symbol_id: 10, + symbol_id: 12, parent_id: Some( - 7, + 8, ), decls: [ SymbolDecl { @@ -522,13 +631,13 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 11: Symbol { + 13: Symbol { module_id: ModuleId( 0, ), - symbol_id: 11, + symbol_id: 13, parent_id: Some( - 7, + 8, ), decls: [ SymbolDecl { @@ -552,13 +661,43 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 12: Symbol { + 14: Symbol { module_id: ModuleId( 0, ), - symbol_id: 12, + symbol_id: 14, parent_id: Some( - 7, + 13, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "other", + ), + ), + range: SourceRange { + start: SourcePos( + 251, + ), + end: SourcePos( + 256, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 15: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 15, + parent_id: Some( + 8, ), decls: [ SymbolDecl { @@ -582,13 +721,43 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 13: Symbol { + 16: Symbol { module_id: ModuleId( 0, ), - symbol_id: 13, + symbol_id: 16, parent_id: Some( - 7, + 15, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "private", + ), + ), + range: SourceRange { + start: SourcePos( + 293, + ), + end: SourcePos( + 300, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 17: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 17, + parent_id: Some( + 8, ), decls: [ SymbolDecl { @@ -628,11 +797,71 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 14: Symbol { + 18: Symbol { module_id: ModuleId( 0, ), - symbol_id: 14, + symbol_id: 18, + parent_id: Some( + 17, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "param", + ), + ), + range: SourceRange { + start: SourcePos( + 385, + ), + end: SourcePos( + 390, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 19: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 19, + parent_id: Some( + 17, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "param", + ), + ), + range: SourceRange { + start: SourcePos( + 441, + ), + end: SourcePos( + 446, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 20: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 20, parent_id: Some( 0, ), @@ -658,11 +887,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 15: Symbol { + 21: Symbol { module_id: ModuleId( 0, ), - symbol_id: 15, + symbol_id: 21, parent_id: Some( 0, ), @@ -688,11 +917,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 16: Symbol { + 22: Symbol { module_id: ModuleId( 0, ), - symbol_id: 16, + symbol_id: 22, parent_id: Some( 0, ), @@ -718,11 +947,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 17: Symbol { + 23: Symbol { module_id: ModuleId( 0, ), - symbol_id: 17, + symbol_id: 23, parent_id: Some( 0, ), @@ -748,11 +977,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 18: Symbol { + 24: Symbol { module_id: ModuleId( 0, ), - symbol_id: 18, + symbol_id: 24, parent_id: Some( 0, ), @@ -778,11 +1007,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 19: Symbol { + 25: Symbol { module_id: ModuleId( 0, ), - symbol_id: 19, + symbol_id: 25, parent_id: Some( 0, ), @@ -808,11 +1037,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 20: Symbol { + 26: Symbol { module_id: ModuleId( 0, ), - symbol_id: 20, + symbol_id: 26, parent_id: Some( 0, ), @@ -838,11 +1067,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 21: Symbol { + 27: Symbol { module_id: ModuleId( 0, ), - symbol_id: 21, + symbol_id: 27, parent_id: Some( 0, ), @@ -868,11 +1097,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 22: Symbol { + 28: Symbol { module_id: ModuleId( 0, ), - symbol_id: 22, + symbol_id: 28, parent_id: Some( 0, ), @@ -898,11 +1127,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 23: Symbol { + 29: Symbol { module_id: ModuleId( 0, ), - symbol_id: 23, + symbol_id: 29, parent_id: Some( 0, ), @@ -928,11 +1157,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 24: Symbol { + 30: Symbol { module_id: ModuleId( 0, ), - symbol_id: 24, + symbol_id: 30, parent_id: Some( 0, ), @@ -958,11 +1187,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 25: Symbol { + 31: Symbol { module_id: ModuleId( 0, ), - symbol_id: 25, + symbol_id: 31, parent_id: Some( 0, ), @@ -985,20 +1214,20 @@ file:///mod.ts: EsModuleInfo { }, ], child_ids: { - 26, + 32, }, exports: { - "prop": 26, + "prop": 32, }, members: {}, }, - 26: Symbol { + 32: Symbol { module_id: ModuleId( 0, ), - symbol_id: 26, + symbol_id: 32, parent_id: Some( - 25, + 31, ), decls: [ SymbolDecl { @@ -1022,11 +1251,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 27: Symbol { + 33: Symbol { module_id: ModuleId( 0, ), - symbol_id: 27, + symbol_id: 33, parent_id: Some( 0, ), @@ -1049,22 +1278,22 @@ file:///mod.ts: EsModuleInfo { }, ], child_ids: { - 28, + 34, }, exports: { - "%%dg_index%%": 28, + "%%dg_index%%": 34, }, members: { - 29, + 35, }, }, - 28: Symbol { + 34: Symbol { module_id: ModuleId( 0, ), - symbol_id: 28, + symbol_id: 34, parent_id: Some( - 27, + 33, ), decls: [ SymbolDecl { @@ -1088,13 +1317,13 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 29: Symbol { + 35: Symbol { module_id: ModuleId( 0, ), - symbol_id: 29, + symbol_id: 35, parent_id: Some( - 27, + 33, ), decls: [ SymbolDecl { @@ -1134,33 +1363,220 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, + 36: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 36, + parent_id: Some( + 0, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "class ClassWithTypeParams {\n prop: T;\n\n method(a: T): X {\n return null as any;\n }\n}", + ), + ), + range: SourceRange { + start: SourcePos( + 1035, + ), + end: SourcePos( + 1130, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: { + 38, + 39, + }, + }, + 37: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 37, + parent_id: Some( + 36, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "T", + ), + ), + range: SourceRange { + start: SourcePos( + 1061, + ), + end: SourcePos( + 1062, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 38: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 38, + parent_id: Some( + 36, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "prop: T;", + ), + ), + range: SourceRange { + start: SourcePos( + 1068, + ), + end: SourcePos( + 1076, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 39: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 39, + parent_id: Some( + 36, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "method(a: T): X {\n return null as any;\n }", + ), + ), + range: SourceRange { + start: SourcePos( + 1080, + ), + end: SourcePos( + 1128, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 40: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 40, + parent_id: Some( + 39, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "X", + ), + ), + range: SourceRange { + start: SourcePos( + 1087, + ), + end: SourcePos( + 1088, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 41: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 41, + parent_id: Some( + 39, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "a", + ), + ), + range: SourceRange { + start: SourcePos( + 1090, + ), + end: SourcePos( + 1091, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, }, } == symbol deps (types and exprs) == 2:19..24 [Id(("B", #2))] 3:27..50 [Id(("C", #2))] -7:109..599 [Id(("BBase", #2)), Id(("IBase", #2))] -8:152..190 [Id(("CtorProp", #2))] -9:193..209 [Id(("PropValue", #2))] -9:340..366 [Id(("PrivateProp", #2))] -10:212..239 [Id(("ReturnValue", #2))] -11:243..276 [Id(("Param", #2))] -12:280..336 [Id(("PrivateParam", #2)), Id(("PrivateReturn", #2))] -13:370..423 [Id(("OverloadParam", #2)), Id(("OverloadReturn", #2))] -13:426..510 [Id(("PrivateImplementationParam", #2)), Id(("PrivateImplementationReturn", #2))] +8:109..599 [Id(("BBase", #2)), Id(("IBase", #2))] +9:152..190 [Id(("CtorProp", #2))] +11:193..209 [Id(("PropValue", #2))] +11:340..366 [Id(("PrivateProp", #2))] +12:212..239 [Id(("ReturnValue", #2))] +13:243..276 [Id(("Param", #2))] +15:280..336 [Id(("PrivateParam", #2)), Id(("PrivateReturn", #2))] +17:370..423 [Id(("OverloadParam", #2)), Id(("OverloadReturn", #2))] +17:426..510 [Id(("PrivateImplementationParam", #2)), Id(("PrivateImplementationReturn", #2))] +38:1068..1076 [Id(("T", #11))] +39:1080..1128 [Id(("T", #11)), Id(("X", #12))] == symbol deps (types only) == 2:19..24 [Id(("B", #2))] 3:27..50 [Id(("C", #2))] -7:109..599 [Id(("BBase", #2)), Id(("IBase", #2))] -8:152..190 [Id(("CtorProp", #2))] -9:193..209 [Id(("PropValue", #2))] -9:340..366 [Id(("PrivateProp", #2))] -10:212..239 [Id(("ReturnValue", #2))] -11:243..276 [Id(("Param", #2))] -12:280..336 [Id(("PrivateParam", #2)), Id(("PrivateReturn", #2))] -13:370..423 [Id(("OverloadParam", #2)), Id(("OverloadReturn", #2))] -13:426..510 [Id(("PrivateImplementationParam", #2)), Id(("PrivateImplementationReturn", #2))] +8:109..599 [Id(("BBase", #2)), Id(("IBase", #2))] +9:152..190 [Id(("CtorProp", #2))] +11:193..209 [Id(("PropValue", #2))] +11:340..366 [Id(("PrivateProp", #2))] +12:212..239 [Id(("ReturnValue", #2))] +13:243..276 [Id(("Param", #2))] +15:280..336 [Id(("PrivateParam", #2)), Id(("PrivateReturn", #2))] +17:370..423 [Id(("OverloadParam", #2)), Id(("OverloadReturn", #2))] +17:426..510 [Id(("PrivateImplementationParam", #2)), Id(("PrivateImplementationReturn", #2))] +38:1068..1076 [Id(("T", #11))] +39:1080..1128 [Id(("T", #11)), Id(("X", #12))] == export definitions == [A]: file:///mod.ts:0..52 diff --git a/tests/specs/symbols/Functions01.txt b/tests/specs/symbols/Functions01.txt index 5815bf0bf..7e58f1baf 100644 --- a/tests/specs/symbols/Functions01.txt +++ b/tests/specs/symbols/Functions01.txt @@ -33,50 +33,74 @@ file:///mod.ts: EsModuleInfo { "test", #2, ): 1, + ( + "T", + #3, + ): 2, + ( + "param", + #3, + ): 3, ( "TypeParam", #2, - ): 2, + ): 4, ( "Param", #2, - ): 3, + ): 5, ( "Return", #2, - ): 4, + ): 6, ( "Default", #2, - ): 5, + ): 7, ( "overloaded", #2, - ): 6, + ): 8, + ( + "T", + #4, + ): 9, + ( + "param", + #4, + ): 10, + ( + "T", + #6, + ): 11, + ( + "param", + #6, + ): 12, ( "OverloadTypeParam", #2, - ): 7, + ): 13, ( "OverloadParam", #2, - ): 8, + ): 14, ( "OverloadReturn", #2, - ): 9, + ): 15, ( "PrivateTypeParam", #2, - ): 10, + ): 16, ( "PrivateParam", #2, - ): 11, + ): 17, ( "PrivateReturn", #2, - ): 12, + ): 18, }, symbols: { 0: Symbol { @@ -105,21 +129,21 @@ file:///mod.ts: EsModuleInfo { ], child_ids: { 1, - 2, - 3, 4, 5, 6, 7, 8, - 9, - 10, - 11, - 12, + 13, + 14, + 15, + 16, + 17, + 18, }, exports: { "test": 1, - "overloaded": 6, + "overloaded": 8, }, members: {}, }, @@ -158,6 +182,66 @@ file:///mod.ts: EsModuleInfo { 0, ), symbol_id: 2, + parent_id: Some( + 1, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "T", + ), + ), + range: SourceRange { + start: SourcePos( + 21, + ), + end: SourcePos( + 22, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 3: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 3, + parent_id: Some( + 1, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "param", + ), + ), + range: SourceRange { + start: SourcePos( + 52, + ), + end: SourcePos( + 57, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 4: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 4, parent_id: Some( 0, ), @@ -183,11 +267,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 3: Symbol { + 5: Symbol { module_id: ModuleId( 0, ), - symbol_id: 3, + symbol_id: 5, parent_id: Some( 0, ), @@ -213,11 +297,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 4: Symbol { + 6: Symbol { module_id: ModuleId( 0, ), - symbol_id: 4, + symbol_id: 6, parent_id: Some( 0, ), @@ -243,11 +327,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 5: Symbol { + 7: Symbol { module_id: ModuleId( 0, ), - symbol_id: 5, + symbol_id: 7, parent_id: Some( 0, ), @@ -273,11 +357,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 6: Symbol { + 8: Symbol { module_id: ModuleId( 0, ), - symbol_id: 6, + symbol_id: 8, parent_id: Some( 0, ), @@ -335,11 +419,131 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 7: Symbol { + 9: Symbol { module_id: ModuleId( 0, ), - symbol_id: 7, + symbol_id: 9, + parent_id: Some( + 8, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "T", + ), + ), + range: SourceRange { + start: SourcePos( + 228, + ), + end: SourcePos( + 229, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 10: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 10, + parent_id: Some( + 8, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "param", + ), + ), + range: SourceRange { + start: SourcePos( + 257, + ), + end: SourcePos( + 262, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 11: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 11, + parent_id: Some( + 8, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "T", + ), + ), + range: SourceRange { + start: SourcePos( + 361, + ), + end: SourcePos( + 362, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 12: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 12, + parent_id: Some( + 8, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "param", + ), + ), + range: SourceRange { + start: SourcePos( + 389, + ), + end: SourcePos( + 394, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 13: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 13, parent_id: Some( 0, ), @@ -365,11 +569,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 8: Symbol { + 14: Symbol { module_id: ModuleId( 0, ), - symbol_id: 8, + symbol_id: 14, parent_id: Some( 0, ), @@ -395,11 +599,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 9: Symbol { + 15: Symbol { module_id: ModuleId( 0, ), - symbol_id: 9, + symbol_id: 15, parent_id: Some( 0, ), @@ -425,11 +629,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 10: Symbol { + 16: Symbol { module_id: ModuleId( 0, ), - symbol_id: 10, + symbol_id: 16, parent_id: Some( 0, ), @@ -455,11 +659,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 11: Symbol { + 17: Symbol { module_id: ModuleId( 0, ), - symbol_id: 11, + symbol_id: 17, parent_id: Some( 0, ), @@ -485,11 +689,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 12: Symbol { + 18: Symbol { module_id: ModuleId( 0, ), - symbol_id: 12, + symbol_id: 18, parent_id: Some( 0, ), @@ -519,13 +723,13 @@ file:///mod.ts: EsModuleInfo { } == symbol deps (types and exprs) == 1:0..77 [Id(("TypeParam", #2)), Id(("Default", #2)), Id(("Param", #2)), Id(("Return", #2))] -6:201..295 [Id(("OverloadTypeParam", #2)), Id(("OverloadParam", #2)), Id(("OverloadReturn", #2))] -6:334..428 [Id(("PrivateTypeParam", #2)), Id(("PrivateParam", #2)), Id(("PrivateReturn", #2))] +8:201..295 [Id(("OverloadTypeParam", #2)), Id(("OverloadParam", #2)), Id(("OverloadReturn", #2))] +8:334..428 [Id(("PrivateTypeParam", #2)), Id(("PrivateParam", #2)), Id(("PrivateReturn", #2))] == symbol deps (types only) == 1:0..77 [Id(("TypeParam", #2)), Id(("Default", #2)), Id(("Param", #2)), Id(("Return", #2))] -6:201..295 [Id(("OverloadTypeParam", #2)), Id(("OverloadParam", #2)), Id(("OverloadReturn", #2))] -6:334..428 [Id(("PrivateTypeParam", #2)), Id(("PrivateParam", #2)), Id(("PrivateReturn", #2))] +8:201..295 [Id(("OverloadTypeParam", #2)), Id(("OverloadParam", #2)), Id(("OverloadReturn", #2))] +8:334..428 [Id(("PrivateTypeParam", #2)), Id(("PrivateParam", #2)), Id(("PrivateReturn", #2))] == export definitions == [test]: file:///mod.ts:0..77 diff --git a/tests/specs/symbols/class_private_ctor_param_props.txt b/tests/specs/symbols/class_private_ctor_param_props.txt index 482502cb8..fee42f42b 100644 --- a/tests/specs/symbols/class_private_ctor_param_props.txt +++ b/tests/specs/symbols/class_private_ctor_param_props.txt @@ -23,14 +23,18 @@ file:///mod.ts: EsModuleInfo { "Class", #2, ): 1, + ( + "regularParam", + #3, + ): 5, ( "PublicClass", #2, - ): 5, + ): 6, ( "PrivateClass", #2, - ): 6, + ): 7, }, symbols: { 0: Symbol { @@ -59,8 +63,8 @@ file:///mod.ts: EsModuleInfo { ], child_ids: { 1, - 5, 6, + 7, }, exports: { "Class": 1, @@ -199,6 +203,36 @@ file:///mod.ts: EsModuleInfo { 0, ), symbol_id: 5, + parent_id: Some( + 2, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "regularParam", + ), + ), + range: SourceRange { + start: SourcePos( + 119, + ), + end: SourcePos( + 131, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 6: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 6, parent_id: Some( 0, ), @@ -224,11 +258,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 6: Symbol { + 7: Symbol { module_id: ModuleId( 0, ), - symbol_id: 6, + symbol_id: 7, parent_id: Some( 0, ), diff --git a/tests/specs/symbols/declaration_merging01.txt b/tests/specs/symbols/declaration_merging01.txt index 24283e0d1..54406b522 100644 --- a/tests/specs/symbols/declaration_merging01.txt +++ b/tests/specs/symbols/declaration_merging01.txt @@ -48,14 +48,18 @@ file:///mod.ts: EsModuleInfo { "mixColor", #4, ): 4, + ( + "colorName", + #5, + ): 5, ( "Test", #2, - ): 5, + ): 6, ( "other", #7, - ): 6, + ): 7, }, symbols: { 0: Symbol { @@ -85,12 +89,12 @@ file:///mod.ts: EsModuleInfo { child_ids: { 1, 3, - 5, + 6, }, exports: { - "Album": 7, - "Color": 8, - "Test": 9, + "Album": 8, + "Color": 9, + "Test": 10, }, members: {}, }, @@ -259,6 +263,36 @@ file:///mod.ts: EsModuleInfo { 0, ), symbol_id: 5, + parent_id: Some( + 4, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "colorName", + ), + ), + range: SourceRange { + start: SourcePos( + 145, + ), + end: SourcePos( + 154, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 6: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 6, parent_id: Some( 0, ), @@ -297,20 +331,20 @@ file:///mod.ts: EsModuleInfo { }, ], child_ids: { - 6, + 7, }, exports: { - "other": 6, + "other": 7, }, members: {}, }, - 6: Symbol { + 7: Symbol { module_id: ModuleId( 0, ), - symbol_id: 6, + symbol_id: 7, parent_id: Some( - 5, + 6, ), decls: [ SymbolDecl { @@ -334,11 +368,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 7: Symbol { + 8: Symbol { module_id: ModuleId( 0, ), - symbol_id: 7, + symbol_id: 8, parent_id: Some( 0, ), @@ -365,11 +399,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 8: Symbol { + 9: Symbol { module_id: ModuleId( 0, ), - symbol_id: 8, + symbol_id: 9, parent_id: Some( 0, ), @@ -396,11 +430,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 9: Symbol { + 10: Symbol { module_id: ModuleId( 0, ), - symbol_id: 9, + symbol_id: 10, parent_id: Some( 0, ), diff --git a/tests/specs/symbols/function_overloads01.txt b/tests/specs/symbols/function_overloads01.txt index 0b616fddd..91118481b 100644 --- a/tests/specs/symbols/function_overloads01.txt +++ b/tests/specs/symbols/function_overloads01.txt @@ -26,18 +26,42 @@ file:///mod.ts: EsModuleInfo { "test", #2, ): 1, + ( + "value", + #3, + ): 2, + ( + "value", + #4, + ): 3, + ( + "value", + #5, + ): 4, ( "Inner", #2, - ): 2, + ): 5, ( "inner", #6, - ): 3, + ): 6, + ( + "value", + #7, + ): 7, + ( + "value", + #8, + ): 8, + ( + "value", + #9, + ): 9, ( "InnerInner", #2, - ): 4, + ): 10, }, symbols: { 0: Symbol { @@ -66,11 +90,11 @@ file:///mod.ts: EsModuleInfo { ], child_ids: { 1, - 2, + 5, }, exports: { "test": 1, - "InnerInner": 5, + "InnerInner": 11, }, members: {}, }, @@ -141,6 +165,96 @@ file:///mod.ts: EsModuleInfo { 0, ), symbol_id: 2, + parent_id: Some( + 1, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "value", + ), + ), + range: SourceRange { + start: SourcePos( + 21, + ), + end: SourcePos( + 26, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 3: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 3, + parent_id: Some( + 1, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "value", + ), + ), + range: SourceRange { + start: SourcePos( + 58, + ), + end: SourcePos( + 63, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 4: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 4, + parent_id: Some( + 1, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "value", + ), + ), + range: SourceRange { + start: SourcePos( + 95, + ), + end: SourcePos( + 100, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 5: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 5, parent_id: Some( 0, ), @@ -163,20 +277,20 @@ file:///mod.ts: EsModuleInfo { }, ], child_ids: { - 3, + 6, }, exports: { - "inner": 3, + "inner": 6, }, members: {}, }, - 3: Symbol { + 6: Symbol { module_id: ModuleId( 0, ), - symbol_id: 3, + symbol_id: 6, parent_id: Some( - 2, + 5, ), decls: [ SymbolDecl { @@ -232,11 +346,101 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 4: Symbol { + 7: Symbol { module_id: ModuleId( 0, ), - symbol_id: 4, + symbol_id: 7, + parent_id: Some( + 6, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "value", + ), + ), + range: SourceRange { + start: SourcePos( + 166, + ), + end: SourcePos( + 171, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 8: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 8, + parent_id: Some( + 6, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "value", + ), + ), + range: SourceRange { + start: SourcePos( + 206, + ), + end: SourcePos( + 211, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 9: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 9, + parent_id: Some( + 6, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "value", + ), + ), + range: SourceRange { + start: SourcePos( + 246, + ), + end: SourcePos( + 251, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, + 10: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 10, parent_id: Some( 0, ), @@ -266,11 +470,11 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, - 5: Symbol { + 11: Symbol { module_id: ModuleId( 0, ), - symbol_id: 5, + symbol_id: 11, parent_id: Some( 0, ), diff --git a/tests/specs/symbols/ts_namespace_export01.txt b/tests/specs/symbols/ts_namespace_export01.txt index c5109ed77..2bc65d0e0 100644 --- a/tests/specs/symbols/ts_namespace_export01.txt +++ b/tests/specs/symbols/ts_namespace_export01.txt @@ -19,6 +19,10 @@ file:///mod.ts: EsModuleInfo { "isPrime", #2, ): 1, + ( + "x", + #3, + ): 2, }, symbols: { 0: Symbol { @@ -83,6 +87,36 @@ file:///mod.ts: EsModuleInfo { exports: {}, members: {}, }, + 2: Symbol { + module_id: ModuleId( + 0, + ), + symbol_id: 2, + parent_id: Some( + 1, + ), + decls: [ + SymbolDecl { + kind: Definition( + SymbolNode( + "x", + ), + ), + range: SourceRange { + start: SourcePos( + 24, + ), + end: SourcePos( + 25, + ), + }, + flags: 0, + }, + ], + child_ids: {}, + exports: {}, + members: {}, + }, }, } == export definitions ==