@ttsc/lint 0.18.4 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -43
- package/go.mod +5 -4
- package/internal/rulecode/rulecode.go +88 -0
- package/lib/index.d.ts +10 -1
- package/lib/index.js +45 -17
- package/lib/index.js.map +1 -1
- package/lib/structures/ITtscLintConfig.d.ts +3 -0
- package/lib/structures/TtscLintRuleSetting.d.ts +3 -2
- package/lib/structures/format/ITtscLintFormat.d.ts +3 -2
- package/lib/structures/format/ITtscLintFormatSortImports.d.ts +20 -4
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +80 -8
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +6 -8
- package/lib/structures/rules/ITtscLintContributorRules.d.ts +18 -2
- package/lib/structures/rules/ITtscLintCoreRuleOptions.d.ts +347 -0
- package/lib/structures/rules/ITtscLintCoreRuleOptions.js +3 -0
- package/lib/structures/rules/ITtscLintCoreRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintCoreRules.d.ts +101 -67
- package/lib/structures/rules/ITtscLintRegexpRules.d.ts +7 -2
- package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +53 -7
- package/lib/structures/rules/ITtscLintRules.d.ts +6 -2
- package/lib/structures/rules/ITtscLintSolidRules.d.ts +0 -8
- package/lib/structures/rules/ITtscLintTypeScriptRuleOptions.d.ts +206 -0
- package/lib/structures/rules/ITtscLintTypeScriptRuleOptions.js +8 -0
- package/lib/structures/rules/ITtscLintTypeScriptRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +55 -42
- package/lib/structures/rules/ITtscLintUnicornRuleOptions.d.ts +276 -0
- package/lib/structures/rules/ITtscLintUnicornRuleOptions.js +3 -0
- package/lib/structures/rules/ITtscLintUnicornRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintUnicornRules.d.ts +44 -36
- package/lib/structures/rules/index.d.ts +3 -0
- package/lib/structures/rules/index.js +3 -0
- package/lib/structures/rules/index.js.map +1 -1
- package/linthost/ast_helpers.go +521 -23
- package/linthost/ast_selector_matcher.go +1628 -0
- package/linthost/ast_selector_parser.go +628 -0
- package/linthost/comment_scan.go +154 -0
- package/linthost/compile.go +129 -79
- package/linthost/config.go +352 -88
- package/linthost/config_format.go +15 -1
- package/linthost/contrib_adapter.go +47 -8
- package/linthost/declaration_rules.go +12 -11
- package/linthost/directives.go +9 -67
- package/linthost/dispatch.go +37 -3
- package/linthost/engine.go +368 -53
- package/linthost/escape_string.go +77 -0
- package/linthost/fix.go +133 -23
- package/linthost/flags_gen.go +18 -17
- package/linthost/format.go +73 -167
- package/linthost/format_editor_settings.go +134 -26
- package/linthost/grapheme_tables_gen.go +1920 -0
- package/linthost/host.go +159 -61
- package/linthost/literal_escape_scan.go +117 -0
- package/linthost/lsp.go +545 -98
- package/linthost/numeric_literal_precision.go +228 -0
- package/linthost/polyfill_browserslist.go +1439 -0
- package/linthost/polyfill_browserslist_config.go +603 -0
- package/linthost/polyfill_corejs.go +750 -0
- package/linthost/polyfill_data.go +113 -0
- package/linthost/polyfill_data_gen.json +39868 -0
- package/linthost/print_nodes_array.go +7 -1
- package/linthost/print_nodes_object.go +7 -1
- package/linthost/project_engine.go +231 -0
- package/linthost/project_rules.go +78 -0
- package/linthost/regex_clean.go +191 -0
- package/linthost/regex_tree.go +1544 -0
- package/linthost/regex_tree_optimizer.go +1685 -0
- package/linthost/regexp_cache.go +44 -0
- package/linthost/rule_codes.go +105 -0
- package/linthost/rule_codes.json +745 -0
- package/linthost/rules_ban_ts_comment.go +312 -0
- package/linthost/rules_boundaries.go +128 -43
- package/linthost/rules_boundaries_dependencies.go +1013 -0
- package/linthost/rules_core_extra.go +62 -92
- package/linthost/rules_cypress.go +1 -1
- package/linthost/rules_default_case.go +87 -11
- package/linthost/rules_dupes.go +38 -13
- package/linthost/rules_empty.go +188 -20
- package/linthost/rules_escape.go +62 -48
- package/linthost/rules_format_arrow_parens.go +19 -5
- package/linthost/rules_format_bracket_spacing.go +1 -1
- package/linthost/rules_format_clause_join.go +1 -1
- package/linthost/rules_format_declaration_header.go +31 -19
- package/linthost/rules_format_indent.go +1 -1
- package/linthost/rules_format_jsdoc.go +1 -1
- package/linthost/rules_format_orphan_semi.go +1 -1
- package/linthost/rules_format_parameter_properties.go +17 -7
- package/linthost/rules_format_print_width.go +1 -1
- package/linthost/rules_format_quote_props.go +1 -1
- package/linthost/rules_format_quotes.go +1 -1
- package/linthost/rules_format_semi.go +106 -79
- package/linthost/rules_format_sort_imports.go +79 -45
- package/linthost/rules_format_statement_split.go +1 -1
- package/linthost/rules_format_ternary_nullish_parens.go +1 -1
- package/linthost/rules_format_trailing_comma.go +64 -1
- package/linthost/rules_format_whitespace.go +1 -1
- package/linthost/rules_functional.go +21 -22
- package/linthost/rules_gap.go +80 -3
- package/linthost/rules_grouped_accessor_pairs.go +84 -25
- package/linthost/rules_guard_for_in.go +64 -147
- package/linthost/rules_jsx_a11y.go +232 -22
- package/linthost/rules_logic.go +84 -38
- package/linthost/rules_nextjs.go +105 -16
- package/linthost/rules_no_class_assign.go +70 -0
- package/linthost/rules_no_duplicate_imports.go +266 -0
- package/linthost/rules_no_else_return.go +156 -38
- package/linthost/rules_no_extend_native.go +113 -17
- package/linthost/rules_no_fallthrough.go +1013 -0
- package/linthost/rules_no_func_assign.go +70 -0
- package/linthost/rules_no_import_assign.go +278 -86
- package/linthost/rules_no_inner_declarations.go +186 -0
- package/linthost/rules_no_loop_func.go +438 -53
- package/linthost/rules_no_mixed_operators.go +208 -52
- package/linthost/rules_no_param_reassign.go +376 -61
- package/linthost/rules_no_promise_executor_return.go +156 -0
- package/linthost/rules_no_restricted_imports.go +1013 -57
- package/linthost/rules_no_restricted_syntax.go +190 -26
- package/linthost/rules_no_useless_constructor.go +6 -36
- package/linthost/rules_problems.go +154 -311
- package/linthost/rules_promise.go +2578 -109
- package/linthost/rules_react_extras.go +71 -45
- package/linthost/rules_react_hooks.go +18 -2
- package/linthost/rules_react_perf.go +1 -0
- package/linthost/rules_react_refresh.go +1 -1
- package/linthost/rules_regexp.go +230 -14
- package/linthost/rules_security.go +45 -19
- package/linthost/rules_self.go +21 -1
- package/linthost/rules_solid.go +13 -7
- package/linthost/rules_storybook.go +1 -1
- package/linthost/rules_suggestions.go +490 -84
- package/linthost/rules_testing_library.go +12 -1
- package/linthost/rules_ts.go +227 -54
- package/linthost/rules_ts_async.go +0 -131
- package/linthost/rules_ts_no_base_to_string.go +3 -4
- package/linthost/rules_ts_no_misused_promises.go +817 -0
- package/linthost/rules_ts_no_restricted_types.go +320 -34
- package/linthost/rules_ts_no_unnecessary_qualifier.go +132 -55
- package/linthost/rules_ts_no_unsafe_assignment.go +608 -60
- package/linthost/rules_ts_require_array_sort_compare.go +5 -5
- package/linthost/rules_ts_switch_exhaustiveness_check.go +556 -86
- package/linthost/rules_unicorn_better_regex.go +224 -16
- package/linthost/rules_unicorn_consistent_destructuring.go +1002 -7
- package/linthost/rules_unicorn_consistent_existence_index_check.go +208 -29
- package/linthost/rules_unicorn_consistent_function_scoping.go +1041 -8
- package/linthost/rules_unicorn_consistent_template_literal_escape.go +178 -7
- package/linthost/rules_unicorn_escape_case.go +30 -19
- package/linthost/rules_unicorn_filename_case.go +763 -16
- package/linthost/rules_unicorn_import_style.go +783 -17
- package/linthost/rules_unicorn_isolated_functions.go +934 -14
- package/linthost/rules_unicorn_no_hex_escape.go +26 -11
- package/linthost/rules_unicorn_no_typeof_undefined.go +234 -25
- package/linthost/rules_unicorn_no_unnecessary_polyfills.go +376 -21
- package/linthost/rules_unicorn_no_unused_properties.go +756 -19
- package/linthost/rules_unicorn_number_literal_case.go +58 -39
- package/linthost/rules_unicorn_prefer_at.go +7 -3
- package/linthost/rules_unicorn_prefer_number_properties.go +381 -48
- package/linthost/rules_unicorn_prefer_optional_catch_binding.go +24 -24
- package/linthost/rules_unicorn_prefer_simple_condition_first.go +597 -19
- package/linthost/rules_unicorn_prefer_string_raw.go +147 -16
- package/linthost/rules_unicorn_prevent_abbreviations.go +1963 -95
- package/linthost/rules_unicorn_string_content.go +611 -15
- package/linthost/rules_unicorn_switch_case_break_position.go +172 -15
- package/linthost/rules_unicorn_template_indent.go +923 -18
- package/linthost/rules_unicorn_text_encoding_identifier_case.go +202 -42
- package/linthost/rules_unicorn_throw_new_error.go +218 -26
- package/linthost/rules_var.go +829 -142
- package/linthost/string_length.go +222 -0
- package/package.json +4 -3
- package/rule/project.go +206 -0
- package/rule/rule.go +58 -1
- package/src/index.ts +58 -17
- package/src/structures/ITtscLintConfig.ts +3 -0
- package/src/structures/TtscLintRuleSetting.ts +3 -2
- package/src/structures/format/ITtscLintFormat.ts +3 -2
- package/src/structures/format/ITtscLintFormatSortImports.ts +21 -4
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +122 -8
- package/src/structures/rules/ITtscLintBoundariesRules.ts +6 -8
- package/src/structures/rules/ITtscLintContributorRules.ts +18 -2
- package/src/structures/rules/ITtscLintCoreRuleOptions.ts +465 -0
- package/src/structures/rules/ITtscLintCoreRules.ts +122 -67
- package/src/structures/rules/ITtscLintRegexpRules.ts +7 -2
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +88 -7
- package/src/structures/rules/ITtscLintRules.ts +7 -2
- package/src/structures/rules/ITtscLintSolidRules.ts +0 -9
- package/src/structures/rules/ITtscLintTypeScriptRuleOptions.ts +248 -0
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +64 -42
- package/src/structures/rules/ITtscLintUnicornRuleOptions.ts +350 -0
- package/src/structures/rules/ITtscLintUnicornRules.ts +60 -36
- package/src/structures/rules/index.ts +3 -0
|
@@ -1,25 +1,233 @@
|
|
|
1
|
-
// unicorn/better-regex:
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
1
|
+
// unicorn/better-regex: rewrite regex literals into their shortest
|
|
2
|
+
// equivalent form (`[0-9]` -> `\d`, dedupe/sort character classes, collapse
|
|
3
|
+
// redundant quantifiers). Two branches mirror the upstream rule:
|
|
4
|
+
//
|
|
5
|
+
// - Regex literals (`/[0-9]/`) run the full regexp-tree optimizer port in
|
|
6
|
+
// regex_tree.go + regex_tree_optimizer.go, then report + autofix when the
|
|
7
|
+
// optimized literal differs. Literals carrying the `u` or `v` flag are
|
|
8
|
+
// skipped: regexp-tree does not handle Unicode/Unicode-sets mode well, so
|
|
9
|
+
// upstream (and this port) leave them untouched.
|
|
10
|
+
// - `new RegExp("pattern", "flags")` string constructors run the
|
|
11
|
+
// clean-regexp table port in regex_clean.go and rewrite the string
|
|
12
|
+
// argument in place. Regex-literal arguments (`new RegExp(/[0-9]/)`) are
|
|
13
|
+
// handled by the literal branch on the inner node, not here.
|
|
14
|
+
//
|
|
15
|
+
// The one option, `sortCharacterClasses` (default true), maps to blacklisting
|
|
16
|
+
// regexp-tree's `charClassClassrangesMerge` transform when set to false.
|
|
8
17
|
//
|
|
9
|
-
// Replace this stub with a real implementation when a regex AST helper
|
|
10
|
-
// lands; the matching fixture under
|
|
11
|
-
// `tests/test-lint/src/cases/unicorn-better-regex.ts` carries the
|
|
12
|
-
// `@ttsc-corpus-skip` directive so the corpus test suite walks past it.
|
|
13
18
|
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/better-regex.md
|
|
14
19
|
package linthost
|
|
15
20
|
|
|
16
|
-
import
|
|
21
|
+
import (
|
|
22
|
+
"encoding/json"
|
|
23
|
+
"fmt"
|
|
24
|
+
|
|
25
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
26
|
+
shimscanner "github.com/microsoft/typescript-go/shim/scanner"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
type unicornBetterRegex struct{ optionsRule }
|
|
30
|
+
|
|
31
|
+
// unicornBetterRegexOptions is the rule's public option object. A nil
|
|
32
|
+
// `SortCharacterClasses` keeps the upstream default (sort/merge enabled).
|
|
33
|
+
type unicornBetterRegexOptions struct {
|
|
34
|
+
SortCharacterClasses *bool `json:"sortCharacterClasses"`
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
func (unicornBetterRegex) Name() string { return "unicorn/better-regex" }
|
|
38
|
+
func (unicornBetterRegex) Visits() []shimast.Kind {
|
|
39
|
+
return []shimast.Kind{shimast.KindRegularExpressionLiteral, shimast.KindNewExpression}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func (unicornBetterRegex) ValidateOptions(raw json.RawMessage) error {
|
|
43
|
+
return validateUnicornBetterRegexOptions(raw)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
func (unicornBetterRegex) Check(ctx *Context, node *shimast.Node) {
|
|
47
|
+
if ctx == nil || node == nil {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
switch node.Kind {
|
|
51
|
+
case shimast.KindRegularExpressionLiteral:
|
|
52
|
+
unicornBetterRegexCheckLiteral(ctx, node)
|
|
53
|
+
case shimast.KindNewExpression:
|
|
54
|
+
unicornBetterRegexCheckConstructor(ctx, node)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// unicornBetterRegexBlacklist decodes the `sortCharacterClasses` option and
|
|
59
|
+
// returns the regexp-tree transform blacklist it implies. Only an explicit
|
|
60
|
+
// `false` disables the class range merge/sort transform.
|
|
61
|
+
func unicornBetterRegexBlacklist(ctx *Context) map[string]bool {
|
|
62
|
+
var options unicornBetterRegexOptions
|
|
63
|
+
_ = ctx.DecodeOptions(&options)
|
|
64
|
+
if options.SortCharacterClasses != nil && !*options.SortCharacterClasses {
|
|
65
|
+
return map[string]bool{"charClassClassrangesMerge": true}
|
|
66
|
+
}
|
|
67
|
+
return nil
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// validateUnicornBetterRegexOptions enforces the upstream schema: an optional
|
|
71
|
+
// object with a single boolean `sortCharacterClasses` and no other keys.
|
|
72
|
+
func validateUnicornBetterRegexOptions(raw json.RawMessage) error {
|
|
73
|
+
if len(raw) == 0 {
|
|
74
|
+
return nil
|
|
75
|
+
}
|
|
76
|
+
var fields map[string]json.RawMessage
|
|
77
|
+
if err := json.Unmarshal(raw, &fields); err != nil {
|
|
78
|
+
return fmt.Errorf("unicorn/better-regex options must be an object: %w", err)
|
|
79
|
+
}
|
|
80
|
+
for key, value := range fields {
|
|
81
|
+
if key != "sortCharacterClasses" {
|
|
82
|
+
return fmt.Errorf("unicorn/better-regex: unknown option %q", key)
|
|
83
|
+
}
|
|
84
|
+
var flag bool
|
|
85
|
+
if err := json.Unmarshal(value, &flag); err != nil {
|
|
86
|
+
return fmt.Errorf("unicorn/better-regex: sortCharacterClasses must be a boolean")
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return nil
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// unicornBetterRegexCheckLiteral optimizes a regex literal and reports when the
|
|
93
|
+
// canonical form differs. The autofix replaces the whole literal token, except
|
|
94
|
+
// when the literal is the object of a non-optional `.source` / `.toString`
|
|
95
|
+
// member access — rewriting there could change a serialized-source consumer's
|
|
96
|
+
// expectations, so upstream reports without a fix.
|
|
97
|
+
func unicornBetterRegexCheckLiteral(ctx *Context, node *shimast.Node) {
|
|
98
|
+
source := ctx.File.Text()
|
|
99
|
+
start := shimscanner.SkipTrivia(source, node.Pos())
|
|
100
|
+
end := node.End()
|
|
101
|
+
if start < 0 || end > len(source) || start >= end {
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
original := source[start:end]
|
|
105
|
+
// regexp-tree mishandles `u` / `v` mode, so upstream skips those flags.
|
|
106
|
+
flags := unicornBetterRegexLiteralFlags(original)
|
|
107
|
+
if containsAnyByte(flags, "uv") {
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
optimized, err := regexOptimizeLiteral(original, unicornBetterRegexBlacklist(ctx))
|
|
111
|
+
if err != nil {
|
|
112
|
+
// A literal TypeScript already tokenized should parse, but this port
|
|
113
|
+
// covers a subset of regexp-tree; on any parse gap, decline rather than
|
|
114
|
+
// emit a wrong diagnostic or fix.
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
if optimized == original {
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
message := fmt.Sprintf("%s can be optimized to %s.", original, optimized)
|
|
121
|
+
if unicornBetterRegexIsSourceOrToString(node) {
|
|
122
|
+
ctx.Report(node, message)
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
ctx.ReportFix(node, message, TextEdit{Pos: start, End: end, Text: optimized})
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// unicornBetterRegexCheckConstructor rewrites a `new RegExp("pattern", "flags")`
|
|
129
|
+
// string argument via the clean-regexp table. Only a bare `new RegExp(...)`
|
|
130
|
+
// with a string-literal first argument qualifies; a regex-literal argument is
|
|
131
|
+
// left to the literal branch, and non-`RegExp` / non-string forms are ignored.
|
|
132
|
+
//
|
|
133
|
+
// clean-regexp works on the literal's cooked value, so the rewritten pattern is
|
|
134
|
+
// re-escaped through the shared escapeString port before it goes back into the
|
|
135
|
+
// source, keeping the original quote character. Emitting the cooked bytes
|
|
136
|
+
// directly would break the literal the moment the pattern carried a line
|
|
137
|
+
// terminator.
|
|
138
|
+
func unicornBetterRegexCheckConstructor(ctx *Context, node *shimast.Node) {
|
|
139
|
+
newExpr := node.AsNewExpression()
|
|
140
|
+
if newExpr == nil || identifierText(newExpr.Expression) != "RegExp" {
|
|
141
|
+
return
|
|
142
|
+
}
|
|
143
|
+
if newExpr.Arguments == nil || len(newExpr.Arguments.Nodes) < 1 {
|
|
144
|
+
return
|
|
145
|
+
}
|
|
146
|
+
patternNode := newExpr.Arguments.Nodes[0]
|
|
147
|
+
if patternNode == nil || patternNode.Kind != shimast.KindStringLiteral {
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
oldPattern := stringLiteralText(patternNode)
|
|
151
|
+
flags := ""
|
|
152
|
+
if len(newExpr.Arguments.Nodes) >= 2 {
|
|
153
|
+
if flagsNode := newExpr.Arguments.Nodes[1]; flagsNode != nil && flagsNode.Kind == shimast.KindStringLiteral {
|
|
154
|
+
flags = stringLiteralText(flagsNode)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
newPattern := regexCleanRegexp(oldPattern, flags)
|
|
158
|
+
if oldPattern == newPattern {
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
source := ctx.File.Text()
|
|
162
|
+
patternStart := shimscanner.SkipTrivia(source, patternNode.Pos())
|
|
163
|
+
patternEnd := patternNode.End()
|
|
164
|
+
if patternStart < 0 || patternEnd > len(source) || patternStart >= patternEnd {
|
|
165
|
+
return
|
|
166
|
+
}
|
|
167
|
+
quote := source[patternStart]
|
|
168
|
+
replacement := escapeString(newPattern, quote)
|
|
169
|
+
ctx.ReportFix(
|
|
170
|
+
node,
|
|
171
|
+
fmt.Sprintf("%s can be optimized to %s.", oldPattern, newPattern),
|
|
172
|
+
TextEdit{Pos: patternStart, End: patternEnd, Text: replacement},
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// unicornBetterRegexLiteralFlags returns the flag suffix of a `/pattern/flags`
|
|
177
|
+
// literal by locating the closing delimiter outside a character class, the
|
|
178
|
+
// same scan the literal parser uses.
|
|
179
|
+
func unicornBetterRegexLiteralFlags(literal string) string {
|
|
180
|
+
runes := []rune(literal)
|
|
181
|
+
if len(runes) < 2 || runes[0] != '/' {
|
|
182
|
+
return ""
|
|
183
|
+
}
|
|
184
|
+
inClass := false
|
|
185
|
+
for index := 1; index < len(runes); index++ {
|
|
186
|
+
switch runes[index] {
|
|
187
|
+
case '\\':
|
|
188
|
+
index++
|
|
189
|
+
case '[':
|
|
190
|
+
inClass = true
|
|
191
|
+
case ']':
|
|
192
|
+
inClass = false
|
|
193
|
+
case '/':
|
|
194
|
+
if !inClass {
|
|
195
|
+
return string(runes[index+1:])
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return ""
|
|
200
|
+
}
|
|
17
201
|
|
|
18
|
-
|
|
202
|
+
// containsAnyByte reports whether s contains any byte listed in set.
|
|
203
|
+
func containsAnyByte(s, set string) bool {
|
|
204
|
+
for index := 0; index < len(s); index++ {
|
|
205
|
+
for j := 0; j < len(set); j++ {
|
|
206
|
+
if s[index] == set[j] {
|
|
207
|
+
return true
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return false
|
|
212
|
+
}
|
|
19
213
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
214
|
+
// unicornBetterRegexIsSourceOrToString reports whether the regex literal is the
|
|
215
|
+
// object of a non-optional, non-computed `.source` or `.toString` member
|
|
216
|
+
// access, the one shape upstream reports without attaching a fix.
|
|
217
|
+
func unicornBetterRegexIsSourceOrToString(node *shimast.Node) bool {
|
|
218
|
+
parent := node.Parent
|
|
219
|
+
if parent == nil || parent.Kind != shimast.KindPropertyAccessExpression {
|
|
220
|
+
return false
|
|
221
|
+
}
|
|
222
|
+
access := parent.AsPropertyAccessExpression()
|
|
223
|
+
if access == nil || access.Expression != node || access.QuestionDotToken != nil {
|
|
224
|
+
return false
|
|
225
|
+
}
|
|
226
|
+
switch identifierText(access.Name()) {
|
|
227
|
+
case "source", "toString":
|
|
228
|
+
return true
|
|
229
|
+
}
|
|
230
|
+
return false
|
|
23
231
|
}
|
|
24
232
|
|
|
25
233
|
func init() {
|