harper-core 2.8.0

The language checker for developers.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
use crate::linting::expr_linter::Chunk;
use crate::{
    Token,
    expr::{Expr, FirstMatchOf, FixedPhrase, SequenceExpr},
    linting::{ExprLinter, Lint, LintKind, Suggestion},
    patterns::WordSet,
};

/// Corrects the typo "thing" for "think".
pub struct ThingThink {
    expr: SequenceExpr,
}

impl Default for ThingThink {
    fn default() -> Self {
        let subject_pronouns = WordSet::new(&["I", "you", "we", "they"]);
        let indefinite_pronouns = FirstMatchOf::new([
            Box::new(WordSet::new(&[
                "anybody",
                "anyone",
                "everybody",
                "everyone",
            ])) as Box<dyn Expr>,
            // "Any one thing", "every one thing", "any body thing" cause false positives.
            Box::new(FixedPhrase::from_phrase("every body")),
        ]);
        let pronoun = FirstMatchOf::new([
            Box::new(subject_pronouns) as Box<dyn Expr>,
            Box::new(indefinite_pronouns),
        ]);

        let verb_to = SequenceExpr::word_set(&[
            "have", "had", "has", "having", "need", "needed", "needs", "needing", "want", "wanted",
            "wants", "wanting", "try", "tried", "tries", "trying",
        ])
        .t_ws()
        .t_aco("to");

        let modal = WordSet::new(&[
            "can",
            "cannot",
            "can't",
            "could",
            "couldn't",
            "may",
            "might",
            "mightn't",
            "must",
            "mustn't",
            "shall",
            "shan't",
            "should",
            "shouldn't",
            "will",
            "won't",
        ]);

        let adverb_of_frequency =
            WordSet::new(&["always", "sometimes", "often", "usually", "never"]);

        let pre_context = FirstMatchOf::new([
            Box::new(pronoun) as Box<dyn Expr>,
            Box::new(verb_to),
            Box::new(modal),
            Box::new(adverb_of_frequency),
        ]);

        let pattern = SequenceExpr::with(pre_context).t_ws().t_aco("thing");

        Self { expr: pattern }
    }
}

impl ExprLinter for ThingThink {
    type Unit = Chunk;

    fn expr(&self) -> &dyn Expr {
        &self.expr
    }

    fn match_to_lint(&self, toks: &[Token], src: &[char]) -> Option<Lint> {
        let thing_span = toks.last()?.span;

        Some(Lint {
            span: thing_span,
            lint_kind: LintKind::Typo,
            suggestions: vec![Suggestion::replace_with_match_case(
                ['t', 'h', 'i', 'n', 'k'].to_vec(),
                thing_span.get_content(src),
            )],
            message: "Did you mean `think`?".to_owned(),
            priority: 31,
        })
    }

    fn description(&self) -> &'static str {
        "Corrects the typo `thing` when it should be `think`."
    }
}

#[cfg(test)]
mod tests {
    use super::ThingThink;
    use crate::linting::pooled_linter::for_tests::create_test_pool;
    use crate::linting::tests::assert_suggestion_result;

    create_test_pool!(ThingThink, ThingThink, ThingThink::default());

    // Pronouns

    #[test]
    fn fix_you_thing() {
        assert_suggestion_result(
            "Whad do you thing about tinygo?",
            test_linter(),
            "Whad do you think about tinygo?",
        );
    }

    #[test]
    fn fix_i_thing() {
        assert_suggestion_result(
            "bcz i thing hugging face embeddings and models are very complex",
            test_linter(),
            "bcz i think hugging face embeddings and models are very complex",
        );
    }

    #[test]
    fn fix_we_thing() {
        assert_suggestion_result(
            "which information we thing to be missing",
            test_linter(),
            "which information we think to be missing",
        );
    }

    #[test]
    fn fix_they_thing() {
        assert_suggestion_result(
            "they thing something is a good idea",
            test_linter(),
            "they think something is a good idea",
        );
    }

    #[test]
    fn fix_everyone_thing() {
        assert_suggestion_result(
            "What does everyone thing here?",
            test_linter(),
            "What does everyone think here?",
        );
    }

    #[test]
    fn fix_anyone_thing() {
        assert_suggestion_result(
            "Can anyone thing of a (reasonable) way to align them such that the 'a's in all 4 words will be in (more or less) the same vertical position?",
            test_linter(),
            "Can anyone think of a (reasonable) way to align them such that the 'a's in all 4 words will be in (more or less) the same vertical position?",
        );
    }

    #[test]
    fn fix_anybody_thing() {
        assert_suggestion_result(
            "If anybody thing there is an issue in Karma, please re-open.",
            test_linter(),
            "If anybody think there is an issue in Karma, please re-open.",
        );
    }

    #[test]
    fn fix_every_body_thing() {
        assert_suggestion_result(
            "What does every body thing I should do with my Randy Johnson rookie card.",
            test_linter(),
            "What does every body think I should do with my Randy Johnson rookie card.",
        );
    }

    // Verb to

    #[test]
    fn fix_have_to_thing() {
        assert_suggestion_result(
            "I always have to thing what button does what action.",
            test_linter(),
            "I always have to think what button does what action.",
        );
    }

    #[test]
    fn fix_need_to_thing() {
        assert_suggestion_result(
            "No need to thing about the REGEX.",
            test_linter(),
            "No need to think about the REGEX.",
        );
    }

    #[test]
    fn fix_want_to_thing() {
        assert_suggestion_result(
            "maybe you want to thing of this also as a feature enhancement.",
            test_linter(),
            "maybe you want to think of this also as a feature enhancement.",
        );
    }

