Skip to content

Commit 1e3e35d

Browse files
committed
implement method definitions
1 parent 805301c commit 1e3e35d

File tree

4 files changed

+128
-19
lines changed

4 files changed

+128
-19
lines changed

src/scope_name.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// TODO: punctuation components
2+
#![allow(dead_code)]
3+
14
use std::collections::VecDeque;
25
use std::fmt::Display;
36
use std::ops::Range;
@@ -6,10 +9,6 @@ use swc_ecma_visit::swc_ecma_ast as ast;
69

710
use crate::swc::convert_span;
811

9-
//use rslint_parser::SyntaxToken;
10-
11-
//use crate::rslint::convert_text_range;
12-
1312
#[derive(Debug)]
1413
pub(crate) struct SyntaxToken;
1514

@@ -64,7 +63,7 @@ impl NameComponent {
6463
pub fn range(&self) -> Option<Range<u32>> {
6564
match &self.inner {
6665
NameComponentInner::SourceIdentifierToken(t) => Some(convert_span(t.span)),
67-
NameComponentInner::SourcePunctuationToken(t) => {
66+
NameComponentInner::SourcePunctuationToken(_t) => {
6867
None
6968
//Some(convert_text_range(t.text_range()))
7069
}

src/swc.rs

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ impl VisitAstPath for FnVisitor {
6969
let name = infer_name_from_ctx(path);
7070

7171
self.scopes.push((convert_span(node.span), name));
72+
73+
node.visit_children_with_path(self, path);
7274
}
7375

7476
fn visit_function<'ast: 'r, 'r>(
@@ -134,11 +136,63 @@ fn infer_name_from_ctx(path: &AstNodePath) -> Option<ScopeName> {
134136
match parent {
135137
// These create a new scope. If we reached this, it means we didn’t
136138
// use any of the other parents properly.
137-
Parent::Function(..)
138-
| Parent::ArrowExpr(..)
139-
| Parent::Constructor(..)
140-
| Parent::ClassMethod(..)
141-
| Parent::PrivateMethod(..) => return None,
139+
Parent::Function(..) | Parent::ArrowExpr(..) | Parent::Constructor(..) => return None,
140+
141+
// A class which is the parent of a method for which we already
142+
// have part of the name.
143+
Parent::ClassExpr(class_expr, _) => {
144+
if let Some(ident) = &class_expr.ident {
145+
scope_name
146+
.components
147+
.push_front(NameComponent::ident(ident.clone()));
148+
}
149+
}
150+
Parent::ClassDecl(class_decl, _) => {
151+
push_sep(&mut scope_name);
152+
scope_name
153+
.components
154+
.push_front(NameComponent::ident(class_decl.ident.clone()));
155+
return Some(scope_name);
156+
}
157+
158+
// An object literal member:
159+
// `{ $name() ... }`
160+
Parent::MethodProp(method, _) => {
161+
if let Some(ident) = method.key.as_ident() {
162+
scope_name
163+
.components
164+
.push_front(NameComponent::ident(ident.clone()));
165+
}
166+
}
167+
168+
// An object literal property:
169+
// `{ $name: ... }`
170+
Parent::KeyValueProp(kv, _) => {
171+
if let Some(ident) = kv.key.as_ident() {
172+
scope_name
173+
.components
174+
.push_front(NameComponent::ident(ident.clone()));
175+
}
176+
}
177+
178+
// A class method:
179+
// `class { $name() ... }`
180+
Parent::ClassMethod(method, _) => {
181+
if let Some(ident) = method.key.as_ident() {
182+
scope_name
183+
.components
184+
.push_front(NameComponent::ident(ident.clone()));
185+
}
186+
}
187+
188+
// A private class method:
189+
// `class { #$name() ... }`
190+
Parent::PrivateMethod(method, _) => {
191+
scope_name
192+
.components
193+
.push_front(NameComponent::ident(method.key.id.clone()));
194+
scope_name.components.push_front(NameComponent::interp("#"));
195+
}
142196

143197
// A variable declaration with a name:
144198
// `var $name = ...`

tests/extract.rs

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ fn extracts_named_fn() {
1919
let scopes = extract_scope_names(src);
2020
let scopes = scope_strs(scopes);
2121

22-
assert_eq!(scopes[0], (9..81, Some("fn_decl".into())));
23-
assert_eq!(scopes[1], (49..70, Some("fn_expr".into())));
22+
let expected = [
23+
(9..81, Some("fn_decl".into())),
24+
(49..70, Some("fn_expr".into())),
25+
];
26+
assert_eq!(scopes, expected);
2427
}
2528

2629
#[test]
@@ -35,8 +38,11 @@ fn extracts_named_class() {
3538
let scopes = extract_scope_names(src);
3639
let scopes = scope_strs(scopes);
3740

38-
assert_eq!(scopes[0], (9..123, Some("new class_decl".into())));
39-
assert_eq!(scopes[1], (79..98, Some("new class_expr".into())));
41+
let expected = [
42+
(9..123, Some("new class_decl".into())),
43+
(79..98, Some("new class_expr".into())),
44+
];
45+
assert_eq!(scopes, expected);
4046
}
4147

4248
#[test]
@@ -49,9 +55,12 @@ fn infer_from_decl() {
4955
let scopes = extract_scope_names(src);
5056
let scopes = scope_strs(scopes);
5157

52-
assert_eq!(scopes[0], (23..37, Some("anon_fn".into())));
53-
assert_eq!(scopes[1], (64..72, Some("new anon_class".into())));
54-
assert_eq!(scopes[2], (96..104, Some("arrow".into())));
58+
let expected = [
59+
(23..37, Some("anon_fn".into())),
60+
(64..72, Some("new anon_class".into())),
61+
(96..104, Some("arrow".into())),
62+
];
63+
assert_eq!(scopes, expected);
5564
}
5665

5766
#[test]
@@ -63,6 +72,52 @@ fn infer_from_assign() {
6372
let scopes = extract_scope_names(src);
6473
let scopes = scope_strs(scopes);
6574

66-
assert_eq!(scopes[0], (23..37, Some("assigned_fn".into())));
67-
assert_eq!(scopes[1], (69..77, Some("new deep.assigned.klass".into())));
75+
let expected = [
76+
(23..37, Some("assigned_fn".into())),
77+
(69..77, Some("new deep.assigned.klass".into())),
78+
];
79+
assert_eq!(scopes, expected);
80+
}
81+
82+
#[test]
83+
fn extract_obj_literal() {
84+
let src = r#"
85+
const obj_literal = {
86+
named_prop: function named_prop() {},
87+
anon_prop: function () {},
88+
arrow_prop: () => {},
89+
method_prop() {},
90+
};
91+
"#;
92+
let scopes = extract_scope_names(src);
93+
let scopes = scope_strs(scopes);
94+
95+
let expected = [
96+
(55..79, Some("named_prop".into())),
97+
(104..118, Some("obj_literal.anon_prop".into())),
98+
(144..152, Some("obj_literal.arrow_prop".into())),
99+
(166..182, Some("obj_literal.method_prop".into())),
100+
];
101+
assert_eq!(scopes, expected);
102+
}
103+
104+
#[test]
105+
fn extract_method_names() {
106+
let src = r#"
107+
class class_decl {
108+
static static_method() {}
109+
class_method() {}
110+
#private_method() {}
111+
}
112+
"#;
113+
let scopes = extract_scope_names(src);
114+
let scopes = scope_strs(scopes);
115+
116+
let expected = [
117+
(9..138, Some("new class_decl".into())),
118+
(40..65, Some("class_decl.static_method".into())),
119+
(78..95, Some("class_decl.class_method".into())),
120+
(108..128, Some("class_decl.#private_method".into())),
121+
];
122+
assert_eq!(scopes, expected);
68123
}

tests/integration.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ fn resolves_scope_names() {
4646

4747
let scopes = extract_scope_names(&src);
4848
// dbg!(&scopes);
49+
4950
let scopes: Vec<_> = scopes
5051
.into_iter()
5152
.map(|s| (s.0, s.1.map(|n| n.to_string()).filter(|s| !s.is_empty())))

0 commit comments

Comments
 (0)