@@ -6,10 +6,9 @@ use crate::transform::{apply_env_transform, Transformation};
6
6
use crate :: DeserializeEnv ;
7
7
8
8
use ast_grep_core:: language:: Language ;
9
- use ast_grep_core:: matcher:: { KindMatcher , KindMatcherError , RegexMatcher , RegexMatcherError } ;
10
- use ast_grep_core:: meta_var:: { MetaVarEnv , MetaVarMatcher , MetaVarMatchers } ;
9
+ use ast_grep_core:: meta_var:: { MetaVarEnv , MetaVarMatchers } ;
11
10
use ast_grep_core:: replacer:: Content ;
12
- use ast_grep_core:: { Doc , Matcher , Node , Pattern , PatternError , StrDoc } ;
11
+ use ast_grep_core:: { Doc , Matcher , Node , StrDoc } ;
13
12
use serde:: { Deserialize , Serialize } ;
14
13
use serde_yaml:: Error as YamlError ;
15
14
@@ -21,60 +20,18 @@ use std::borrow::Cow;
21
20
use std:: collections:: HashMap ;
22
21
use std:: ops:: Deref ;
23
22
24
- #[ derive( Serialize , Deserialize , Clone , JsonSchema ) ]
25
- #[ serde( rename_all = "camelCase" ) ]
26
- pub enum SerializableMetaVarMatcher {
27
- /// A regex to filter metavar based on its textual content.
28
- Regex ( String ) ,
29
- /// A pattern to filter matched metavar based on its AST tree shape.
30
- Pattern ( String ) ,
31
- /// A kind_id to filter matched metavar based on its ts-node kind
32
- Kind ( String ) ,
33
- }
34
-
35
- #[ derive( Debug , Error ) ]
36
- pub enum SerializeConstraintsError {
37
- #[ error( "Invalid Regex." ) ]
38
- RegexError ( #[ from] RegexMatcherError ) ,
39
- #[ error( "Invalid Kind." ) ]
40
- InvalidKind ( #[ from] KindMatcherError ) ,
41
- #[ error( "Invalid Pattern." ) ]
42
- PatternError ( #[ from] PatternError ) ,
43
- }
44
-
45
- pub fn try_from_serializable < L : Language > (
46
- meta_var : SerializableMetaVarMatcher ,
47
- lang : L ,
48
- ) -> Result < MetaVarMatcher < StrDoc < L > > , SerializeConstraintsError > {
49
- use SerializableMetaVarMatcher as S ;
50
- Ok ( match meta_var {
51
- S :: Regex ( s) => MetaVarMatcher :: Regex ( RegexMatcher :: try_new ( & s) ?) ,
52
- S :: Kind ( p) => MetaVarMatcher :: Kind ( KindMatcher :: try_new ( & p, lang) ?) ,
53
- S :: Pattern ( p) => MetaVarMatcher :: Pattern ( Pattern :: try_new ( & p, lang) ?) ,
54
- } )
55
- }
56
-
57
- pub fn try_deserialize_matchers < L : Language > (
58
- meta_vars : HashMap < String , SerializableMetaVarMatcher > ,
59
- lang : L ,
60
- ) -> Result < MetaVarMatchers < StrDoc < L > > , SerializeConstraintsError > {
61
- let mut map = MetaVarMatchers :: new ( ) ;
62
- for ( key, matcher) in meta_vars {
63
- map. insert ( key, try_from_serializable ( matcher, lang. clone ( ) ) ?) ;
64
- }
65
- Ok ( map)
66
- }
67
-
68
23
#[ derive( Debug , Error ) ]
69
24
pub enum RuleConfigError {
70
25
#[ error( "Fail to parse yaml as RuleConfig" ) ]
71
26
Yaml ( #[ from] YamlError ) ,
72
27
#[ error( "Rule is not configured correctly." ) ]
73
28
Rule ( #[ from] RuleSerializeError ) ,
29
+ #[ error( "Utility rule is not configured correctly." ) ]
30
+ Utils ( #[ source] RuleSerializeError ) ,
74
31
#[ error( "fix pattern is invalid." ) ]
75
32
Fixer ( #[ from] FixerError ) ,
76
33
#[ error( "constraints is not configured correctly." ) ]
77
- Constraints ( #[ from ] SerializeConstraintsError ) ,
34
+ Constraints ( #[ source ] RuleSerializeError ) ,
78
35
}
79
36
80
37
type RResult < T > = std:: result:: Result < T , RuleConfigError > ;
@@ -85,7 +42,7 @@ pub struct SerializableRuleCore {
85
42
/// A rule object to find matching AST nodes
86
43
pub rule : SerializableRule ,
87
44
/// Additional meta variables pattern to filter matching
88
- pub constraints : Option < HashMap < String , SerializableMetaVarMatcher > > ,
45
+ pub constraints : Option < HashMap < String , SerializableRule > > ,
89
46
/// Utility rules that can be used in `matches`
90
47
pub utils : Option < HashMap < String , SerializableRule > > ,
91
48
/// A dictionary for metavariable manipulation. Dict key is the new variable name.
@@ -101,7 +58,9 @@ pub struct SerializableRuleCore {
101
58
impl SerializableRuleCore {
102
59
fn get_deserialize_env < L : Language > ( & self , env : DeserializeEnv < L > ) -> RResult < DeserializeEnv < L > > {
103
60
if let Some ( utils) = & self . utils {
104
- let env = env. register_local_utils ( utils) ?;
61
+ let env = env
62
+ . register_local_utils ( utils)
63
+ . map_err ( RuleConfigError :: Rule ) ?;
105
64
Ok ( env)
106
65
} else {
107
66
Ok ( env)
@@ -111,12 +70,15 @@ impl SerializableRuleCore {
111
70
fn get_meta_var_matchers < L : Language > (
112
71
& self ,
113
72
env : & DeserializeEnv < L > ,
114
- ) -> RResult < MetaVarMatchers < StrDoc < L > > > {
115
- Ok ( if let Some ( constraints) = self . constraints . clone ( ) {
116
- try_deserialize_matchers ( constraints, env. lang . clone ( ) ) ?
117
- } else {
118
- MetaVarMatchers :: default ( )
119
- } )
73
+ ) -> RResult < HashMap < String , Rule < L > > > {
74
+ let mut matchers = HashMap :: new ( ) ;
75
+ let Some ( constraints) = & self . constraints else {
76
+ return Ok ( matchers) ;
77
+ } ;
78
+ for ( key, ser) in constraints {
79
+ matchers. insert ( key. to_string ( ) , env. deserialize_rule ( ser. clone ( ) ) ?) ;
80
+ }
81
+ Ok ( matchers)
120
82
}
121
83
122
84
fn get_fixer < C : Content , L : Language > (
@@ -157,7 +119,7 @@ impl SerializableRuleCore {
157
119
158
120
pub struct RuleCore < L : Language > {
159
121
rule : Rule < L > ,
160
- matchers : MetaVarMatchers < StrDoc < L > > ,
122
+ matchers : HashMap < String , Rule < L > > ,
161
123
kinds : Option < BitSet > ,
162
124
transform : Option < HashMap < String , Transformation > > ,
163
125
pub fixer : Option < Fixer < String , L > > ,
@@ -177,7 +139,7 @@ impl<L: Language> RuleCore<L> {
177
139
}
178
140
179
141
#[ inline]
180
- pub fn with_matchers ( self , matchers : MetaVarMatchers < StrDoc < L > > ) -> Self {
142
+ pub fn with_matchers ( self , matchers : HashMap < String , Rule < L > > ) -> Self {
181
143
Self { matchers, ..self }
182
144
}
183
145
@@ -228,7 +190,7 @@ impl<L: Language> Default for RuleCore<L> {
228
190
fn default ( ) -> Self {
229
191
Self {
230
192
rule : Rule :: default ( ) ,
231
- matchers : MetaVarMatchers :: default ( ) ,
193
+ matchers : HashMap :: default ( ) ,
232
194
kinds : None ,
233
195
transform : None ,
234
196
fixer : None ,
@@ -249,8 +211,11 @@ impl<L: Language> Matcher<L> for RuleCore<L> {
249
211
}
250
212
}
251
213
let ret = self . rule . match_node_with_env ( node, env) ?;
252
- if !env. match_constraints ( & self . matchers ) {
253
- return None ;
214
+ for ( key, matcher) in & self . matchers {
215
+ let Some ( node) = env. get_match ( key) else {
216
+ continue ;
217
+ } ;
218
+ _ = matcher. match_node_with_env ( node. clone ( ) , env) ?;
254
219
}
255
220
if let Some ( trans) = & self . transform {
256
221
let lang = ret. lang ( ) ;
@@ -282,71 +247,71 @@ mod test {
282
247
283
248
#[ test]
284
249
fn test_rule_with_constraints ( ) {
285
- let mut matchers = MetaVarMatchers :: new ( ) ;
286
- matchers. insert (
287
- "A" . to_string ( ) ,
288
- MetaVarMatcher :: Regex ( RegexMatcher :: try_new ( "a" ) . unwrap ( ) ) ,
289
- ) ;
290
- let rule =
291
- RuleCore :: new ( Rule :: Pattern ( Pattern :: new ( "$A" , TypeScript :: Tsx ) ) ) . with_matchers ( matchers) ;
292
- let grep = TypeScript :: Tsx . ast_grep ( "a" ) ;
293
- assert ! ( grep. root( ) . find( & rule) . is_some( ) ) ;
294
- let grep = TypeScript :: Tsx . ast_grep ( "bbb" ) ;
295
- assert ! ( grep. root( ) . find( & rule) . is_none( ) ) ;
250
+ // let mut matchers = MetaVarMatchers::new();
251
+ // matchers.insert(
252
+ // "A".to_string(),
253
+ // MetaVarMatcher::Regex(RegexMatcher::try_new("a").unwrap()),
254
+ // );
255
+ // let rule =
256
+ // RuleCore::new(Rule::Pattern(Pattern::new("$A", TypeScript::Tsx))).with_matchers(matchers);
257
+ // let grep = TypeScript::Tsx.ast_grep("a");
258
+ // assert!(grep.root().find(&rule).is_some());
259
+ // let grep = TypeScript::Tsx.ast_grep("bbb");
260
+ // assert!(grep.root().find(&rule).is_none());
296
261
}
297
262
298
263
#[ test]
299
264
fn test_serializable_regex ( ) {
300
- let yaml = from_str ( "regex: aa" ) . expect ( "must parse" ) ;
301
- let matcher = try_from_serializable ( yaml, TypeScript :: Tsx ) . expect ( "should parse" ) ;
302
- let reg = cast ! ( matcher, MetaVarMatcher :: Regex ) ;
303
- let matched = TypeScript :: Tsx . ast_grep ( "var aa = 1" ) ;
304
- assert ! ( matched. root( ) . find( & reg) . is_some( ) ) ;
305
- let non_matched = TypeScript :: Tsx . ast_grep ( "var b = 2" ) ;
306
- assert ! ( non_matched. root( ) . find( & reg) . is_none( ) ) ;
265
+ // let yaml = from_str("regex: aa").expect("must parse");
266
+ // let matcher = try_from_serializable(yaml, TypeScript::Tsx).expect("should parse");
267
+ // let reg = cast!(matcher, MetaVarMatcher::Regex);
268
+ // let matched = TypeScript::Tsx.ast_grep("var aa = 1");
269
+ // assert!(matched.root().find(®).is_some());
270
+ // let non_matched = TypeScript::Tsx.ast_grep("var b = 2");
271
+ // assert!(non_matched.root().find(®).is_none());
307
272
}
308
273
309
274
#[ test]
310
275
fn test_non_serializable_regex ( ) {
311
- let yaml = from_str ( "regex: '*'" ) . expect ( "must parse" ) ;
312
- let matcher = try_from_serializable ( yaml, TypeScript :: Tsx ) ;
313
- assert ! ( matches!(
314
- matcher,
315
- Err ( SerializeConstraintsError :: RegexError ( _) )
316
- ) ) ;
276
+ // let yaml = from_str("regex: '*'").expect("must parse");
277
+ // let matcher = try_from_serializable(yaml, TypeScript::Tsx);
278
+ // assert!(matches!(
279
+ // matcher,
280
+ // Err(SerializeConstraintsError::RegexError(_))
281
+ // ));
317
282
}
318
283
319
284
// TODO: test invalid pattern
320
285
#[ test]
321
286
fn test_serializable_pattern ( ) {
322
- let yaml = from_str ( "pattern: var a = 1" ) . expect ( "must parse" ) ;
323
- let matcher = try_from_serializable ( yaml, TypeScript :: Tsx ) . expect ( "should parse" ) ;
324
- let pattern = cast ! ( matcher, MetaVarMatcher :: Pattern ) ;
325
- let matched = TypeScript :: Tsx . ast_grep ( "var a = 1" ) ;
326
- assert ! ( matched. root( ) . find( & pattern) . is_some( ) ) ;
327
- let non_matched = TypeScript :: Tsx . ast_grep ( "var b = 2" ) ;
328
- assert ! ( non_matched. root( ) . find( & pattern) . is_none( ) ) ;
287
+ // let yaml = from_str("pattern: var a = 1").expect("must parse");
288
+ // let matcher = try_from_serializable(yaml, TypeScript::Tsx).expect("should parse");
289
+ // let pattern = cast!(matcher, MetaVarMatcher::Pattern);
290
+ // let matched = TypeScript::Tsx.ast_grep("var a = 1");
291
+ // assert!(matched.root().find(&pattern).is_some());
292
+ // let non_matched = TypeScript::Tsx.ast_grep("var b = 2");
293
+ // assert!(non_matched.root().find(&pattern).is_none());
329
294
}
330
295
331
296
#[ test]
332
297
fn test_serializable_kind ( ) {
333
- let yaml = from_str ( "kind: class_body" ) . expect ( "must parse" ) ;
334
- let matcher = try_from_serializable ( yaml, TypeScript :: Tsx ) . expect ( "should parse" ) ;
335
- let pattern = cast ! ( matcher, MetaVarMatcher :: Kind ) ;
336
- let matched = TypeScript :: Tsx . ast_grep ( "class A {}" ) ;
337
- assert ! ( matched. root( ) . find( & pattern) . is_some( ) ) ;
338
- let non_matched = TypeScript :: Tsx . ast_grep ( "function b() {}" ) ;
339
- assert ! ( non_matched. root( ) . find( & pattern) . is_none( ) ) ;
298
+ // let yaml = from_str("kind: class_body").expect("must parse");
299
+ // let matcher = try_from_serializable(yaml, TypeScript::Tsx).expect("should parse");
300
+ // let pattern = cast!(matcher, MetaVarMatcher::Kind);
301
+ // let matched = TypeScript::Tsx.ast_grep("class A {}");
302
+ // assert!(matched.root().find(&pattern).is_some());
303
+ // let non_matched = TypeScript::Tsx.ast_grep("function b() {}");
304
+ // assert!(non_matched.root().find(&pattern).is_none());
340
305
}
341
306
342
307
#[ test]
343
308
fn test_non_serializable_kind ( ) {
344
- let yaml = from_str ( "kind: IMPOSSIBLE_KIND" ) . expect ( "must parse" ) ;
345
- let matcher = try_from_serializable ( yaml, TypeScript :: Tsx ) ;
346
- let error = match matcher {
347
- Err ( SerializeConstraintsError :: InvalidKind ( s) ) => s,
348
- _ => panic ! ( "serialization should fail for invalid kind" ) ,
349
- } ;
350
- assert_eq ! ( error. to_string( ) , "Kind `IMPOSSIBLE_KIND` is invalid." ) ;
309
+ // let yaml = from_str("kind: IMPOSSIBLE_KIND").expect("must parse");
310
+ // let matcher = try_from_serializable(yaml, TypeScript::Tsx);
311
+ // let error = match matcher {
312
+ // Err(SerializeConstraintsError::InvalidKind(s)) => s,
313
+ // _ => panic!("serialization should fail for invalid kind"),
314
+ // };
315
+ // assert_eq!(error.to_string(), "Kind `IMPOSSIBLE_KIND` is invalid.");
351
316
}
352
317
}
0 commit comments