    #[test]
    fn fix_having_to_thing() {
        assert_suggestion_result(
            "it has saved me personally hours in combined time not having to thing about whether something is in seconds or milliseconds",
            test_linter(),
            "it has saved me personally hours in combined time not having to think about whether something is in seconds or milliseconds",
        );
    }

    #[test]
    fn fix_needs_to() {
        assert_suggestion_result(
            "When implementing any functionality once needs to thing aboiut how it is going to be used.",
            test_linter(),
            "When implementing any functionality once needs to think aboiut how it is going to be used.",
        );
    }

    #[test]
    fn fix_needed_to() {
        assert_suggestion_result(
            "Even in that case we needed to thing about the syntax so that we wouldn't need to change existing syntax",
            test_linter(),
            "Even in that case we needed to think about the syntax so that we wouldn't need to change existing syntax",
        );
    }

    #[test]
    fn fix_had_to() {
        assert_suggestion_result(
            "I had to thing in ways of making people more interested in it",
            test_linter(),
            "I had to think in ways of making people more interested in it",
        );
    }

    #[test]
    fn fix_trying_to_thing() {
        assert_suggestion_result(
            "Here I'm trying to thing about the following questions:",
            test_linter(),
            "Here I'm trying to think about the following questions:",
        );
    }

    // Modal verbs

    #[test]
    fn fix_can_thing() {
        assert_suggestion_result(
            "The exe file dosen't work allways, because antivirus can thing it is a virus.",
            test_linter(),
            "The exe file dosen't work allways, because antivirus can think it is a virus.",
        );
    }

    #[test]
    fn fix_could_thing() {
        assert_suggestion_result(
            "\"doesNotReturnSameInstanceWhenCalledMultipleTimes\" is a terrible name, but the only one i could thing of immediately.",
            test_linter(),
            "\"doesNotReturnSameInstanceWhenCalledMultipleTimes\" is a terrible name, but the only one i could think of immediately.",
        );
    }

    #[test]
    fn fix_might_thing() {
        assert_suggestion_result(
            "Consider what a reader might thing when reading a switch",
            test_linter(),
            "Consider what a reader might think when reading a switch",
        );
    }

    #[test]
    fn fix_should_thing() {
        assert_suggestion_result(
            "And we should thing to add a flag so the user could decide if internal top level extension functions are ok or not.",
            test_linter(),
            "And we should think to add a flag so the user could decide if internal top level extension functions are ok or not.",
        );
    }

    #[test]
    fn fix_may_thing() {
        assert_suggestion_result(
            "It is easier than you may thing to run both bands with hostapd.",
            test_linter(),
            "It is easier than you may think to run both bands with hostapd.",
        );
    }

    #[test]
    fn fix_cannot_thing() {
        assert_suggestion_result(
            "I cannot thing of a simple way to implement compensation of a change in Fnco.",
            test_linter(),
            "I cannot think of a simple way to implement compensation of a change in Fnco.",
        );
    }

    #[test]
    fn fix_will_thing() {
        assert_suggestion_result(
            "So user will thing that delete operation is fine but its not this code deletes the wrong page and make one extra page which wrong.",
            test_linter(),
            "So user will think that delete operation is fine but its not this code deletes the wrong page and make one extra page which wrong.",
        );
    }

    #[test]
    fn fix_cant_thing() {
        assert_suggestion_result(
            "can't thing of another place, which could have such effect",
            test_linter(),
            "can't think of another place, which could have such effect",
        );
    }

    #[test]
    fn fix_couldnt_thing() {
        assert_suggestion_result(
            "I couldn't thing about a better title, but I run into problems since the new dplyr release.",
            test_linter(),
            "I couldn't think about a better title, but I run into problems since the new dplyr release.",
        );
    }

    #[test]
    fn fix_shouldnt_thing() {
        assert_suggestion_result(
            "When dealing with a multi-tenanted system, users shouldn't thing about 'Databases', they should think about Tenants.",
            test_linter(),
            "When dealing with a multi-tenanted system, users shouldn't think about 'Databases', they should think about Tenants.",
        );
    }

    #[test]
    fn fix_wont_thing() {
        assert_suggestion_result(
            "I think you need to use an io.Pipe so the Go HTTP Request won't thing the buf has been fulling read.",
            test_linter(),
            "I think you need to use an io.Pipe so the Go HTTP Request won't think the buf has been fulling read.",
        );
    }

    // Adverb of frequency

    #[test]
    fn fix_always_thing() {
        assert_suggestion_result(
            "one should always thing of whether the efforts are better targeted to the improvement",
            test_linter(),
            "one should always think of whether the efforts are better targeted to the improvement",
        );
    }

    #[test]
    fn fix_sometimes_thing() {
        assert_suggestion_result(
            "One thing that I sometimes thing would be nice is if I could make different instances",
            test_linter(),
            "One thing that I sometimes think would be nice is if I could make different instances",
        );
    }

    #[test]
    fn fix_often_thing() {
        assert_suggestion_result(
            "When working with workflows on many forms I often thing I need to do the same over and over",
            test_linter(),
            "When working with workflows on many forms I often think I need to do the same over and over",
        );
    }

    #[test]
    fn fix_never_thing() {
        assert_suggestion_result(
            "just use UUIDv7 and never thing about those details again",
            test_linter(),
            "just use UUIDv7 and never think about those details again",
        );
    }

    #[test]
    fn fix_usually_thing() {
        assert_suggestion_result(
            "And the order of that relationship might be reversed from what one might usually thing.",
            test_linter(),
            "And the order of that relationship might be reversed from what one might usually think.",
        );
    }
}