@ttsc/lint 0.18.3 → 0.19.0
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 +95 -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 +129 -25
- 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 +160 -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 +151 -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 +145 -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
|
@@ -0,0 +1,1628 @@
|
|
|
1
|
+
package linthost
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"errors"
|
|
5
|
+
"math"
|
|
6
|
+
"math/big"
|
|
7
|
+
"strconv"
|
|
8
|
+
"strings"
|
|
9
|
+
"unicode/utf16"
|
|
10
|
+
|
|
11
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
12
|
+
shimscanner "github.com/microsoft/typescript-go/shim/scanner"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
// matchASTSelector returns every node selected below root. A configured
|
|
16
|
+
// selector reports each node once even when multiple alternatives or subject
|
|
17
|
+
// paths reach it.
|
|
18
|
+
func matchASTSelector(root *shimast.Node, selector *astSelector) []*shimast.Node {
|
|
19
|
+
if root == nil || selector == nil {
|
|
20
|
+
return nil
|
|
21
|
+
}
|
|
22
|
+
subjects := astSelectorSubjects(selector, selector)
|
|
23
|
+
selected := make(map[*shimast.Node]struct{})
|
|
24
|
+
ordered := make([]*shimast.Node, 0)
|
|
25
|
+
walkDescendants(root, func(node *shimast.Node) {
|
|
26
|
+
if !astSelectorMatchesNode(node, selector, nil) {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
if len(subjects) == 0 {
|
|
30
|
+
if _, duplicate := selected[node]; !duplicate {
|
|
31
|
+
selected[node] = struct{}{}
|
|
32
|
+
ordered = append(ordered, node)
|
|
33
|
+
}
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
for candidate := node; candidate != nil; candidate = selectorParent(candidate) {
|
|
37
|
+
for _, subject := range subjects {
|
|
38
|
+
if !astSelectorMatchesNode(candidate, subject, nil) {
|
|
39
|
+
continue
|
|
40
|
+
}
|
|
41
|
+
if _, duplicate := selected[candidate]; !duplicate {
|
|
42
|
+
selected[candidate] = struct{}{}
|
|
43
|
+
ordered = append(ordered, candidate)
|
|
44
|
+
}
|
|
45
|
+
break
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
return ordered
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
func astSelectorSubjects(selector, ancestor *astSelector) []*astSelector {
|
|
53
|
+
if selector == nil {
|
|
54
|
+
return nil
|
|
55
|
+
}
|
|
56
|
+
subjects := make([]*astSelector, 0)
|
|
57
|
+
if selector.subject {
|
|
58
|
+
subjects = append(subjects, ancestor)
|
|
59
|
+
}
|
|
60
|
+
if selector.left != nil {
|
|
61
|
+
subjects = append(subjects, astSelectorSubjects(selector.left, selector.left)...)
|
|
62
|
+
}
|
|
63
|
+
if selector.right != nil {
|
|
64
|
+
subjects = append(subjects, astSelectorSubjects(selector.right, ancestor)...)
|
|
65
|
+
}
|
|
66
|
+
for _, child := range selector.selectors {
|
|
67
|
+
subjects = append(subjects, astSelectorSubjects(child, ancestor)...)
|
|
68
|
+
}
|
|
69
|
+
return subjects
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
func astSelectorMatchesNode(node *shimast.Node, selector *astSelector, scopeRoot *shimast.Node) bool {
|
|
73
|
+
if node == nil || selector == nil {
|
|
74
|
+
return false
|
|
75
|
+
}
|
|
76
|
+
switch selector.kind {
|
|
77
|
+
case astSelectorWildcard:
|
|
78
|
+
return true
|
|
79
|
+
case astSelectorNodeType:
|
|
80
|
+
return astSelectorMatchesNodeType(node, selector.name)
|
|
81
|
+
case astSelectorExactNode:
|
|
82
|
+
return scopeRoot != nil && node == scopeRoot
|
|
83
|
+
case astSelectorAttribute:
|
|
84
|
+
return astSelectorMatchesAttribute(node, selector)
|
|
85
|
+
case astSelectorField:
|
|
86
|
+
return astSelectorMatchesField(node, selector.name)
|
|
87
|
+
case astSelectorMatches:
|
|
88
|
+
for _, alternative := range selector.selectors {
|
|
89
|
+
if astSelectorMatchesNode(node, alternative, scopeRoot) {
|
|
90
|
+
return true
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return false
|
|
94
|
+
case astSelectorCompound:
|
|
95
|
+
for _, part := range selector.selectors {
|
|
96
|
+
if !astSelectorMatchesNode(node, part, scopeRoot) {
|
|
97
|
+
return false
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return true
|
|
101
|
+
case astSelectorNot:
|
|
102
|
+
for _, excluded := range selector.selectors {
|
|
103
|
+
if astSelectorMatchesNode(node, excluded, scopeRoot) {
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return true
|
|
108
|
+
case astSelectorHas:
|
|
109
|
+
found := false
|
|
110
|
+
walkDescendants(node, func(candidate *shimast.Node) {
|
|
111
|
+
if found {
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
for _, nested := range selector.selectors {
|
|
115
|
+
if astSelectorMatchesNode(candidate, nested, node) {
|
|
116
|
+
found = true
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
return found
|
|
122
|
+
case astSelectorChild:
|
|
123
|
+
parent := selectorParent(node)
|
|
124
|
+
return parent != nil &&
|
|
125
|
+
astSelectorMatchesNode(node, selector.right, scopeRoot) &&
|
|
126
|
+
astSelectorMatchesNode(parent, selector.left, scopeRoot)
|
|
127
|
+
case astSelectorDescendant:
|
|
128
|
+
if !astSelectorMatchesNode(node, selector.right, scopeRoot) {
|
|
129
|
+
return false
|
|
130
|
+
}
|
|
131
|
+
for parent := selectorParent(node); parent != nil; parent = selectorParent(parent) {
|
|
132
|
+
if astSelectorMatchesNode(parent, selector.left, scopeRoot) {
|
|
133
|
+
return true
|
|
134
|
+
}
|
|
135
|
+
if scopeRoot != nil && parent == scopeRoot {
|
|
136
|
+
break
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return false
|
|
140
|
+
case astSelectorSibling:
|
|
141
|
+
if astSelectorMatchesNode(node, selector.right, scopeRoot) {
|
|
142
|
+
for _, sibling := range selectorSiblings(node, false) {
|
|
143
|
+
if astSelectorMatchesNode(sibling, selector.left, scopeRoot) {
|
|
144
|
+
return true
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if selector.left != nil && selector.left.subject && astSelectorMatchesNode(node, selector.left, scopeRoot) {
|
|
149
|
+
for _, sibling := range selectorSiblings(node, true) {
|
|
150
|
+
if astSelectorMatchesNode(sibling, selector.right, scopeRoot) {
|
|
151
|
+
return true
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return false
|
|
156
|
+
case astSelectorAdjacent:
|
|
157
|
+
if astSelectorMatchesNode(node, selector.right, scopeRoot) {
|
|
158
|
+
if sibling := selectorAdjacent(node, false); sibling != nil {
|
|
159
|
+
return astSelectorMatchesNode(sibling, selector.left, scopeRoot)
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if selector.left != nil && selector.left.subject && astSelectorMatchesNode(node, selector.left, scopeRoot) {
|
|
163
|
+
if sibling := selectorAdjacent(node, true); sibling != nil {
|
|
164
|
+
return astSelectorMatchesNode(sibling, selector.right, scopeRoot)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return false
|
|
168
|
+
case astSelectorNthChild:
|
|
169
|
+
return selectorChildIndex(node, false) == selector.index
|
|
170
|
+
case astSelectorNthLastChild:
|
|
171
|
+
return selectorChildIndex(node, true) == selector.index
|
|
172
|
+
case astSelectorClass:
|
|
173
|
+
return astSelectorMatchesClass(node, selector.name)
|
|
174
|
+
}
|
|
175
|
+
return false
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
func selectorParent(node *shimast.Node) *shimast.Node {
|
|
179
|
+
if node == nil {
|
|
180
|
+
return nil
|
|
181
|
+
}
|
|
182
|
+
return node.Parent
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
func selectorSiblings(node *shimast.Node, following bool) []*shimast.Node {
|
|
186
|
+
children, index := selectorNodeListPosition(node)
|
|
187
|
+
if index < 0 {
|
|
188
|
+
return nil
|
|
189
|
+
}
|
|
190
|
+
if following {
|
|
191
|
+
return children[index+1:]
|
|
192
|
+
}
|
|
193
|
+
return children[:index]
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
func selectorAdjacent(node *shimast.Node, following bool) *shimast.Node {
|
|
197
|
+
siblings := selectorSiblings(node, following)
|
|
198
|
+
if len(siblings) == 0 {
|
|
199
|
+
return nil
|
|
200
|
+
}
|
|
201
|
+
if following {
|
|
202
|
+
return siblings[0]
|
|
203
|
+
}
|
|
204
|
+
return siblings[len(siblings)-1]
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
func selectorChildIndex(node *shimast.Node, fromEnd bool) int {
|
|
208
|
+
children, index := selectorNodeListPosition(node)
|
|
209
|
+
if index < 0 {
|
|
210
|
+
return 0
|
|
211
|
+
}
|
|
212
|
+
if fromEnd {
|
|
213
|
+
return len(children) - index
|
|
214
|
+
}
|
|
215
|
+
return index + 1
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// esquery defines sibling and child-position selectors only within array-valued
|
|
219
|
+
// visitor fields. Scalar children such as a call's callee are not siblings of
|
|
220
|
+
// entries in its arguments array. TypeScript-Go exposes traversal through
|
|
221
|
+
// ForEachChild, so recover the node-list boundaries from the structural fields
|
|
222
|
+
// supported by this selector adapter instead of flattening every child.
|
|
223
|
+
func selectorNodeListPosition(node *shimast.Node) ([]*shimast.Node, int) {
|
|
224
|
+
parent := selectorParent(node)
|
|
225
|
+
if parent == nil {
|
|
226
|
+
return nil, -1
|
|
227
|
+
}
|
|
228
|
+
fields := [...]string{
|
|
229
|
+
"body",
|
|
230
|
+
"params",
|
|
231
|
+
"arguments",
|
|
232
|
+
"consequent",
|
|
233
|
+
"declarations",
|
|
234
|
+
"elements",
|
|
235
|
+
"members",
|
|
236
|
+
"properties",
|
|
237
|
+
"statements",
|
|
238
|
+
}
|
|
239
|
+
for _, field := range fields {
|
|
240
|
+
value := astSelectorNodeProperty(parent, field)
|
|
241
|
+
if value.kind != astSelectorRuntimeNodes {
|
|
242
|
+
continue
|
|
243
|
+
}
|
|
244
|
+
for index, candidate := range value.nodes {
|
|
245
|
+
if candidate == node {
|
|
246
|
+
return value.nodes, index
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return nil, -1
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
func astSelectorMatchesNodeType(node *shimast.Node, requested string) bool {
|
|
254
|
+
if node == nil {
|
|
255
|
+
return false
|
|
256
|
+
}
|
|
257
|
+
native := strings.TrimPrefix(node.Kind.String(), "Kind")
|
|
258
|
+
if strings.EqualFold(native, requested) {
|
|
259
|
+
return true
|
|
260
|
+
}
|
|
261
|
+
switch strings.ToLower(requested) {
|
|
262
|
+
case "program":
|
|
263
|
+
return node.Kind == shimast.KindSourceFile
|
|
264
|
+
case "arrowfunctionexpression":
|
|
265
|
+
return node.Kind == shimast.KindArrowFunction
|
|
266
|
+
case "objectexpression":
|
|
267
|
+
return node.Kind == shimast.KindObjectLiteralExpression && !isDestructuringAssignmentTarget(node)
|
|
268
|
+
case "arrayexpression":
|
|
269
|
+
return node.Kind == shimast.KindArrayLiteralExpression && !isDestructuringAssignmentTarget(node)
|
|
270
|
+
case "objectpattern":
|
|
271
|
+
return node.Kind == shimast.KindObjectBindingPattern ||
|
|
272
|
+
node.Kind == shimast.KindObjectLiteralExpression && isDestructuringAssignmentTarget(node)
|
|
273
|
+
case "arraypattern":
|
|
274
|
+
return node.Kind == shimast.KindArrayBindingPattern ||
|
|
275
|
+
node.Kind == shimast.KindArrayLiteralExpression && isDestructuringAssignmentTarget(node)
|
|
276
|
+
case "variabledeclarator":
|
|
277
|
+
return node.Kind == shimast.KindVariableDeclaration
|
|
278
|
+
case "memberexpression":
|
|
279
|
+
return node.Kind == shimast.KindPropertyAccessExpression || node.Kind == shimast.KindElementAccessExpression
|
|
280
|
+
case "assignmentexpression":
|
|
281
|
+
if node.Kind != shimast.KindBinaryExpression {
|
|
282
|
+
return false
|
|
283
|
+
}
|
|
284
|
+
expression := node.AsBinaryExpression()
|
|
285
|
+
return expression != nil && expression.OperatorToken != nil &&
|
|
286
|
+
isAssignmentOperator(expression.OperatorToken.Kind) &&
|
|
287
|
+
!isDestructuringAssignmentTarget(node)
|
|
288
|
+
case "logicalexpression":
|
|
289
|
+
if node.Kind != shimast.KindBinaryExpression {
|
|
290
|
+
return false
|
|
291
|
+
}
|
|
292
|
+
expression := node.AsBinaryExpression()
|
|
293
|
+
if expression == nil || expression.OperatorToken == nil {
|
|
294
|
+
return false
|
|
295
|
+
}
|
|
296
|
+
switch expression.OperatorToken.Kind {
|
|
297
|
+
case shimast.KindAmpersandAmpersandToken, shimast.KindBarBarToken, shimast.KindQuestionQuestionToken:
|
|
298
|
+
return true
|
|
299
|
+
}
|
|
300
|
+
return false
|
|
301
|
+
case "updateexpression":
|
|
302
|
+
if node.Kind == shimast.KindPrefixUnaryExpression {
|
|
303
|
+
expression := node.AsPrefixUnaryExpression()
|
|
304
|
+
return expression != nil && (expression.Operator == shimast.KindPlusPlusToken || expression.Operator == shimast.KindMinusMinusToken)
|
|
305
|
+
}
|
|
306
|
+
if node.Kind == shimast.KindPostfixUnaryExpression {
|
|
307
|
+
expression := node.AsPostfixUnaryExpression()
|
|
308
|
+
return expression != nil && (expression.Operator == shimast.KindPlusPlusToken || expression.Operator == shimast.KindMinusMinusToken)
|
|
309
|
+
}
|
|
310
|
+
return false
|
|
311
|
+
case "unaryexpression":
|
|
312
|
+
if node.Kind == shimast.KindPrefixUnaryExpression {
|
|
313
|
+
expression := node.AsPrefixUnaryExpression()
|
|
314
|
+
return expression != nil && expression.Operator != shimast.KindPlusPlusToken && expression.Operator != shimast.KindMinusMinusToken
|
|
315
|
+
}
|
|
316
|
+
return node.Kind == shimast.KindDeleteExpression ||
|
|
317
|
+
node.Kind == shimast.KindTypeOfExpression ||
|
|
318
|
+
node.Kind == shimast.KindVoidExpression
|
|
319
|
+
case "literal":
|
|
320
|
+
return astSelectorIsLiteral(node)
|
|
321
|
+
case "thisexpression":
|
|
322
|
+
return node.Kind == shimast.KindThisKeyword
|
|
323
|
+
case "super":
|
|
324
|
+
return node.Kind == shimast.KindSuperKeyword
|
|
325
|
+
case "templateliteral":
|
|
326
|
+
return node.Kind == shimast.KindTemplateExpression || node.Kind == shimast.KindNoSubstitutionTemplateLiteral
|
|
327
|
+
case "templateelement":
|
|
328
|
+
// ESTree models each quasi as a TemplateElement; TypeScript-Go spells
|
|
329
|
+
// them TemplateHead/Middle/Tail. A no-substitution template is its own
|
|
330
|
+
// single quasi (ESTree wraps it in a one-element TemplateLiteral).
|
|
331
|
+
return node.Kind == shimast.KindTemplateHead ||
|
|
332
|
+
node.Kind == shimast.KindTemplateMiddle ||
|
|
333
|
+
node.Kind == shimast.KindTemplateTail ||
|
|
334
|
+
node.Kind == shimast.KindNoSubstitutionTemplateLiteral
|
|
335
|
+
case "property":
|
|
336
|
+
switch node.Kind {
|
|
337
|
+
case shimast.KindPropertyAssignment,
|
|
338
|
+
shimast.KindShorthandPropertyAssignment:
|
|
339
|
+
return true
|
|
340
|
+
case shimast.KindBindingElement:
|
|
341
|
+
element := node.AsBindingElement()
|
|
342
|
+
return element != nil && element.DotDotDotToken == nil &&
|
|
343
|
+
node.Parent != nil && node.Parent.Kind == shimast.KindObjectBindingPattern
|
|
344
|
+
case shimast.KindMethodDeclaration,
|
|
345
|
+
shimast.KindGetAccessor,
|
|
346
|
+
shimast.KindSetAccessor:
|
|
347
|
+
return node.Parent != nil && node.Parent.Kind == shimast.KindObjectLiteralExpression
|
|
348
|
+
}
|
|
349
|
+
case "spreadelement":
|
|
350
|
+
return (node.Kind == shimast.KindSpreadElement || node.Kind == shimast.KindSpreadAssignment) &&
|
|
351
|
+
!isDestructuringAssignmentTarget(node)
|
|
352
|
+
case "restelement":
|
|
353
|
+
if (node.Kind == shimast.KindSpreadElement || node.Kind == shimast.KindSpreadAssignment) &&
|
|
354
|
+
isDestructuringAssignmentTarget(node) {
|
|
355
|
+
return true
|
|
356
|
+
}
|
|
357
|
+
if node.Kind == shimast.KindBindingElement {
|
|
358
|
+
element := node.AsBindingElement()
|
|
359
|
+
return element != nil && element.DotDotDotToken != nil
|
|
360
|
+
}
|
|
361
|
+
if node.Kind == shimast.KindParameter {
|
|
362
|
+
parameter := node.AsParameterDeclaration()
|
|
363
|
+
return parameter != nil && parameter.DotDotDotToken != nil
|
|
364
|
+
}
|
|
365
|
+
return false
|
|
366
|
+
case "tsasexpression":
|
|
367
|
+
return node.Kind == shimast.KindAsExpression
|
|
368
|
+
case "tstypeassertion":
|
|
369
|
+
return node.Kind == shimast.KindTypeAssertionExpression
|
|
370
|
+
case "tssatisfiesexpression":
|
|
371
|
+
return node.Kind == shimast.KindSatisfiesExpression
|
|
372
|
+
case "tsnonnullexpression":
|
|
373
|
+
return node.Kind == shimast.KindNonNullExpression
|
|
374
|
+
}
|
|
375
|
+
return false
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
func astSelectorIsLiteral(node *shimast.Node) bool {
|
|
379
|
+
if node == nil {
|
|
380
|
+
return false
|
|
381
|
+
}
|
|
382
|
+
switch node.Kind {
|
|
383
|
+
case shimast.KindNumericLiteral,
|
|
384
|
+
shimast.KindBigIntLiteral,
|
|
385
|
+
shimast.KindStringLiteral,
|
|
386
|
+
shimast.KindRegularExpressionLiteral,
|
|
387
|
+
shimast.KindTrueKeyword,
|
|
388
|
+
shimast.KindFalseKeyword,
|
|
389
|
+
shimast.KindNullKeyword:
|
|
390
|
+
return true
|
|
391
|
+
}
|
|
392
|
+
return false
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
func astSelectorMatchesClass(node *shimast.Node, class string) bool {
|
|
396
|
+
switch strings.ToLower(class) {
|
|
397
|
+
case "statement":
|
|
398
|
+
native := strings.TrimPrefix(node.Kind.String(), "Kind")
|
|
399
|
+
return strings.HasSuffix(native, "Statement") || strings.HasSuffix(native, "Declaration")
|
|
400
|
+
case "expression":
|
|
401
|
+
return astSelectorIsExpression(node)
|
|
402
|
+
case "declaration":
|
|
403
|
+
return astSelectorIsDeclaration(node)
|
|
404
|
+
case "function":
|
|
405
|
+
return isFunctionLikeKind(node)
|
|
406
|
+
case "pattern":
|
|
407
|
+
return astSelectorIsPattern(node) || astSelectorIsExpression(node)
|
|
408
|
+
default:
|
|
409
|
+
return false
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
func astSelectorIsExpression(node *shimast.Node) bool {
|
|
414
|
+
if node == nil {
|
|
415
|
+
return false
|
|
416
|
+
}
|
|
417
|
+
if astSelectorIsLiteral(node) {
|
|
418
|
+
return true
|
|
419
|
+
}
|
|
420
|
+
native := strings.TrimPrefix(node.Kind.String(), "Kind")
|
|
421
|
+
if strings.HasSuffix(native, "Expression") || strings.HasSuffix(native, "Literal") {
|
|
422
|
+
return true
|
|
423
|
+
}
|
|
424
|
+
switch node.Kind {
|
|
425
|
+
case shimast.KindIdentifier:
|
|
426
|
+
return node.Parent == nil || node.Parent.Kind != shimast.KindMetaProperty
|
|
427
|
+
case shimast.KindPrivateIdentifier,
|
|
428
|
+
shimast.KindMetaProperty,
|
|
429
|
+
shimast.KindThisKeyword,
|
|
430
|
+
shimast.KindSuperKeyword,
|
|
431
|
+
shimast.KindArrowFunction:
|
|
432
|
+
return true
|
|
433
|
+
}
|
|
434
|
+
return false
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
func astSelectorIsDeclaration(node *shimast.Node) bool {
|
|
438
|
+
if node == nil {
|
|
439
|
+
return false
|
|
440
|
+
}
|
|
441
|
+
return strings.HasSuffix(strings.TrimPrefix(node.Kind.String(), "Kind"), "Declaration")
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
func astSelectorIsPattern(node *shimast.Node) bool {
|
|
445
|
+
if node == nil {
|
|
446
|
+
return false
|
|
447
|
+
}
|
|
448
|
+
return strings.HasSuffix(strings.TrimPrefix(node.Kind.String(), "Kind"), "Pattern")
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
type astSelectorRuntimeValueKind uint8
|
|
452
|
+
|
|
453
|
+
const (
|
|
454
|
+
astSelectorRuntimeMissing astSelectorRuntimeValueKind = iota
|
|
455
|
+
astSelectorRuntimeNull
|
|
456
|
+
astSelectorRuntimeString
|
|
457
|
+
astSelectorRuntimeNumber
|
|
458
|
+
astSelectorRuntimeBigInt
|
|
459
|
+
astSelectorRuntimeBoolean
|
|
460
|
+
astSelectorRuntimeObject
|
|
461
|
+
astSelectorRuntimeNode
|
|
462
|
+
astSelectorRuntimeNodes
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
type astSelectorRuntimeValue struct {
|
|
466
|
+
kind astSelectorRuntimeValueKind
|
|
467
|
+
text string
|
|
468
|
+
number float64
|
|
469
|
+
boolean bool
|
|
470
|
+
node *shimast.Node
|
|
471
|
+
nodes []*shimast.Node
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
func astSelectorMatchesAttribute(node *shimast.Node, selector *astSelector) bool {
|
|
475
|
+
value := astSelectorPathValue(astSelectorRuntimeValue{kind: astSelectorRuntimeNode, node: node}, strings.Split(selector.name, "."))
|
|
476
|
+
if selector.operator == "" {
|
|
477
|
+
return value.kind != astSelectorRuntimeMissing && value.kind != astSelectorRuntimeNull
|
|
478
|
+
}
|
|
479
|
+
matched := false
|
|
480
|
+
switch selector.value.kind {
|
|
481
|
+
case astSelectorValueRegexp:
|
|
482
|
+
if selector.operator == "!=" {
|
|
483
|
+
return selector.value.regexp == nil || !selector.value.regexp.MatchString(astSelectorRuntimeStringValue(value))
|
|
484
|
+
}
|
|
485
|
+
matched = value.kind == astSelectorRuntimeString && selector.value.regexp != nil && selector.value.regexp.MatchString(value.text)
|
|
486
|
+
case astSelectorValueType:
|
|
487
|
+
matched = selector.value.literal == astSelectorRuntimeType(value)
|
|
488
|
+
case astSelectorValueLiteral:
|
|
489
|
+
if selector.operator == "=" || selector.operator == "!=" {
|
|
490
|
+
expected := selector.value.literal
|
|
491
|
+
if selector.value.number != nil {
|
|
492
|
+
expected = astSelectorNumberString(*selector.value.number)
|
|
493
|
+
}
|
|
494
|
+
matched = astSelectorRuntimeStringValue(value) == expected
|
|
495
|
+
} else {
|
|
496
|
+
return astSelectorCompare(value, selector.value, selector.operator)
|
|
497
|
+
}
|
|
498
|
+
default:
|
|
499
|
+
return false
|
|
500
|
+
}
|
|
501
|
+
if selector.operator == "!=" {
|
|
502
|
+
return !matched
|
|
503
|
+
}
|
|
504
|
+
return matched
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
func astSelectorCompare(value astSelectorRuntimeValue, expected astSelectorValue, operator string) bool {
|
|
508
|
+
if left, stringValue := astSelectorRuntimeRelationalString(value); stringValue && expected.number == nil {
|
|
509
|
+
comparison := astSelectorCompareUTF16(left, expected.literal)
|
|
510
|
+
switch operator {
|
|
511
|
+
case ">":
|
|
512
|
+
return comparison > 0
|
|
513
|
+
case ">=":
|
|
514
|
+
return comparison >= 0
|
|
515
|
+
case "<":
|
|
516
|
+
return comparison < 0
|
|
517
|
+
case "<=":
|
|
518
|
+
return comparison <= 0
|
|
519
|
+
}
|
|
520
|
+
return false
|
|
521
|
+
}
|
|
522
|
+
if value.kind == astSelectorRuntimeBigInt {
|
|
523
|
+
return astSelectorCompareBigInt(value.text, expected, operator)
|
|
524
|
+
}
|
|
525
|
+
left, leftNumber := astSelectorRuntimeNumberValue(value)
|
|
526
|
+
right := 0.0
|
|
527
|
+
rightNumber := false
|
|
528
|
+
if expected.number != nil {
|
|
529
|
+
right = *expected.number
|
|
530
|
+
rightNumber = true
|
|
531
|
+
} else if parsed, ok := astSelectorParseNumberString(expected.literal); ok {
|
|
532
|
+
right = parsed
|
|
533
|
+
rightNumber = true
|
|
534
|
+
}
|
|
535
|
+
if !leftNumber || !rightNumber || math.IsNaN(left) || math.IsNaN(right) {
|
|
536
|
+
return false
|
|
537
|
+
}
|
|
538
|
+
switch operator {
|
|
539
|
+
case ">":
|
|
540
|
+
return left > right
|
|
541
|
+
case ">=":
|
|
542
|
+
return left >= right
|
|
543
|
+
case "<":
|
|
544
|
+
return left < right
|
|
545
|
+
case "<=":
|
|
546
|
+
return left <= right
|
|
547
|
+
}
|
|
548
|
+
return false
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
func astSelectorCompareUTF16(left, right string) int {
|
|
552
|
+
leftUnits := utf16.Encode([]rune(left))
|
|
553
|
+
rightUnits := utf16.Encode([]rune(right))
|
|
554
|
+
length := len(leftUnits)
|
|
555
|
+
if len(rightUnits) < length {
|
|
556
|
+
length = len(rightUnits)
|
|
557
|
+
}
|
|
558
|
+
for index := 0; index < length; index++ {
|
|
559
|
+
if leftUnits[index] < rightUnits[index] {
|
|
560
|
+
return -1
|
|
561
|
+
}
|
|
562
|
+
if leftUnits[index] > rightUnits[index] {
|
|
563
|
+
return 1
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
switch {
|
|
567
|
+
case len(leftUnits) < len(rightUnits):
|
|
568
|
+
return -1
|
|
569
|
+
case len(leftUnits) > len(rightUnits):
|
|
570
|
+
return 1
|
|
571
|
+
default:
|
|
572
|
+
return 0
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
func astSelectorRuntimeRelationalString(value astSelectorRuntimeValue) (string, bool) {
|
|
577
|
+
switch value.kind {
|
|
578
|
+
case astSelectorRuntimeString,
|
|
579
|
+
astSelectorRuntimeObject,
|
|
580
|
+
astSelectorRuntimeNode,
|
|
581
|
+
astSelectorRuntimeNodes:
|
|
582
|
+
return astSelectorRuntimeStringValue(value), true
|
|
583
|
+
}
|
|
584
|
+
return "", false
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
func astSelectorCompareBigInt(value string, expected astSelectorValue, operator string) bool {
|
|
588
|
+
left, ok := new(big.Int).SetString(value, 10)
|
|
589
|
+
if !ok {
|
|
590
|
+
return false
|
|
591
|
+
}
|
|
592
|
+
right := new(big.Rat)
|
|
593
|
+
comparison := 0
|
|
594
|
+
if expected.number != nil {
|
|
595
|
+
if math.IsNaN(*expected.number) {
|
|
596
|
+
return false
|
|
597
|
+
}
|
|
598
|
+
if math.IsInf(*expected.number, 1) {
|
|
599
|
+
comparison = -1
|
|
600
|
+
} else if math.IsInf(*expected.number, -1) {
|
|
601
|
+
comparison = 1
|
|
602
|
+
} else {
|
|
603
|
+
if right.SetFloat64(*expected.number) == nil {
|
|
604
|
+
return false
|
|
605
|
+
}
|
|
606
|
+
comparison = new(big.Rat).SetInt(left).Cmp(right)
|
|
607
|
+
}
|
|
608
|
+
} else {
|
|
609
|
+
integer, ok := astSelectorParseBigIntString(expected.literal)
|
|
610
|
+
if !ok {
|
|
611
|
+
return false
|
|
612
|
+
}
|
|
613
|
+
right.SetInt(integer)
|
|
614
|
+
comparison = new(big.Rat).SetInt(left).Cmp(right)
|
|
615
|
+
}
|
|
616
|
+
switch operator {
|
|
617
|
+
case ">":
|
|
618
|
+
return comparison > 0
|
|
619
|
+
case ">=":
|
|
620
|
+
return comparison >= 0
|
|
621
|
+
case "<":
|
|
622
|
+
return comparison < 0
|
|
623
|
+
case "<=":
|
|
624
|
+
return comparison <= 0
|
|
625
|
+
}
|
|
626
|
+
return false
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
func astSelectorParseBigIntString(value string) (*big.Int, bool) {
|
|
630
|
+
value = strings.TrimSpace(value)
|
|
631
|
+
if value == "" {
|
|
632
|
+
return new(big.Int), true
|
|
633
|
+
}
|
|
634
|
+
negative := false
|
|
635
|
+
if value[0] == '+' || value[0] == '-' {
|
|
636
|
+
negative = value[0] == '-'
|
|
637
|
+
value = value[1:]
|
|
638
|
+
if value == "" {
|
|
639
|
+
return nil, false
|
|
640
|
+
}
|
|
641
|
+
lower := strings.ToLower(value)
|
|
642
|
+
if strings.HasPrefix(lower, "0x") || strings.HasPrefix(lower, "0o") || strings.HasPrefix(lower, "0b") {
|
|
643
|
+
return nil, false
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
base := 10
|
|
647
|
+
lower := strings.ToLower(value)
|
|
648
|
+
switch {
|
|
649
|
+
case strings.HasPrefix(lower, "0x"):
|
|
650
|
+
base, value = 16, value[2:]
|
|
651
|
+
case strings.HasPrefix(lower, "0o"):
|
|
652
|
+
base, value = 8, value[2:]
|
|
653
|
+
case strings.HasPrefix(lower, "0b"):
|
|
654
|
+
base, value = 2, value[2:]
|
|
655
|
+
}
|
|
656
|
+
integer, ok := new(big.Int).SetString(value, base)
|
|
657
|
+
if !ok {
|
|
658
|
+
return nil, false
|
|
659
|
+
}
|
|
660
|
+
if negative {
|
|
661
|
+
integer.Neg(integer)
|
|
662
|
+
}
|
|
663
|
+
return integer, true
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
func astSelectorRuntimeType(value astSelectorRuntimeValue) string {
|
|
667
|
+
switch value.kind {
|
|
668
|
+
case astSelectorRuntimeString:
|
|
669
|
+
return "string"
|
|
670
|
+
case astSelectorRuntimeNumber:
|
|
671
|
+
return "number"
|
|
672
|
+
case astSelectorRuntimeBigInt:
|
|
673
|
+
return "bigint"
|
|
674
|
+
case astSelectorRuntimeBoolean:
|
|
675
|
+
return "boolean"
|
|
676
|
+
case astSelectorRuntimeObject, astSelectorRuntimeNode, astSelectorRuntimeNodes, astSelectorRuntimeNull:
|
|
677
|
+
return "object"
|
|
678
|
+
default:
|
|
679
|
+
return "undefined"
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
func astSelectorRuntimeStringValue(value astSelectorRuntimeValue) string {
|
|
684
|
+
switch value.kind {
|
|
685
|
+
case astSelectorRuntimeString:
|
|
686
|
+
return value.text
|
|
687
|
+
case astSelectorRuntimeNumber:
|
|
688
|
+
return astSelectorNumberString(value.number)
|
|
689
|
+
case astSelectorRuntimeBigInt:
|
|
690
|
+
return value.text
|
|
691
|
+
case astSelectorRuntimeBoolean:
|
|
692
|
+
return strconv.FormatBool(value.boolean)
|
|
693
|
+
case astSelectorRuntimeNull:
|
|
694
|
+
return "null"
|
|
695
|
+
case astSelectorRuntimeMissing:
|
|
696
|
+
return "undefined"
|
|
697
|
+
case astSelectorRuntimeNodes:
|
|
698
|
+
if len(value.nodes) == 0 {
|
|
699
|
+
return ""
|
|
700
|
+
}
|
|
701
|
+
return strings.TrimSuffix(strings.Repeat("[object Object],", len(value.nodes)), ",")
|
|
702
|
+
case astSelectorRuntimeObject:
|
|
703
|
+
if value.text != "" {
|
|
704
|
+
return value.text
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
return "[object Object]"
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
func astSelectorRuntimeNumberValue(value astSelectorRuntimeValue) (float64, bool) {
|
|
711
|
+
switch value.kind {
|
|
712
|
+
case astSelectorRuntimeNumber:
|
|
713
|
+
return value.number, true
|
|
714
|
+
case astSelectorRuntimeString:
|
|
715
|
+
return astSelectorParseNumberString(value.text)
|
|
716
|
+
case astSelectorRuntimeBoolean:
|
|
717
|
+
if value.boolean {
|
|
718
|
+
return 1, true
|
|
719
|
+
}
|
|
720
|
+
return 0, true
|
|
721
|
+
case astSelectorRuntimeNull:
|
|
722
|
+
return 0, true
|
|
723
|
+
case astSelectorRuntimeObject,
|
|
724
|
+
astSelectorRuntimeNode,
|
|
725
|
+
astSelectorRuntimeNodes:
|
|
726
|
+
return astSelectorParseNumberString(astSelectorRuntimeStringValue(value))
|
|
727
|
+
}
|
|
728
|
+
return 0, false
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
func astSelectorNumberString(value float64) string {
|
|
732
|
+
if math.IsInf(value, 1) {
|
|
733
|
+
return "Infinity"
|
|
734
|
+
}
|
|
735
|
+
if math.IsInf(value, -1) {
|
|
736
|
+
return "-Infinity"
|
|
737
|
+
}
|
|
738
|
+
if math.IsNaN(value) {
|
|
739
|
+
return "NaN"
|
|
740
|
+
}
|
|
741
|
+
if value == 0 {
|
|
742
|
+
return "0"
|
|
743
|
+
}
|
|
744
|
+
formatted := strconv.FormatFloat(value, 'g', -1, 64)
|
|
745
|
+
exponentAt := strings.IndexByte(formatted, 'e')
|
|
746
|
+
if exponentAt < 0 {
|
|
747
|
+
return formatted
|
|
748
|
+
}
|
|
749
|
+
mantissa := formatted[:exponentAt]
|
|
750
|
+
exponent, err := strconv.Atoi(formatted[exponentAt+1:])
|
|
751
|
+
if err != nil {
|
|
752
|
+
return formatted
|
|
753
|
+
}
|
|
754
|
+
sign := ""
|
|
755
|
+
if strings.HasPrefix(mantissa, "-") {
|
|
756
|
+
sign = "-"
|
|
757
|
+
mantissa = mantissa[1:]
|
|
758
|
+
}
|
|
759
|
+
if exponent >= -6 && exponent < 21 {
|
|
760
|
+
digits := strings.ReplaceAll(mantissa, ".", "")
|
|
761
|
+
decimal := exponent + 1
|
|
762
|
+
switch {
|
|
763
|
+
case decimal <= 0:
|
|
764
|
+
return sign + "0." + strings.Repeat("0", -decimal) + digits
|
|
765
|
+
case decimal >= len(digits):
|
|
766
|
+
return sign + digits + strings.Repeat("0", decimal-len(digits))
|
|
767
|
+
default:
|
|
768
|
+
return sign + digits[:decimal] + "." + digits[decimal:]
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
exponentSign := "+"
|
|
772
|
+
if exponent < 0 {
|
|
773
|
+
exponentSign = ""
|
|
774
|
+
}
|
|
775
|
+
return sign + mantissa + "e" + exponentSign + strconv.Itoa(exponent)
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
func astSelectorParseNumberString(value string) (float64, bool) {
|
|
779
|
+
value = strings.TrimSpace(value)
|
|
780
|
+
if value == "" {
|
|
781
|
+
return 0, true
|
|
782
|
+
}
|
|
783
|
+
switch value {
|
|
784
|
+
case "Infinity", "+Infinity":
|
|
785
|
+
return math.Inf(1), true
|
|
786
|
+
case "-Infinity":
|
|
787
|
+
return math.Inf(-1), true
|
|
788
|
+
}
|
|
789
|
+
lower := strings.ToLower(value)
|
|
790
|
+
switch lower {
|
|
791
|
+
case "inf", "+inf", "-inf", "infinity", "+infinity", "-infinity":
|
|
792
|
+
return 0, false
|
|
793
|
+
}
|
|
794
|
+
if strings.ContainsRune(value, '_') {
|
|
795
|
+
return 0, false
|
|
796
|
+
}
|
|
797
|
+
if len(lower) > 1 && (lower[0] == '+' || lower[0] == '-') {
|
|
798
|
+
unsigned := lower[1:]
|
|
799
|
+
if strings.HasPrefix(unsigned, "0x") || strings.HasPrefix(unsigned, "0o") || strings.HasPrefix(unsigned, "0b") {
|
|
800
|
+
return 0, false
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
base := 0
|
|
804
|
+
switch {
|
|
805
|
+
case strings.HasPrefix(lower, "0x"):
|
|
806
|
+
base = 16
|
|
807
|
+
case strings.HasPrefix(lower, "0o"):
|
|
808
|
+
base = 8
|
|
809
|
+
case strings.HasPrefix(lower, "0b"):
|
|
810
|
+
base = 2
|
|
811
|
+
}
|
|
812
|
+
if base != 0 {
|
|
813
|
+
digits := value[2:]
|
|
814
|
+
if digits == "" || digits[0] == '+' || digits[0] == '-' || strings.ContainsRune(digits, '_') {
|
|
815
|
+
return 0, false
|
|
816
|
+
}
|
|
817
|
+
integer, ok := new(big.Int).SetString(digits, base)
|
|
818
|
+
if !ok {
|
|
819
|
+
return 0, false
|
|
820
|
+
}
|
|
821
|
+
number, _ := new(big.Float).SetInt(integer).Float64()
|
|
822
|
+
return number, true
|
|
823
|
+
}
|
|
824
|
+
number, err := strconv.ParseFloat(value, 64)
|
|
825
|
+
return number, err == nil || errors.Is(err, strconv.ErrRange)
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
func astSelectorPathValue(value astSelectorRuntimeValue, path []string) astSelectorRuntimeValue {
|
|
829
|
+
current := value
|
|
830
|
+
for _, field := range path {
|
|
831
|
+
switch current.kind {
|
|
832
|
+
case astSelectorRuntimeNode:
|
|
833
|
+
current = astSelectorNodeProperty(current.node, field)
|
|
834
|
+
case astSelectorRuntimeNodes:
|
|
835
|
+
if field == "length" {
|
|
836
|
+
current = astSelectorRuntimeValue{kind: astSelectorRuntimeNumber, number: float64(len(current.nodes))}
|
|
837
|
+
continue
|
|
838
|
+
}
|
|
839
|
+
index, err := strconv.Atoi(field)
|
|
840
|
+
if err != nil || index < 0 || strconv.Itoa(index) != field || index >= len(current.nodes) {
|
|
841
|
+
return astSelectorRuntimeValue{}
|
|
842
|
+
}
|
|
843
|
+
current = astSelectorNode(current.nodes[index])
|
|
844
|
+
case astSelectorRuntimeString:
|
|
845
|
+
if field != "length" {
|
|
846
|
+
return astSelectorRuntimeValue{}
|
|
847
|
+
}
|
|
848
|
+
current = astSelectorRuntimeValue{
|
|
849
|
+
kind: astSelectorRuntimeNumber,
|
|
850
|
+
number: float64(len(utf16.Encode([]rune(current.text)))),
|
|
851
|
+
}
|
|
852
|
+
case astSelectorRuntimeNull:
|
|
853
|
+
return current
|
|
854
|
+
default:
|
|
855
|
+
return astSelectorRuntimeValue{}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
return current
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
func astSelectorMatchesField(node *shimast.Node, name string) bool {
|
|
862
|
+
path := strings.Split(name, ".")
|
|
863
|
+
ancestor := node
|
|
864
|
+
for range path {
|
|
865
|
+
ancestor = selectorParent(ancestor)
|
|
866
|
+
if ancestor == nil {
|
|
867
|
+
return false
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
return astSelectorNodeInPath(node, astSelectorRuntimeValue{kind: astSelectorRuntimeNode, node: ancestor}, path)
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
func astSelectorNodeInPath(node *shimast.Node, value astSelectorRuntimeValue, path []string) bool {
|
|
874
|
+
if len(path) == 0 {
|
|
875
|
+
return value.kind == astSelectorRuntimeNode && value.node == node
|
|
876
|
+
}
|
|
877
|
+
if value.kind != astSelectorRuntimeNode {
|
|
878
|
+
return false
|
|
879
|
+
}
|
|
880
|
+
next := astSelectorNodeProperty(value.node, path[0])
|
|
881
|
+
if next.kind == astSelectorRuntimeNodes {
|
|
882
|
+
for _, child := range next.nodes {
|
|
883
|
+
if astSelectorNodeInPath(node, astSelectorRuntimeValue{kind: astSelectorRuntimeNode, node: child}, path[1:]) {
|
|
884
|
+
return true
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
return false
|
|
888
|
+
}
|
|
889
|
+
return astSelectorNodeInPath(node, next, path[1:])
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
func astSelectorNodeProperty(node *shimast.Node, field string) astSelectorRuntimeValue {
|
|
893
|
+
if node == nil {
|
|
894
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeNull}
|
|
895
|
+
}
|
|
896
|
+
switch field {
|
|
897
|
+
case "type":
|
|
898
|
+
return astSelectorString(strings.TrimPrefix(node.Kind.String(), "Kind"))
|
|
899
|
+
case "name":
|
|
900
|
+
if name := identifierText(node); name != "" {
|
|
901
|
+
return astSelectorString(name)
|
|
902
|
+
}
|
|
903
|
+
if node.Kind == shimast.KindPrivateIdentifier {
|
|
904
|
+
return astSelectorString(node.AsPrivateIdentifier().Text)
|
|
905
|
+
}
|
|
906
|
+
nameNode := node.Name()
|
|
907
|
+
if name := identifierText(nameNode); name != "" {
|
|
908
|
+
return astSelectorString(name)
|
|
909
|
+
}
|
|
910
|
+
if nameNode != nil && nameNode.Kind == shimast.KindPrivateIdentifier {
|
|
911
|
+
return astSelectorString(nameNode.AsPrivateIdentifier().Text)
|
|
912
|
+
}
|
|
913
|
+
if value := astSelectorLiteralValue(nameNode); value.kind != astSelectorRuntimeMissing {
|
|
914
|
+
return value
|
|
915
|
+
}
|
|
916
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeNull}
|
|
917
|
+
case "value":
|
|
918
|
+
if node.Kind == shimast.KindPropertyAssignment {
|
|
919
|
+
return astSelectorNode(node.AsPropertyAssignment().Initializer)
|
|
920
|
+
}
|
|
921
|
+
if node.Kind == shimast.KindShorthandPropertyAssignment {
|
|
922
|
+
return astSelectorNode(node.AsShorthandPropertyAssignment().Name())
|
|
923
|
+
}
|
|
924
|
+
if node.Kind == shimast.KindBindingElement {
|
|
925
|
+
return astSelectorNode(node.Name())
|
|
926
|
+
}
|
|
927
|
+
return astSelectorLiteralValue(node)
|
|
928
|
+
case "raw":
|
|
929
|
+
if astSelectorIsLiteral(node) || node.Kind == shimast.KindNoSubstitutionTemplateLiteral {
|
|
930
|
+
if file := shimast.GetSourceFileOfNode(node); file != nil {
|
|
931
|
+
return astSelectorString(nodeText(file, node))
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
return astSelectorRuntimeValue{}
|
|
935
|
+
case "operator":
|
|
936
|
+
if operator := astSelectorNodeOperator(node); operator != "" {
|
|
937
|
+
return astSelectorString(operator)
|
|
938
|
+
}
|
|
939
|
+
return astSelectorRuntimeValue{}
|
|
940
|
+
case "kind":
|
|
941
|
+
if kind := astSelectorVariableKind(node); kind != "" {
|
|
942
|
+
return astSelectorString(kind)
|
|
943
|
+
}
|
|
944
|
+
return astSelectorRuntimeValue{}
|
|
945
|
+
case "async":
|
|
946
|
+
if node.FunctionLikeData() == nil {
|
|
947
|
+
return astSelectorRuntimeValue{}
|
|
948
|
+
}
|
|
949
|
+
return astSelectorBoolean(hasModifier(node, shimast.KindAsyncKeyword))
|
|
950
|
+
case "generator":
|
|
951
|
+
if node.FunctionLikeData() == nil {
|
|
952
|
+
return astSelectorRuntimeValue{}
|
|
953
|
+
}
|
|
954
|
+
return astSelectorBoolean(astSelectorIsGenerator(node))
|
|
955
|
+
case "static":
|
|
956
|
+
if !astSelectorSupportsStatic(node) {
|
|
957
|
+
return astSelectorRuntimeValue{}
|
|
958
|
+
}
|
|
959
|
+
if node.Kind == shimast.KindClassStaticBlockDeclaration {
|
|
960
|
+
return astSelectorBoolean(true)
|
|
961
|
+
}
|
|
962
|
+
return astSelectorBoolean(hasModifier(node, shimast.KindStaticKeyword))
|
|
963
|
+
case "readonly":
|
|
964
|
+
if !astSelectorSupportsReadonly(node) {
|
|
965
|
+
return astSelectorRuntimeValue{}
|
|
966
|
+
}
|
|
967
|
+
return astSelectorBoolean(hasModifier(node, shimast.KindReadonlyKeyword))
|
|
968
|
+
case "declare":
|
|
969
|
+
declared, applicable := astSelectorIsDeclared(node)
|
|
970
|
+
if !applicable {
|
|
971
|
+
return astSelectorRuntimeValue{}
|
|
972
|
+
}
|
|
973
|
+
return astSelectorBoolean(declared)
|
|
974
|
+
case "optional":
|
|
975
|
+
optional, applicable := astSelectorIsOptional(node)
|
|
976
|
+
if !applicable {
|
|
977
|
+
return astSelectorRuntimeValue{}
|
|
978
|
+
}
|
|
979
|
+
return astSelectorBoolean(optional)
|
|
980
|
+
case "computed":
|
|
981
|
+
computed, applicable := astSelectorIsComputed(node)
|
|
982
|
+
if !applicable {
|
|
983
|
+
return astSelectorRuntimeValue{}
|
|
984
|
+
}
|
|
985
|
+
return astSelectorBoolean(computed)
|
|
986
|
+
case "prefix":
|
|
987
|
+
switch node.Kind {
|
|
988
|
+
case shimast.KindPrefixUnaryExpression,
|
|
989
|
+
shimast.KindDeleteExpression,
|
|
990
|
+
shimast.KindTypeOfExpression,
|
|
991
|
+
shimast.KindVoidExpression:
|
|
992
|
+
return astSelectorBoolean(true)
|
|
993
|
+
case shimast.KindPostfixUnaryExpression:
|
|
994
|
+
return astSelectorBoolean(false)
|
|
995
|
+
}
|
|
996
|
+
return astSelectorRuntimeValue{}
|
|
997
|
+
case "id":
|
|
998
|
+
return astSelectorNode(node.Name())
|
|
999
|
+
case "params":
|
|
1000
|
+
if function := node.FunctionLikeData(); function != nil && function.Parameters != nil {
|
|
1001
|
+
return astSelectorNodes(function.Parameters.Nodes)
|
|
1002
|
+
}
|
|
1003
|
+
case "body":
|
|
1004
|
+
if body := node.Body(); body != nil {
|
|
1005
|
+
return astSelectorNode(body)
|
|
1006
|
+
}
|
|
1007
|
+
return astSelectorStatementBody(node)
|
|
1008
|
+
case "callee":
|
|
1009
|
+
if node.Kind == shimast.KindCallExpression {
|
|
1010
|
+
if call := node.AsCallExpression(); call != nil {
|
|
1011
|
+
return astSelectorNode(call.Expression)
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
if node.Kind == shimast.KindNewExpression {
|
|
1015
|
+
if expression := node.AsNewExpression(); expression != nil {
|
|
1016
|
+
return astSelectorNode(expression.Expression)
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
case "arguments":
|
|
1020
|
+
if node.Kind == shimast.KindCallExpression {
|
|
1021
|
+
if call := node.AsCallExpression(); call != nil && call.Arguments != nil {
|
|
1022
|
+
return astSelectorNodes(call.Arguments.Nodes)
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
if node.Kind == shimast.KindNewExpression {
|
|
1026
|
+
if expression := node.AsNewExpression(); expression != nil && expression.Arguments != nil {
|
|
1027
|
+
return astSelectorNodes(expression.Arguments.Nodes)
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
case "object":
|
|
1031
|
+
if node.Kind == shimast.KindPropertyAccessExpression {
|
|
1032
|
+
return astSelectorNode(node.AsPropertyAccessExpression().Expression)
|
|
1033
|
+
}
|
|
1034
|
+
if node.Kind == shimast.KindElementAccessExpression {
|
|
1035
|
+
return astSelectorNode(node.AsElementAccessExpression().Expression)
|
|
1036
|
+
}
|
|
1037
|
+
case "property":
|
|
1038
|
+
if node.Kind == shimast.KindPropertyAccessExpression {
|
|
1039
|
+
return astSelectorNode(node.AsPropertyAccessExpression().Name())
|
|
1040
|
+
}
|
|
1041
|
+
if node.Kind == shimast.KindElementAccessExpression {
|
|
1042
|
+
return astSelectorNode(node.AsElementAccessExpression().ArgumentExpression)
|
|
1043
|
+
}
|
|
1044
|
+
case "left":
|
|
1045
|
+
if node.Kind == shimast.KindBinaryExpression {
|
|
1046
|
+
return astSelectorNode(node.AsBinaryExpression().Left)
|
|
1047
|
+
}
|
|
1048
|
+
if node.Kind == shimast.KindQualifiedName {
|
|
1049
|
+
return astSelectorNode(node.AsQualifiedName().Left)
|
|
1050
|
+
}
|
|
1051
|
+
case "right":
|
|
1052
|
+
if node.Kind == shimast.KindBinaryExpression {
|
|
1053
|
+
return astSelectorNode(node.AsBinaryExpression().Right)
|
|
1054
|
+
}
|
|
1055
|
+
if node.Kind == shimast.KindQualifiedName {
|
|
1056
|
+
return astSelectorNode(node.AsQualifiedName().Right)
|
|
1057
|
+
}
|
|
1058
|
+
case "argument":
|
|
1059
|
+
return astSelectorUnaryArgument(node)
|
|
1060
|
+
case "expression":
|
|
1061
|
+
return astSelectorExpressionChild(node)
|
|
1062
|
+
case "test":
|
|
1063
|
+
return astSelectorTestChild(node)
|
|
1064
|
+
case "consequent":
|
|
1065
|
+
if node.Kind == shimast.KindIfStatement {
|
|
1066
|
+
return astSelectorNode(node.AsIfStatement().ThenStatement)
|
|
1067
|
+
}
|
|
1068
|
+
if node.Kind == shimast.KindConditionalExpression {
|
|
1069
|
+
return astSelectorNode(node.AsConditionalExpression().WhenTrue)
|
|
1070
|
+
}
|
|
1071
|
+
if node.Kind == shimast.KindCaseClause || node.Kind == shimast.KindDefaultClause {
|
|
1072
|
+
clause := node.AsCaseOrDefaultClause()
|
|
1073
|
+
if clause != nil && clause.Statements != nil {
|
|
1074
|
+
return astSelectorNodes(clause.Statements.Nodes)
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
case "alternate":
|
|
1078
|
+
if node.Kind == shimast.KindIfStatement {
|
|
1079
|
+
return astSelectorNode(node.AsIfStatement().ElseStatement)
|
|
1080
|
+
}
|
|
1081
|
+
if node.Kind == shimast.KindConditionalExpression {
|
|
1082
|
+
return astSelectorNode(node.AsConditionalExpression().WhenFalse)
|
|
1083
|
+
}
|
|
1084
|
+
case "init":
|
|
1085
|
+
if node.Kind == shimast.KindVariableDeclaration {
|
|
1086
|
+
return astSelectorNode(node.AsVariableDeclaration().Initializer)
|
|
1087
|
+
}
|
|
1088
|
+
if node.Kind == shimast.KindForStatement {
|
|
1089
|
+
return astSelectorNode(node.AsForStatement().Initializer)
|
|
1090
|
+
}
|
|
1091
|
+
case "update":
|
|
1092
|
+
if node.Kind == shimast.KindForStatement {
|
|
1093
|
+
return astSelectorNode(node.AsForStatement().Incrementor)
|
|
1094
|
+
}
|
|
1095
|
+
case "declarations":
|
|
1096
|
+
if node.Kind == shimast.KindVariableDeclarationList {
|
|
1097
|
+
list := node.AsVariableDeclarationList()
|
|
1098
|
+
if list != nil && list.Declarations != nil {
|
|
1099
|
+
return astSelectorNodes(list.Declarations.Nodes)
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
if node.Kind == shimast.KindVariableStatement {
|
|
1103
|
+
statement := node.AsVariableStatement()
|
|
1104
|
+
if statement != nil && statement.DeclarationList != nil {
|
|
1105
|
+
list := statement.DeclarationList.AsVariableDeclarationList()
|
|
1106
|
+
if list != nil && list.Declarations != nil {
|
|
1107
|
+
return astSelectorNodes(list.Declarations.Nodes)
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
case "elements":
|
|
1112
|
+
if node.Kind == shimast.KindArrayLiteralExpression {
|
|
1113
|
+
expression := node.AsArrayLiteralExpression()
|
|
1114
|
+
if expression != nil && expression.Elements != nil {
|
|
1115
|
+
return astSelectorNodes(expression.Elements.Nodes)
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
if node.Kind == shimast.KindObjectBindingPattern || node.Kind == shimast.KindArrayBindingPattern {
|
|
1119
|
+
pattern := node.AsBindingPattern()
|
|
1120
|
+
if pattern != nil && pattern.Elements != nil {
|
|
1121
|
+
return astSelectorNodes(pattern.Elements.Nodes)
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
case "properties":
|
|
1125
|
+
if node.Kind == shimast.KindObjectLiteralExpression {
|
|
1126
|
+
expression := node.AsObjectLiteralExpression()
|
|
1127
|
+
if expression != nil && expression.Properties != nil {
|
|
1128
|
+
return astSelectorNodes(expression.Properties.Nodes)
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
if node.Kind == shimast.KindObjectBindingPattern {
|
|
1132
|
+
pattern := node.AsBindingPattern()
|
|
1133
|
+
if pattern != nil && pattern.Elements != nil {
|
|
1134
|
+
return astSelectorNodes(pattern.Elements.Nodes)
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
case "members":
|
|
1138
|
+
switch node.Kind {
|
|
1139
|
+
case shimast.KindClassDeclaration,
|
|
1140
|
+
shimast.KindClassExpression,
|
|
1141
|
+
shimast.KindInterfaceDeclaration,
|
|
1142
|
+
shimast.KindEnumDeclaration,
|
|
1143
|
+
shimast.KindTypeLiteral,
|
|
1144
|
+
shimast.KindMappedType:
|
|
1145
|
+
return astSelectorNodes(node.Members())
|
|
1146
|
+
}
|
|
1147
|
+
case "key":
|
|
1148
|
+
return astSelectorPropertyKey(node)
|
|
1149
|
+
case "source":
|
|
1150
|
+
if node.Kind == shimast.KindImportDeclaration {
|
|
1151
|
+
return astSelectorNode(node.AsImportDeclaration().ModuleSpecifier)
|
|
1152
|
+
}
|
|
1153
|
+
if node.Kind == shimast.KindExportDeclaration {
|
|
1154
|
+
return astSelectorNode(node.AsExportDeclaration().ModuleSpecifier)
|
|
1155
|
+
}
|
|
1156
|
+
case "statements":
|
|
1157
|
+
return astSelectorStatements(node)
|
|
1158
|
+
}
|
|
1159
|
+
return astSelectorRuntimeValue{}
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
func astSelectorString(value string) astSelectorRuntimeValue {
|
|
1163
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeString, text: value}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
func astSelectorBoolean(value bool) astSelectorRuntimeValue {
|
|
1167
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeBoolean, boolean: value}
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
func astSelectorLiteralValue(node *shimast.Node) astSelectorRuntimeValue {
|
|
1171
|
+
if node == nil {
|
|
1172
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeNull}
|
|
1173
|
+
}
|
|
1174
|
+
switch node.Kind {
|
|
1175
|
+
case shimast.KindStringLiteral, shimast.KindNoSubstitutionTemplateLiteral:
|
|
1176
|
+
if data := node.LiteralLikeData(); data != nil {
|
|
1177
|
+
return astSelectorString(data.Text)
|
|
1178
|
+
}
|
|
1179
|
+
case shimast.KindRegularExpressionLiteral:
|
|
1180
|
+
if file := shimast.GetSourceFileOfNode(node); file != nil {
|
|
1181
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeObject, text: astSelectorRegexpString(nodeText(file, node))}
|
|
1182
|
+
}
|
|
1183
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeObject}
|
|
1184
|
+
case shimast.KindNumericLiteral:
|
|
1185
|
+
if data := node.LiteralLikeData(); data != nil {
|
|
1186
|
+
text := strings.ReplaceAll(data.Text, "_", "")
|
|
1187
|
+
if number, err := strconv.ParseFloat(text, 64); err == nil || errors.Is(err, strconv.ErrRange) {
|
|
1188
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeNumber, number: number}
|
|
1189
|
+
}
|
|
1190
|
+
if integer, ok := new(big.Int).SetString(text, 0); ok {
|
|
1191
|
+
number, _ := new(big.Float).SetInt(integer).Float64()
|
|
1192
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeNumber, number: number}
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
case shimast.KindBigIntLiteral:
|
|
1196
|
+
if data := node.LiteralLikeData(); data != nil {
|
|
1197
|
+
text := strings.TrimSuffix(strings.ReplaceAll(data.Text, "_", ""), "n")
|
|
1198
|
+
if integer, ok := new(big.Int).SetString(text, 0); ok {
|
|
1199
|
+
text = integer.String()
|
|
1200
|
+
}
|
|
1201
|
+
return astSelectorRuntimeValue{
|
|
1202
|
+
kind: astSelectorRuntimeBigInt,
|
|
1203
|
+
text: text,
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
case shimast.KindTrueKeyword:
|
|
1207
|
+
return astSelectorBoolean(true)
|
|
1208
|
+
case shimast.KindFalseKeyword:
|
|
1209
|
+
return astSelectorBoolean(false)
|
|
1210
|
+
case shimast.KindNullKeyword:
|
|
1211
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeNull}
|
|
1212
|
+
}
|
|
1213
|
+
return astSelectorRuntimeValue{}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
func astSelectorRegexpString(raw string) string {
|
|
1217
|
+
delimiter := strings.LastIndexByte(raw, '/')
|
|
1218
|
+
if delimiter <= 0 || delimiter == len(raw)-1 {
|
|
1219
|
+
return raw
|
|
1220
|
+
}
|
|
1221
|
+
flags := raw[delimiter+1:]
|
|
1222
|
+
var canonical strings.Builder
|
|
1223
|
+
for _, flag := range "dgimsuvy" {
|
|
1224
|
+
if strings.ContainsRune(flags, flag) {
|
|
1225
|
+
canonical.WriteRune(flag)
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
if canonical.Len() != len(flags) {
|
|
1229
|
+
return raw
|
|
1230
|
+
}
|
|
1231
|
+
return raw[:delimiter+1] + canonical.String()
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
func astSelectorNode(node *shimast.Node) astSelectorRuntimeValue {
|
|
1235
|
+
if node == nil {
|
|
1236
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeNull}
|
|
1237
|
+
}
|
|
1238
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeNode, node: node}
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
func astSelectorNodes(nodes []*shimast.Node) astSelectorRuntimeValue {
|
|
1242
|
+
if nodes == nil {
|
|
1243
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeNull}
|
|
1244
|
+
}
|
|
1245
|
+
return astSelectorRuntimeValue{kind: astSelectorRuntimeNodes, nodes: nodes}
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
func astSelectorNodeOperator(node *shimast.Node) string {
|
|
1249
|
+
if node == nil {
|
|
1250
|
+
return ""
|
|
1251
|
+
}
|
|
1252
|
+
kind := shimast.KindUnknown
|
|
1253
|
+
switch node.Kind {
|
|
1254
|
+
case shimast.KindBinaryExpression:
|
|
1255
|
+
if expression := node.AsBinaryExpression(); expression != nil && expression.OperatorToken != nil {
|
|
1256
|
+
kind = expression.OperatorToken.Kind
|
|
1257
|
+
}
|
|
1258
|
+
case shimast.KindPrefixUnaryExpression:
|
|
1259
|
+
kind = node.AsPrefixUnaryExpression().Operator
|
|
1260
|
+
case shimast.KindPostfixUnaryExpression:
|
|
1261
|
+
kind = node.AsPostfixUnaryExpression().Operator
|
|
1262
|
+
case shimast.KindDeleteExpression:
|
|
1263
|
+
return "delete"
|
|
1264
|
+
case shimast.KindTypeOfExpression:
|
|
1265
|
+
return "typeof"
|
|
1266
|
+
case shimast.KindVoidExpression:
|
|
1267
|
+
return "void"
|
|
1268
|
+
}
|
|
1269
|
+
return astSelectorOperatorText(kind)
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
func astSelectorOperatorText(kind shimast.Kind) string {
|
|
1273
|
+
return shimscanner.TokenToString(kind)
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
func astSelectorVariableKind(node *shimast.Node) string {
|
|
1277
|
+
if node == nil {
|
|
1278
|
+
return ""
|
|
1279
|
+
}
|
|
1280
|
+
list := node
|
|
1281
|
+
if node.Kind == shimast.KindVariableStatement {
|
|
1282
|
+
statement := node.AsVariableStatement()
|
|
1283
|
+
if statement == nil {
|
|
1284
|
+
return ""
|
|
1285
|
+
}
|
|
1286
|
+
list = statement.DeclarationList
|
|
1287
|
+
} else if node.Kind == shimast.KindVariableDeclaration {
|
|
1288
|
+
list = node.Parent
|
|
1289
|
+
}
|
|
1290
|
+
if list == nil || list.Kind != shimast.KindVariableDeclarationList {
|
|
1291
|
+
return ""
|
|
1292
|
+
}
|
|
1293
|
+
flags := list.Flags & shimast.NodeFlagsBlockScoped
|
|
1294
|
+
switch flags {
|
|
1295
|
+
case shimast.NodeFlagsLet:
|
|
1296
|
+
return "let"
|
|
1297
|
+
case shimast.NodeFlagsConst:
|
|
1298
|
+
return "const"
|
|
1299
|
+
case shimast.NodeFlagsUsing:
|
|
1300
|
+
return "using"
|
|
1301
|
+
case shimast.NodeFlagsAwaitUsing:
|
|
1302
|
+
return "await using"
|
|
1303
|
+
default:
|
|
1304
|
+
return "var"
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
func astSelectorIsGenerator(node *shimast.Node) bool {
|
|
1309
|
+
if node == nil || !isFunctionLikeKind(node) {
|
|
1310
|
+
return false
|
|
1311
|
+
}
|
|
1312
|
+
body := node.BodyData()
|
|
1313
|
+
return body != nil && body.AsteriskToken != nil
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
func astSelectorIsOptional(node *shimast.Node) (bool, bool) {
|
|
1317
|
+
if node == nil {
|
|
1318
|
+
return false, false
|
|
1319
|
+
}
|
|
1320
|
+
switch node.Kind {
|
|
1321
|
+
case shimast.KindPropertyAccessExpression:
|
|
1322
|
+
return node.AsPropertyAccessExpression().QuestionDotToken != nil, true
|
|
1323
|
+
case shimast.KindElementAccessExpression:
|
|
1324
|
+
return node.AsElementAccessExpression().QuestionDotToken != nil, true
|
|
1325
|
+
case shimast.KindCallExpression:
|
|
1326
|
+
return node.AsCallExpression().QuestionDotToken != nil, true
|
|
1327
|
+
case shimast.KindTaggedTemplateExpression:
|
|
1328
|
+
return node.AsTaggedTemplateExpression().QuestionDotToken != nil, true
|
|
1329
|
+
case shimast.KindParameter,
|
|
1330
|
+
shimast.KindNamedTupleMember,
|
|
1331
|
+
shimast.KindMethodDeclaration,
|
|
1332
|
+
shimast.KindShorthandPropertyAssignment,
|
|
1333
|
+
shimast.KindMethodSignature,
|
|
1334
|
+
shimast.KindPropertySignature,
|
|
1335
|
+
shimast.KindPropertyAssignment,
|
|
1336
|
+
shimast.KindPropertyDeclaration,
|
|
1337
|
+
shimast.KindEnumMember,
|
|
1338
|
+
shimast.KindGetAccessor,
|
|
1339
|
+
shimast.KindSetAccessor:
|
|
1340
|
+
return node.QuestionToken() != nil, true
|
|
1341
|
+
}
|
|
1342
|
+
return false, false
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
func astSelectorSupportsStatic(node *shimast.Node) bool {
|
|
1346
|
+
if node == nil {
|
|
1347
|
+
return false
|
|
1348
|
+
}
|
|
1349
|
+
switch node.Kind {
|
|
1350
|
+
case shimast.KindClassStaticBlockDeclaration:
|
|
1351
|
+
return true
|
|
1352
|
+
case shimast.KindPropertyDeclaration,
|
|
1353
|
+
shimast.KindMethodDeclaration,
|
|
1354
|
+
shimast.KindGetAccessor,
|
|
1355
|
+
shimast.KindSetAccessor:
|
|
1356
|
+
return node.Parent != nil &&
|
|
1357
|
+
(node.Parent.Kind == shimast.KindClassDeclaration || node.Parent.Kind == shimast.KindClassExpression)
|
|
1358
|
+
}
|
|
1359
|
+
return false
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
func astSelectorSupportsReadonly(node *shimast.Node) bool {
|
|
1363
|
+
if node == nil {
|
|
1364
|
+
return false
|
|
1365
|
+
}
|
|
1366
|
+
switch node.Kind {
|
|
1367
|
+
case shimast.KindParameter,
|
|
1368
|
+
shimast.KindPropertyDeclaration,
|
|
1369
|
+
shimast.KindPropertySignature,
|
|
1370
|
+
shimast.KindIndexSignature:
|
|
1371
|
+
return true
|
|
1372
|
+
}
|
|
1373
|
+
return false
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
func astSelectorIsDeclared(node *shimast.Node) (bool, bool) {
|
|
1377
|
+
if node == nil {
|
|
1378
|
+
return false, false
|
|
1379
|
+
}
|
|
1380
|
+
declaration := node
|
|
1381
|
+
if node.Kind == shimast.KindVariableDeclaration {
|
|
1382
|
+
declaration = node.Parent
|
|
1383
|
+
}
|
|
1384
|
+
if declaration != nil && declaration.Kind == shimast.KindVariableDeclarationList {
|
|
1385
|
+
declaration = declaration.Parent
|
|
1386
|
+
}
|
|
1387
|
+
if declaration != nil && declaration.Kind == shimast.KindVariableStatement {
|
|
1388
|
+
return hasModifier(declaration, shimast.KindDeclareKeyword), true
|
|
1389
|
+
}
|
|
1390
|
+
if !astSelectorIsDeclaration(node) {
|
|
1391
|
+
return false, false
|
|
1392
|
+
}
|
|
1393
|
+
return hasModifier(node, shimast.KindDeclareKeyword), true
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
func astSelectorIsComputed(node *shimast.Node) (bool, bool) {
|
|
1397
|
+
if node == nil {
|
|
1398
|
+
return false, false
|
|
1399
|
+
}
|
|
1400
|
+
switch node.Kind {
|
|
1401
|
+
case shimast.KindElementAccessExpression, shimast.KindComputedPropertyName:
|
|
1402
|
+
return true, true
|
|
1403
|
+
case shimast.KindPropertyAccessExpression:
|
|
1404
|
+
return false, true
|
|
1405
|
+
case shimast.KindBindingElement:
|
|
1406
|
+
element := node.AsBindingElement()
|
|
1407
|
+
return element != nil && element.PropertyName != nil && element.PropertyName.Kind == shimast.KindComputedPropertyName, true
|
|
1408
|
+
case shimast.KindPropertyAssignment,
|
|
1409
|
+
shimast.KindShorthandPropertyAssignment,
|
|
1410
|
+
shimast.KindMethodDeclaration,
|
|
1411
|
+
shimast.KindMethodSignature,
|
|
1412
|
+
shimast.KindGetAccessor,
|
|
1413
|
+
shimast.KindSetAccessor,
|
|
1414
|
+
shimast.KindPropertyDeclaration,
|
|
1415
|
+
shimast.KindPropertySignature,
|
|
1416
|
+
shimast.KindEnumMember:
|
|
1417
|
+
name := node.Name()
|
|
1418
|
+
return name != nil && name.Kind == shimast.KindComputedPropertyName, true
|
|
1419
|
+
}
|
|
1420
|
+
return false, false
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
func astSelectorStatementBody(node *shimast.Node) astSelectorRuntimeValue {
|
|
1424
|
+
if node == nil {
|
|
1425
|
+
return astSelectorRuntimeValue{}
|
|
1426
|
+
}
|
|
1427
|
+
switch node.Kind {
|
|
1428
|
+
case shimast.KindSourceFile:
|
|
1429
|
+
file := node.AsSourceFile()
|
|
1430
|
+
if file != nil && file.Statements != nil {
|
|
1431
|
+
return astSelectorNodes(file.Statements.Nodes)
|
|
1432
|
+
}
|
|
1433
|
+
case shimast.KindBlock:
|
|
1434
|
+
block := node.AsBlock()
|
|
1435
|
+
if block != nil && block.Statements != nil {
|
|
1436
|
+
return astSelectorNodes(block.Statements.Nodes)
|
|
1437
|
+
}
|
|
1438
|
+
case shimast.KindModuleBlock:
|
|
1439
|
+
block := node.AsModuleBlock()
|
|
1440
|
+
if block != nil && block.Statements != nil {
|
|
1441
|
+
return astSelectorNodes(block.Statements.Nodes)
|
|
1442
|
+
}
|
|
1443
|
+
case shimast.KindCatchClause:
|
|
1444
|
+
if clause := node.AsCatchClause(); clause != nil {
|
|
1445
|
+
return astSelectorNode(clause.Block)
|
|
1446
|
+
}
|
|
1447
|
+
case shimast.KindLabeledStatement:
|
|
1448
|
+
if statement := node.AsLabeledStatement(); statement != nil {
|
|
1449
|
+
return astSelectorNode(statement.Statement)
|
|
1450
|
+
}
|
|
1451
|
+
case shimast.KindClassStaticBlockDeclaration:
|
|
1452
|
+
if block := node.AsClassStaticBlockDeclaration(); block != nil {
|
|
1453
|
+
return astSelectorNode(block.Body)
|
|
1454
|
+
}
|
|
1455
|
+
case shimast.KindIfStatement:
|
|
1456
|
+
return astSelectorNode(node.AsIfStatement().ThenStatement)
|
|
1457
|
+
case shimast.KindWhileStatement:
|
|
1458
|
+
return astSelectorNode(node.AsWhileStatement().Statement)
|
|
1459
|
+
case shimast.KindDoStatement:
|
|
1460
|
+
return astSelectorNode(node.AsDoStatement().Statement)
|
|
1461
|
+
case shimast.KindForStatement:
|
|
1462
|
+
return astSelectorNode(node.AsForStatement().Statement)
|
|
1463
|
+
case shimast.KindForInStatement, shimast.KindForOfStatement:
|
|
1464
|
+
return astSelectorNode(node.AsForInOrOfStatement().Statement)
|
|
1465
|
+
case shimast.KindWithStatement:
|
|
1466
|
+
return astSelectorNode(node.AsWithStatement().Statement)
|
|
1467
|
+
}
|
|
1468
|
+
return astSelectorRuntimeValue{}
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
func astSelectorUnaryArgument(node *shimast.Node) astSelectorRuntimeValue {
|
|
1472
|
+
if node == nil {
|
|
1473
|
+
return astSelectorRuntimeValue{}
|
|
1474
|
+
}
|
|
1475
|
+
switch node.Kind {
|
|
1476
|
+
case shimast.KindPrefixUnaryExpression:
|
|
1477
|
+
return astSelectorNode(node.AsPrefixUnaryExpression().Operand)
|
|
1478
|
+
case shimast.KindPostfixUnaryExpression:
|
|
1479
|
+
return astSelectorNode(node.AsPostfixUnaryExpression().Operand)
|
|
1480
|
+
case shimast.KindDeleteExpression:
|
|
1481
|
+
return astSelectorNode(node.AsDeleteExpression().Expression)
|
|
1482
|
+
case shimast.KindTypeOfExpression:
|
|
1483
|
+
return astSelectorNode(node.AsTypeOfExpression().Expression)
|
|
1484
|
+
case shimast.KindVoidExpression:
|
|
1485
|
+
return astSelectorNode(node.AsVoidExpression().Expression)
|
|
1486
|
+
case shimast.KindAwaitExpression:
|
|
1487
|
+
return astSelectorNode(node.AsAwaitExpression().Expression)
|
|
1488
|
+
case shimast.KindYieldExpression:
|
|
1489
|
+
return astSelectorNode(node.AsYieldExpression().Expression)
|
|
1490
|
+
case shimast.KindReturnStatement:
|
|
1491
|
+
return astSelectorNode(node.AsReturnStatement().Expression)
|
|
1492
|
+
case shimast.KindThrowStatement:
|
|
1493
|
+
return astSelectorNode(node.AsThrowStatement().Expression)
|
|
1494
|
+
case shimast.KindSpreadElement:
|
|
1495
|
+
return astSelectorNode(node.AsSpreadElement().Expression)
|
|
1496
|
+
case shimast.KindSpreadAssignment:
|
|
1497
|
+
return astSelectorNode(node.AsSpreadAssignment().Expression)
|
|
1498
|
+
case shimast.KindBindingElement:
|
|
1499
|
+
element := node.AsBindingElement()
|
|
1500
|
+
if element != nil && element.DotDotDotToken != nil {
|
|
1501
|
+
return astSelectorNode(element.Name())
|
|
1502
|
+
}
|
|
1503
|
+
case shimast.KindParameter:
|
|
1504
|
+
parameter := node.AsParameterDeclaration()
|
|
1505
|
+
if parameter != nil && parameter.DotDotDotToken != nil {
|
|
1506
|
+
return astSelectorNode(parameter.Name())
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
return astSelectorRuntimeValue{}
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
func astSelectorExpressionChild(node *shimast.Node) astSelectorRuntimeValue {
|
|
1513
|
+
if node == nil {
|
|
1514
|
+
return astSelectorRuntimeValue{}
|
|
1515
|
+
}
|
|
1516
|
+
switch node.Kind {
|
|
1517
|
+
case shimast.KindPropertyAccessExpression,
|
|
1518
|
+
shimast.KindElementAccessExpression,
|
|
1519
|
+
shimast.KindParenthesizedExpression,
|
|
1520
|
+
shimast.KindCallExpression,
|
|
1521
|
+
shimast.KindNewExpression,
|
|
1522
|
+
shimast.KindExpressionWithTypeArguments,
|
|
1523
|
+
shimast.KindComputedPropertyName,
|
|
1524
|
+
shimast.KindNonNullExpression,
|
|
1525
|
+
shimast.KindTypeAssertionExpression,
|
|
1526
|
+
shimast.KindAsExpression,
|
|
1527
|
+
shimast.KindSatisfiesExpression,
|
|
1528
|
+
shimast.KindTypeOfExpression,
|
|
1529
|
+
shimast.KindSpreadAssignment,
|
|
1530
|
+
shimast.KindSpreadElement,
|
|
1531
|
+
shimast.KindTemplateSpan,
|
|
1532
|
+
shimast.KindDeleteExpression,
|
|
1533
|
+
shimast.KindVoidExpression,
|
|
1534
|
+
shimast.KindAwaitExpression,
|
|
1535
|
+
shimast.KindYieldExpression,
|
|
1536
|
+
shimast.KindPartiallyEmittedExpression,
|
|
1537
|
+
shimast.KindIfStatement,
|
|
1538
|
+
shimast.KindDoStatement,
|
|
1539
|
+
shimast.KindWhileStatement,
|
|
1540
|
+
shimast.KindWithStatement,
|
|
1541
|
+
shimast.KindForInStatement,
|
|
1542
|
+
shimast.KindForOfStatement,
|
|
1543
|
+
shimast.KindSwitchStatement,
|
|
1544
|
+
shimast.KindCaseClause,
|
|
1545
|
+
shimast.KindExpressionStatement,
|
|
1546
|
+
shimast.KindReturnStatement,
|
|
1547
|
+
shimast.KindThrowStatement,
|
|
1548
|
+
shimast.KindExternalModuleReference,
|
|
1549
|
+
shimast.KindExportAssignment,
|
|
1550
|
+
shimast.KindDecorator,
|
|
1551
|
+
shimast.KindJsxExpression,
|
|
1552
|
+
shimast.KindJsxSpreadAttribute:
|
|
1553
|
+
return astSelectorNode(node.Expression())
|
|
1554
|
+
}
|
|
1555
|
+
return astSelectorRuntimeValue{}
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
func astSelectorTestChild(node *shimast.Node) astSelectorRuntimeValue {
|
|
1559
|
+
if node == nil {
|
|
1560
|
+
return astSelectorRuntimeValue{}
|
|
1561
|
+
}
|
|
1562
|
+
switch node.Kind {
|
|
1563
|
+
case shimast.KindIfStatement:
|
|
1564
|
+
return astSelectorNode(node.AsIfStatement().Expression)
|
|
1565
|
+
case shimast.KindWhileStatement:
|
|
1566
|
+
return astSelectorNode(node.AsWhileStatement().Expression)
|
|
1567
|
+
case shimast.KindDoStatement:
|
|
1568
|
+
return astSelectorNode(node.AsDoStatement().Expression)
|
|
1569
|
+
case shimast.KindForStatement:
|
|
1570
|
+
return astSelectorNode(node.AsForStatement().Condition)
|
|
1571
|
+
case shimast.KindConditionalExpression:
|
|
1572
|
+
return astSelectorNode(node.AsConditionalExpression().Condition)
|
|
1573
|
+
case shimast.KindCaseClause:
|
|
1574
|
+
clause := node.AsCaseOrDefaultClause()
|
|
1575
|
+
if clause != nil {
|
|
1576
|
+
return astSelectorNode(clause.Expression)
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
return astSelectorRuntimeValue{}
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
func astSelectorPropertyKey(node *shimast.Node) astSelectorRuntimeValue {
|
|
1583
|
+
if node == nil {
|
|
1584
|
+
return astSelectorRuntimeValue{}
|
|
1585
|
+
}
|
|
1586
|
+
switch node.Kind {
|
|
1587
|
+
case shimast.KindPropertyAssignment:
|
|
1588
|
+
return astSelectorNode(node.AsPropertyAssignment().Name())
|
|
1589
|
+
case shimast.KindShorthandPropertyAssignment:
|
|
1590
|
+
return astSelectorNode(node.AsShorthandPropertyAssignment().Name())
|
|
1591
|
+
case shimast.KindBindingElement:
|
|
1592
|
+
element := node.AsBindingElement()
|
|
1593
|
+
if element.PropertyName != nil {
|
|
1594
|
+
return astSelectorNode(element.PropertyName)
|
|
1595
|
+
}
|
|
1596
|
+
return astSelectorNode(element.Name())
|
|
1597
|
+
}
|
|
1598
|
+
return astSelectorNode(node.Name())
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
func astSelectorStatements(node *shimast.Node) astSelectorRuntimeValue {
|
|
1602
|
+
if node == nil {
|
|
1603
|
+
return astSelectorRuntimeValue{}
|
|
1604
|
+
}
|
|
1605
|
+
switch node.Kind {
|
|
1606
|
+
case shimast.KindSourceFile:
|
|
1607
|
+
file := node.AsSourceFile()
|
|
1608
|
+
if file != nil && file.Statements != nil {
|
|
1609
|
+
return astSelectorNodes(file.Statements.Nodes)
|
|
1610
|
+
}
|
|
1611
|
+
case shimast.KindBlock:
|
|
1612
|
+
block := node.AsBlock()
|
|
1613
|
+
if block != nil && block.Statements != nil {
|
|
1614
|
+
return astSelectorNodes(block.Statements.Nodes)
|
|
1615
|
+
}
|
|
1616
|
+
case shimast.KindModuleBlock:
|
|
1617
|
+
block := node.AsModuleBlock()
|
|
1618
|
+
if block != nil && block.Statements != nil {
|
|
1619
|
+
return astSelectorNodes(block.Statements.Nodes)
|
|
1620
|
+
}
|
|
1621
|
+
case shimast.KindCaseClause, shimast.KindDefaultClause:
|
|
1622
|
+
clause := node.AsCaseOrDefaultClause()
|
|
1623
|
+
if clause != nil && clause.Statements != nil {
|
|
1624
|
+
return astSelectorNodes(clause.Statements.Nodes)
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
return astSelectorRuntimeValue{}
|
|
1628
|
+
}
|