rapydscript-ng 0.7.24 → 0.8.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/CHANGELOG.md +28 -0
- package/README.md +80 -26
- package/bin/build.ts +117 -0
- package/bin/package.json +1 -0
- package/bin/rapydscript +65 -62
- package/build_wheels.py +133 -0
- package/editor-plugins/README.md +80 -0
- package/editor-plugins/nvim.lua +321 -0
- package/local-agent.md +28 -0
- package/package.json +4 -5
- package/publish.py +27 -17
- package/release/baselib-plain-pretty.js +448 -326
- package/release/baselib-plain-ugly.js +3 -3
- package/release/compiler.js +9027 -8139
- package/release/signatures.json +27 -27
- package/release/stdlib_modules.json +1 -0
- package/src/ast.pyj +428 -280
- package/src/baselib-builtins.pyj +49 -28
- package/src/baselib-containers.pyj +241 -226
- package/src/baselib-errors.pyj +8 -1
- package/src/baselib-internal.pyj +38 -23
- package/src/baselib-itertools.pyj +13 -7
- package/src/baselib-str.pyj +59 -84
- package/src/compiler.pyj +4 -4
- package/src/errors.pyj +3 -4
- package/src/lib/aes.pyj +46 -32
- package/src/lib/elementmaker.pyj +11 -9
- package/src/lib/encodings.pyj +15 -5
- package/src/lib/gettext.pyj +9 -4
- package/src/lib/math.pyj +106 -45
- package/src/lib/operator.pyj +10 -10
- package/src/lib/pythonize.pyj +2 -1
- package/src/lib/random.pyj +28 -21
- package/src/lib/re.pyj +492 -19
- package/src/lib/traceback.pyj +171 -29
- package/src/lib/uuid.pyj +2 -2
- package/src/output/classes.pyj +28 -27
- package/src/output/codegen.pyj +87 -83
- package/src/output/comments.pyj +8 -8
- package/src/output/exceptions.pyj +20 -21
- package/src/output/functions.pyj +66 -64
- package/src/output/literals.pyj +24 -23
- package/src/output/loops.pyj +84 -142
- package/src/output/modules.pyj +55 -68
- package/src/output/operators.pyj +40 -29
- package/src/output/statements.pyj +21 -15
- package/src/output/stream.pyj +82 -56
- package/src/output/utils.pyj +12 -8
- package/src/parse.pyj +971 -620
- package/src/string_interpolation.pyj +5 -3
- package/src/tokenizer.pyj +188 -148
- package/src/utils.pyj +32 -15
- package/test/_treeshake_mod.pyj +30 -0
- package/test/_treeshake_side_effect.pyj +9 -0
- package/test/ast_serialization.pyj +392 -0
- package/test/async.pyj +95 -0
- package/test/baselib.pyj +1 -2
- package/test/embedded_compiler.pyj +57 -0
- package/test/fmt.pyj +291 -0
- package/test/generic.pyj +16 -3
- package/test/imports.pyj +8 -6
- package/test/internationalization.pyj +38 -37
- package/test/lint.pyj +120 -117
- package/test/lsp.pyj +257 -0
- package/test/repl.pyj +70 -65
- package/test/sourcemaps.pyj +315 -0
- package/test/starargs.pyj +46 -39
- package/test/str.pyj +8 -0
- package/test/traceback.pyj +263 -0
- package/test/treeshaking.pyj +181 -0
- package/test/web_repl_export.pyj +88 -0
- package/tools/ast_serialize.mjs +557 -0
- package/tools/cli.mjs +531 -0
- package/tools/compile.mjs +205 -0
- package/tools/compiler.mjs +159 -0
- package/tools/{completer.js → completer.mjs} +6 -6
- package/tools/{embedded_compiler.js → embedded_compiler.mjs} +17 -13
- package/tools/export.js +109 -56
- package/tools/fmt.mjs +975 -0
- package/tools/{gettext.js → gettext.mjs} +46 -53
- package/tools/ini.mjs +175 -0
- package/tools/{lint.js → lint.mjs} +78 -55
- package/tools/lsp.mjs +964 -0
- package/tools/lsp_protocol.mjs +259 -0
- package/tools/lsp_symbols.mjs +418 -0
- package/tools/{msgfmt.js → msgfmt.mjs} +18 -18
- package/tools/{repl.js → repl.mjs} +56 -42
- package/tools/{self.js → self.mjs} +71 -46
- package/tools/sourcemap.mjs +123 -0
- package/tools/test.mjs +252 -0
- package/tools/treeshake.mjs +400 -0
- package/tools/{utils.js → utils.mjs} +26 -23
- package/tools/{web_repl.js → web_repl.mjs} +15 -13
- package/tools/web_repl_export.mjs +97 -0
- package/tree-sitter/README.md +101 -0
- package/tree-sitter/grammar.js +992 -0
- package/tree-sitter/package.json +43 -0
- package/tree-sitter/queries/highlights.scm +232 -0
- package/tree-sitter/queries/indents.scm +64 -0
- package/tree-sitter/queries/injections.scm +14 -0
- package/tree-sitter/queries/locals.scm +108 -0
- package/tree-sitter/src/grammar.json +4976 -0
- package/tree-sitter/src/node-types.json +2901 -0
- package/tree-sitter/src/parser.c +196465 -0
- package/tree-sitter/src/scanner.c +294 -0
- package/tree-sitter/src/tree_sitter/alloc.h +54 -0
- package/tree-sitter/src/tree_sitter/array.h +330 -0
- package/tree-sitter/src/tree_sitter/parser.h +286 -0
- package/tree-sitter/test/corpus/chaining.txt +99 -0
- package/tree-sitter/test/corpus/classes.txt +147 -0
- package/tree-sitter/test/corpus/comprehensions.txt +155 -0
- package/tree-sitter/test/corpus/containers.txt +242 -0
- package/tree-sitter/test/corpus/control_flow.txt +361 -0
- package/tree-sitter/test/corpus/decorators.txt +64 -0
- package/tree-sitter/test/corpus/existential.txt +102 -0
- package/tree-sitter/test/corpus/functions.txt +293 -0
- package/tree-sitter/test/corpus/imports.txt +117 -0
- package/tree-sitter/test/corpus/literals.txt +135 -0
- package/tree-sitter/test/corpus/operators.txt +296 -0
- package/tree-sitter/test/corpus/statements.txt +189 -0
- package/tree-sitter/test/corpus/strings.txt +90 -0
- package/tree-sitter/test/corpus/subscripts.txt +227 -0
- package/tree-sitter/tree-sitter.json +36 -0
- package/web-repl/env.js +35 -23
- package/web-repl/main.js +8 -8
- package/bin/export +0 -75
- package/bin/web-repl-export +0 -102
- package/tools/cli.js +0 -523
- package/tools/compile.js +0 -184
- package/tools/compiler.js +0 -84
- package/tools/ini.js +0 -65
- package/tools/test.js +0 -110
package/src/ast.pyj
CHANGED
|
@@ -4,13 +4,14 @@ from __python__ import hash_literals
|
|
|
4
4
|
|
|
5
5
|
from utils import noop
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
def is_node_type(node, typ):
|
|
8
9
|
return v'node instanceof typ'
|
|
9
10
|
|
|
10
11
|
# Basic classes {{{
|
|
11
12
|
|
|
12
|
-
class AST:
|
|
13
13
|
|
|
14
|
+
class AST:
|
|
14
15
|
properties = {}
|
|
15
16
|
|
|
16
17
|
def __init__(self, initializer):
|
|
@@ -38,17 +39,18 @@ class AST_Token(AST):
|
|
|
38
39
|
'col': 'The column number at which the token occurs',
|
|
39
40
|
'pos': '',
|
|
40
41
|
'endpos': '',
|
|
41
|
-
'nlb':'True iff there was a newline before this token',
|
|
42
|
-
'comments_before':'True iff there were comments before this token',
|
|
43
|
-
'file':'The filename in which this token occurs',
|
|
42
|
+
'nlb': 'True iff there was a newline before this token',
|
|
43
|
+
'comments_before': 'True iff there were comments before this token',
|
|
44
|
+
'file': 'The filename in which this token occurs',
|
|
44
45
|
'leading_whitespace': 'The leading whitespace for the line on which this token occurs',
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
|
|
47
49
|
class AST_Node(AST):
|
|
48
|
-
|
|
50
|
+
'Base class of all AST nodes'
|
|
49
51
|
properties = {
|
|
50
|
-
'start':
|
|
51
|
-
'end':
|
|
52
|
+
'start': '[AST_Token] The first token of this node',
|
|
53
|
+
'end': '[AST_Token] The last token of this node'
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
def _walk(self, visitor):
|
|
@@ -59,12 +61,12 @@ class AST_Node(AST):
|
|
|
59
61
|
|
|
60
62
|
def _dump(self, depth=100, omit={'start', 'end'}, offset=0, include_name=True):
|
|
61
63
|
p = console.log
|
|
62
|
-
reset =
|
|
63
|
-
yellow =
|
|
64
|
-
blue =
|
|
65
|
-
green =
|
|
66
|
-
red =
|
|
67
|
-
magenta =
|
|
64
|
+
reset = '\x1b[0m'
|
|
65
|
+
yellow = '\x1b[33m'
|
|
66
|
+
blue = '\x1b[34m'
|
|
67
|
+
green = '\x1b[32m'
|
|
68
|
+
red = '\x1b[31m'
|
|
69
|
+
magenta = '\x1b[35m'
|
|
68
70
|
pad = Array(offset + 1).join(' ')
|
|
69
71
|
|
|
70
72
|
if include_name:
|
|
@@ -78,7 +80,7 @@ class AST_Node(AST):
|
|
|
78
80
|
p(pad + ' ' + blue + key + ': ' + reset + '[')
|
|
79
81
|
if depth > 1:
|
|
80
82
|
for element in self[key]:
|
|
81
|
-
element._dump(depth-1, omit, offset+1, True)
|
|
83
|
+
element._dump(depth - 1, omit, offset + 1, True)
|
|
82
84
|
else:
|
|
83
85
|
for element in self[key]:
|
|
84
86
|
p(pad + ' ' + yellow + element.constructor.name.slice(4) + reset)
|
|
@@ -95,10 +97,10 @@ class AST_Node(AST):
|
|
|
95
97
|
else:
|
|
96
98
|
p(pad + ' ' + blue + key + ': ' + yellow + tname + reset)
|
|
97
99
|
if depth > 1:
|
|
98
|
-
self[key]._dump(depth-1, omit, offset+1, False)
|
|
99
|
-
elif jstype(self[key]) is
|
|
100
|
+
self[key]._dump(depth - 1, omit, offset + 1, False)
|
|
101
|
+
elif jstype(self[key]) is 'string':
|
|
100
102
|
p(pad + ' ' + blue + key + ': ' + green + '"' + self[key] + '"' + reset)
|
|
101
|
-
elif jstype(self[key]) is
|
|
103
|
+
elif jstype(self[key]) is 'number':
|
|
102
104
|
p(pad + ' ' + blue + key + ': ' + green + self[key] + reset)
|
|
103
105
|
else:
|
|
104
106
|
# unexpected object
|
|
@@ -114,39 +116,44 @@ class AST_Node(AST):
|
|
|
114
116
|
|
|
115
117
|
# Statements {{{
|
|
116
118
|
|
|
119
|
+
|
|
117
120
|
class AST_Statement(AST_Node):
|
|
118
|
-
|
|
121
|
+
'Base class of all statements'
|
|
122
|
+
|
|
119
123
|
|
|
120
124
|
class AST_Debugger(AST_Statement):
|
|
121
|
-
|
|
125
|
+
'Represents a debugger statement'
|
|
126
|
+
|
|
122
127
|
|
|
123
128
|
class AST_Directive(AST_Statement):
|
|
124
129
|
'Represents a directive, like "use strict";'
|
|
125
130
|
properties = {
|
|
126
131
|
'value': "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
|
127
|
-
'scope':
|
|
132
|
+
'scope': '[AST_Scope/S] The scope that this directive affects'
|
|
128
133
|
}
|
|
129
134
|
|
|
135
|
+
|
|
130
136
|
class AST_SimpleStatement(AST_Statement):
|
|
131
|
-
|
|
132
|
-
properties =
|
|
133
|
-
'body':
|
|
137
|
+
'A statement consisting of an expression, i.e. a = 1 + 2'
|
|
138
|
+
properties = {
|
|
139
|
+
'body': '[AST_Node] an expression node (should not be instanceof AST_Statement)'
|
|
134
140
|
}
|
|
135
141
|
|
|
136
142
|
def _walk(self, visitor):
|
|
137
|
-
return visitor._visit(self, def():
|
|
143
|
+
return visitor._visit(self, def ():
|
|
138
144
|
self.body._walk(visitor)
|
|
139
145
|
)
|
|
140
146
|
|
|
147
|
+
|
|
141
148
|
class AST_Assert(AST_Statement):
|
|
142
149
|
"An assert statement, e.g. assert True, 'an error message'"
|
|
143
150
|
properties = {
|
|
144
|
-
'condition':
|
|
145
|
-
'message':
|
|
151
|
+
'condition': '[AST_Node] the expression that should be tested',
|
|
152
|
+
'message': '[AST_Node*] the expression that is the error message or None',
|
|
146
153
|
}
|
|
147
154
|
|
|
148
155
|
def _walk(self, visitor):
|
|
149
|
-
return visitor._visit(self, def():
|
|
156
|
+
return visitor._visit(self, def ():
|
|
150
157
|
self.condition._walk(visitor)
|
|
151
158
|
if self.message:
|
|
152
159
|
self.message._walk(visitor)
|
|
@@ -160,68 +167,76 @@ def walk_body(node, visitor):
|
|
|
160
167
|
for stat in node.body:
|
|
161
168
|
stat._walk(visitor)
|
|
162
169
|
|
|
170
|
+
|
|
163
171
|
class AST_Block(AST_Statement):
|
|
164
|
-
|
|
165
|
-
properties =
|
|
166
|
-
'body':
|
|
172
|
+
'A body of statements (usually bracketed)'
|
|
173
|
+
properties = {
|
|
174
|
+
'body': '[AST_Statement*] an array of statements'
|
|
167
175
|
}
|
|
168
176
|
|
|
169
177
|
def _walk(self, visitor):
|
|
170
|
-
return visitor._visit(self, def():
|
|
178
|
+
return visitor._visit(self, def ():
|
|
171
179
|
walk_body(self, visitor)
|
|
172
180
|
)
|
|
173
181
|
|
|
182
|
+
|
|
174
183
|
class AST_BlockStatement(AST_Block):
|
|
175
|
-
|
|
184
|
+
'A block statement'
|
|
185
|
+
|
|
176
186
|
|
|
177
187
|
class AST_EmptyStatement(AST_Statement):
|
|
178
|
-
|
|
188
|
+
'The empty statement (empty block or simply a semicolon)'
|
|
179
189
|
properties = {
|
|
180
|
-
'stype':
|
|
190
|
+
'stype': '[string] the type of empty statement. Is ; for semicolons',
|
|
181
191
|
}
|
|
182
192
|
|
|
183
193
|
def _walk(self, visitor):
|
|
184
194
|
return visitor._visit(self)
|
|
185
195
|
|
|
196
|
+
|
|
186
197
|
class AST_StatementWithBody(AST_Statement):
|
|
187
|
-
|
|
198
|
+
'Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`'
|
|
188
199
|
properties = {
|
|
189
200
|
'body': "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
|
|
190
201
|
}
|
|
191
202
|
|
|
192
203
|
def _walk(self, visitor):
|
|
193
|
-
return visitor._visit(self, def():
|
|
204
|
+
return visitor._visit(self, def ():
|
|
194
205
|
self.body._walk(visitor)
|
|
195
206
|
)
|
|
196
207
|
|
|
208
|
+
|
|
197
209
|
class AST_DWLoop(AST_StatementWithBody):
|
|
198
|
-
|
|
210
|
+
'Base class for do/while statements'
|
|
199
211
|
properties = {
|
|
200
|
-
'condition':
|
|
212
|
+
'condition': '[AST_Node] the loop condition. Should not be instanceof AST_Statement'
|
|
201
213
|
}
|
|
202
214
|
|
|
203
215
|
def _walk(self, visitor):
|
|
204
|
-
return visitor._visit(self, def():
|
|
216
|
+
return visitor._visit(self, def ():
|
|
205
217
|
self.condition._walk(visitor)
|
|
206
218
|
self.body._walk(visitor)
|
|
207
219
|
)
|
|
208
220
|
|
|
221
|
+
|
|
209
222
|
class AST_Do(AST_DWLoop):
|
|
210
|
-
|
|
223
|
+
'A `do` statement'
|
|
224
|
+
|
|
211
225
|
|
|
212
226
|
class AST_While(AST_DWLoop):
|
|
213
|
-
|
|
227
|
+
'A `while` statement'
|
|
228
|
+
|
|
214
229
|
|
|
215
230
|
class AST_ForIn(AST_StatementWithBody):
|
|
216
|
-
|
|
231
|
+
'A `for ... in` statement'
|
|
217
232
|
properties = {
|
|
218
|
-
'init':
|
|
219
|
-
'name':
|
|
233
|
+
'init': '[AST_Node] the `for/in` initialization code',
|
|
234
|
+
'name': '[AST_SymbolRef?] the loop variable, only if `init` is AST_Var',
|
|
220
235
|
'object': "[AST_Node] the object that we're looping through"
|
|
221
236
|
}
|
|
222
237
|
|
|
223
238
|
def _walk(self, visitor):
|
|
224
|
-
return visitor._visit(self, def():
|
|
239
|
+
return visitor._visit(self, def ():
|
|
225
240
|
self.init._walk(visitor)
|
|
226
241
|
if (self.name) self.name._walk(visitor)
|
|
227
242
|
self.object._walk(visitor)
|
|
@@ -229,40 +244,44 @@ class AST_ForIn(AST_StatementWithBody):
|
|
|
229
244
|
self.body._walk(visitor)
|
|
230
245
|
)
|
|
231
246
|
|
|
247
|
+
|
|
232
248
|
class AST_ForJS(AST_StatementWithBody):
|
|
233
|
-
|
|
249
|
+
'A `for ... in` statement'
|
|
234
250
|
properties = {
|
|
235
|
-
'condition':
|
|
251
|
+
'condition': '[AST_Verbatim] raw JavaScript conditional'
|
|
236
252
|
}
|
|
237
253
|
|
|
254
|
+
|
|
238
255
|
class AST_ListComprehension(AST_ForIn):
|
|
239
|
-
|
|
256
|
+
'A list comprehension expression'
|
|
240
257
|
properties = {
|
|
241
|
-
'condition':
|
|
242
|
-
'statement':
|
|
258
|
+
'condition': '[AST_Node] the `if` condition',
|
|
259
|
+
'statement': '[AST_Node] statement to perform on each element before returning it'
|
|
243
260
|
}
|
|
244
261
|
|
|
245
262
|
def _walk(self, visitor):
|
|
246
|
-
return visitor._visit(self, def():
|
|
263
|
+
return visitor._visit(self, def ():
|
|
247
264
|
self.init._walk(visitor)
|
|
248
265
|
self.object._walk(visitor)
|
|
249
266
|
self.statement._walk(visitor)
|
|
250
267
|
if (self.condition) self.condition._walk(visitor)
|
|
251
268
|
)
|
|
252
269
|
|
|
270
|
+
|
|
253
271
|
class AST_SetComprehension(AST_ListComprehension):
|
|
254
272
|
'A set comprehension'
|
|
255
273
|
|
|
274
|
+
|
|
256
275
|
class AST_DictComprehension(AST_ListComprehension):
|
|
257
276
|
'A set comprehension'
|
|
258
277
|
properties = {
|
|
259
|
-
'value_statement':
|
|
260
|
-
'is_pydict':
|
|
261
|
-
'is_jshash':
|
|
278
|
+
'value_statement': '[AST_Node] statement to perform on each value before returning it',
|
|
279
|
+
'is_pydict': '[bool] True if this comprehension is for a python dict',
|
|
280
|
+
'is_jshash': '[bool] True if this comprehension is for a js hash',
|
|
262
281
|
}
|
|
263
282
|
|
|
264
283
|
def _walk(self, visitor):
|
|
265
|
-
return visitor._visit(self, def():
|
|
284
|
+
return visitor._visit(self, def ():
|
|
266
285
|
self.init._walk(visitor)
|
|
267
286
|
self.object._walk(visitor)
|
|
268
287
|
self.statement._walk(visitor)
|
|
@@ -270,22 +289,25 @@ class AST_DictComprehension(AST_ListComprehension):
|
|
|
270
289
|
if (self.condition) self.condition._walk(visitor)
|
|
271
290
|
)
|
|
272
291
|
|
|
292
|
+
|
|
273
293
|
class AST_GeneratorComprehension(AST_ListComprehension):
|
|
274
294
|
'A generator comprehension'
|
|
275
295
|
|
|
296
|
+
|
|
276
297
|
class AST_With(AST_StatementWithBody):
|
|
277
|
-
|
|
298
|
+
'A `with` statement'
|
|
278
299
|
properties = {
|
|
279
|
-
'clauses':
|
|
300
|
+
'clauses': '[AST_WithClause*] the `with` clauses (comma separated)'
|
|
280
301
|
}
|
|
281
302
|
|
|
282
303
|
def _walk(self, visitor):
|
|
283
|
-
return visitor._visit(self, def():
|
|
304
|
+
return visitor._visit(self, def ():
|
|
284
305
|
for exp in self.clauses:
|
|
285
306
|
exp._walk(visitor)
|
|
286
307
|
self.body._walk(visitor)
|
|
287
308
|
)
|
|
288
309
|
|
|
310
|
+
|
|
289
311
|
class AST_WithClause(AST_Node):
|
|
290
312
|
'A clause in a with statement'
|
|
291
313
|
properties = {
|
|
@@ -294,7 +316,7 @@ class AST_WithClause(AST_Node):
|
|
|
294
316
|
}
|
|
295
317
|
|
|
296
318
|
def _walk(self, visitor):
|
|
297
|
-
return visitor._visit(self, def():
|
|
319
|
+
return visitor._visit(self, def ():
|
|
298
320
|
self.expression._walk(visitor)
|
|
299
321
|
if self.alias:
|
|
300
322
|
self.alias._walk(visitor)
|
|
@@ -303,45 +325,47 @@ class AST_WithClause(AST_Node):
|
|
|
303
325
|
|
|
304
326
|
# Scope and functions {{{
|
|
305
327
|
|
|
328
|
+
|
|
306
329
|
class AST_Scope(AST_Block):
|
|
307
|
-
|
|
330
|
+
'Base class for all statements introducing a lexical scope'
|
|
308
331
|
properties = {
|
|
309
|
-
'localvars':
|
|
310
|
-
'docstrings':
|
|
332
|
+
'localvars': '[SymbolDef*] list of variables local to this scope',
|
|
333
|
+
'docstrings': '[AST_String*] list of docstrings for this scope',
|
|
311
334
|
}
|
|
312
335
|
|
|
313
336
|
|
|
314
337
|
class AST_Toplevel(AST_Scope):
|
|
315
|
-
|
|
338
|
+
'The toplevel scope'
|
|
316
339
|
properties = {
|
|
317
|
-
'globals':
|
|
318
|
-
'baselib':
|
|
319
|
-
'imports':
|
|
320
|
-
'imported_module_ids':
|
|
321
|
-
'nonlocalvars':
|
|
322
|
-
'shebang':
|
|
323
|
-
'import_order':
|
|
324
|
-
'module_id':
|
|
325
|
-
'exports':
|
|
326
|
-
'classes':
|
|
327
|
-
'filename':
|
|
328
|
-
'srchash':
|
|
340
|
+
'globals': '[Object/S] a map of name -> SymbolDef for all undeclared names',
|
|
341
|
+
'baselib': '[Object/s] a collection of used parts of baselib',
|
|
342
|
+
'imports': '[Object/S] a map of module_id->AST_Toplevel for all imported modules (this represents all imported modules across all source files)',
|
|
343
|
+
'imported_module_ids': '[string*] a list of module ids that were imported by this module, specifically',
|
|
344
|
+
'nonlocalvars': '[String*] a list of all non-local variable names (names that come from the global scope)',
|
|
345
|
+
'shebang': '[string] If #! line is present, it will be stored here',
|
|
346
|
+
'import_order': '[number] The global order in which this scope was imported',
|
|
347
|
+
'module_id': '[string] The id of this module',
|
|
348
|
+
'exports': '[SymbolDef*] list of names exported from this module',
|
|
349
|
+
'classes': '[Object/S] a map of class names to AST_Class for classes defined in this module',
|
|
350
|
+
'filename': '[string] The absolute path to the file from which this module was read',
|
|
351
|
+
'srchash': '[string] SHA1 hash of source code, used for caching',
|
|
329
352
|
'comments_after': '[array] True iff there were comments before this token',
|
|
330
353
|
}
|
|
331
354
|
|
|
355
|
+
|
|
332
356
|
class AST_Import(AST_Statement):
|
|
333
|
-
|
|
357
|
+
'Container for a single import'
|
|
334
358
|
|
|
335
359
|
properties = {
|
|
336
360
|
'module': "[AST_SymbolVar] name of the module we're importing",
|
|
337
|
-
'key':
|
|
338
|
-
'alias':
|
|
339
|
-
'argnames':
|
|
340
|
-
'body':
|
|
361
|
+
'key': '[string] The key by which this module is stored in the global modules mapping',
|
|
362
|
+
'alias': '[AST_SymbolAlias] The name this module is imported as, can be None. For import x as y statements.',
|
|
363
|
+
'argnames': '[AST_ImportedVar*] names of objects to be imported',
|
|
364
|
+
'body': '[AST_TopLevel] parsed contents of the imported file',
|
|
341
365
|
}
|
|
342
366
|
|
|
343
367
|
def _walk(self, visitor):
|
|
344
|
-
return visitor._visit(self, def():
|
|
368
|
+
return visitor._visit(self, def ():
|
|
345
369
|
if self.alias:
|
|
346
370
|
self.alias._walk(visitor)
|
|
347
371
|
if self.argnames:
|
|
@@ -349,81 +373,103 @@ class AST_Import(AST_Statement):
|
|
|
349
373
|
arg._walk(visitor)
|
|
350
374
|
)
|
|
351
375
|
|
|
376
|
+
|
|
352
377
|
class AST_Imports(AST_Statement):
|
|
353
|
-
|
|
378
|
+
'Container for a single import'
|
|
354
379
|
properties = {
|
|
355
|
-
'imports':
|
|
380
|
+
'imports': '[AST_Import+] array of imports',
|
|
356
381
|
}
|
|
357
382
|
|
|
358
383
|
def _walk(self, visitor):
|
|
359
|
-
return visitor._visit(self, def():
|
|
384
|
+
return visitor._visit(self, def ():
|
|
360
385
|
for imp in self.imports:
|
|
361
386
|
imp._walk(visitor)
|
|
362
387
|
)
|
|
363
388
|
|
|
389
|
+
|
|
364
390
|
class AST_Decorator(AST_Node):
|
|
365
|
-
|
|
391
|
+
'Class for function decorators'
|
|
366
392
|
properties = {
|
|
367
|
-
'expression':
|
|
393
|
+
'expression': '[AST_Node] the decorator expression'
|
|
368
394
|
}
|
|
369
395
|
|
|
370
396
|
def _walk(self, visitor):
|
|
371
|
-
return visitor._visit(self, def():
|
|
397
|
+
return visitor._visit(self, def ():
|
|
372
398
|
if self.expression:
|
|
373
399
|
self.expression.walk(visitor)
|
|
374
400
|
)
|
|
375
401
|
|
|
402
|
+
|
|
403
|
+
class AST_ArgsDef(AST_Node):
|
|
404
|
+
'The formal argument definition list for a function'
|
|
405
|
+
properties = {
|
|
406
|
+
'args': '[AST_SymbolFunarg*] formal positional parameters',
|
|
407
|
+
'starargs': '[AST_SymbolFunarg?] *args parameter, or None',
|
|
408
|
+
'kwargs': '[AST_SymbolFunarg?] **kwargs parameter, or None',
|
|
409
|
+
'defaults': '[Object] map of parameter name to default value expression',
|
|
410
|
+
'has_defaults': '[bool] True if any parameter has a default value',
|
|
411
|
+
'is_simple_func': '[bool] True if no starargs, no kwargs, and no defaults',
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
def _walk(self, visitor):
|
|
415
|
+
return visitor._visit(self, def ():
|
|
416
|
+
for arg in self.args:
|
|
417
|
+
arg._walk(visitor)
|
|
418
|
+
if self.starargs:
|
|
419
|
+
self.starargs._walk(visitor)
|
|
420
|
+
if self.kwargs:
|
|
421
|
+
self.kwargs._walk(visitor)
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
|
|
376
425
|
class AST_Lambda(AST_Scope):
|
|
377
|
-
|
|
426
|
+
'Base class for functions'
|
|
378
427
|
properties = {
|
|
379
|
-
'name':
|
|
380
|
-
'argnames':
|
|
381
|
-
'decorators':
|
|
382
|
-
'is_generator':
|
|
383
|
-
'
|
|
384
|
-
'
|
|
385
|
-
|
|
428
|
+
'name': '[AST_SymbolDeclaration?] the name of this function',
|
|
429
|
+
'argnames': '[AST_ArgsDef] the function argument definitions',
|
|
430
|
+
'decorators': '[AST_Decorator*] function decorators, if any',
|
|
431
|
+
'is_generator': '[bool*] True iff this function is a generator',
|
|
432
|
+
'is_async': '[bool*] True iff this function is an async function',
|
|
433
|
+
'is_expression': '[bool*] True iff this function is a function expression',
|
|
434
|
+
'is_anonymous': '[bool*] True iff this function is an anonymous function',
|
|
435
|
+
'return_annotation': '[AST_Node?] The return type annotation provided (if any)',
|
|
386
436
|
}
|
|
387
437
|
|
|
388
438
|
def _walk(self, visitor):
|
|
389
|
-
return visitor._visit(self, def():
|
|
439
|
+
return visitor._visit(self, def ():
|
|
390
440
|
if self.decorators:
|
|
391
441
|
for d in self.decorators:
|
|
392
442
|
d.walk(visitor)
|
|
393
443
|
if self.name:
|
|
394
444
|
self.name._walk(visitor)
|
|
395
|
-
|
|
396
|
-
for arg in self.argnames:
|
|
397
|
-
arg._walk(visitor)
|
|
398
|
-
if self.argnames.starargs:
|
|
399
|
-
self.argnames.starargs._walk(visitor)
|
|
400
|
-
if self.argnames.kwargs:
|
|
401
|
-
self.argnames.kwargs._walk(visitor)
|
|
445
|
+
self.argnames._walk(visitor)
|
|
402
446
|
walk_body(self, visitor)
|
|
403
447
|
)
|
|
404
448
|
|
|
449
|
+
|
|
405
450
|
class AST_Function(AST_Lambda):
|
|
406
|
-
|
|
451
|
+
'A function expression'
|
|
452
|
+
|
|
407
453
|
|
|
408
454
|
class AST_Class(AST_Scope):
|
|
409
|
-
|
|
455
|
+
'A class declaration'
|
|
410
456
|
properties = {
|
|
411
|
-
'name':
|
|
412
|
-
'init':
|
|
413
|
-
'parent':
|
|
414
|
-
'bases':
|
|
415
|
-
|
|
416
|
-
'external':
|
|
417
|
-
'bound':
|
|
418
|
-
'decorators':
|
|
419
|
-
'module_id':
|
|
420
|
-
'statements':
|
|
457
|
+
'name': '[AST_SymbolDeclaration?] the name of this class',
|
|
458
|
+
'init': '[AST_Function] constructor for the class',
|
|
459
|
+
'parent': '[AST_Symbol?] parent class this class inherits from',
|
|
460
|
+
'bases': '[AST_Symbol*] list of base classes this class inherits from',
|
|
461
|
+
'static': '[dict] A hash whose keys are names of static methods for this class',
|
|
462
|
+
'external': '[boolean] true if class is declared elsewhere, but will be within current scope at runtime',
|
|
463
|
+
'bound': '[string*] list of methods that need to be bound to self',
|
|
464
|
+
'decorators': '[AST_Decorator*] function decorators, if any',
|
|
465
|
+
'module_id': '[string] The id of the module this class is defined in',
|
|
466
|
+
'statements': '[AST_Node*] list of statements in the class scope (excluding method definitions)',
|
|
421
467
|
'dynamic_properties': '[dict] map of dynamic property names to property descriptors of the form {getter:AST_Method, setter:AST_Method',
|
|
422
468
|
'classvars': '[dict] map containing all class variables as keys, to be used to easily test for existence of a class variable',
|
|
423
469
|
}
|
|
424
470
|
|
|
425
471
|
def _walk(self, visitor):
|
|
426
|
-
return visitor._visit(self, def():
|
|
472
|
+
return visitor._visit(self, def ():
|
|
427
473
|
if self.decorators:
|
|
428
474
|
for d in self.decorators:
|
|
429
475
|
d.walk(visitor)
|
|
@@ -432,65 +478,88 @@ class AST_Class(AST_Scope):
|
|
|
432
478
|
if (self.parent) self.parent._walk(visitor)
|
|
433
479
|
)
|
|
434
480
|
|
|
481
|
+
|
|
435
482
|
class AST_Method(AST_Lambda):
|
|
436
|
-
|
|
483
|
+
'A class method definition'
|
|
437
484
|
properties = {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
485
|
+
'static': '[boolean] true if method is static',
|
|
486
|
+
'is_getter': '[boolean] true if method is a property getter',
|
|
487
|
+
'is_setter': '[boolean] true if method is a property setter',
|
|
441
488
|
}
|
|
442
489
|
|
|
443
490
|
# }}}
|
|
444
491
|
|
|
445
492
|
# Jumps(break/continue/etc) {{{
|
|
446
493
|
|
|
494
|
+
|
|
447
495
|
class AST_Jump(AST_Statement):
|
|
448
496
|
"Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"
|
|
449
497
|
|
|
498
|
+
|
|
450
499
|
class AST_Exit(AST_Jump):
|
|
451
|
-
|
|
500
|
+
'Base class for “exits” (`return` and `throw`)'
|
|
452
501
|
properties = {
|
|
453
|
-
'value':
|
|
502
|
+
'value': '[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return'
|
|
454
503
|
}
|
|
455
504
|
|
|
456
505
|
def _walk(self, visitor):
|
|
457
|
-
return visitor._visit(self, def():
|
|
506
|
+
return visitor._visit(self, def ():
|
|
458
507
|
if self.value:
|
|
459
508
|
self.value._walk(visitor)
|
|
460
509
|
)
|
|
461
510
|
|
|
511
|
+
|
|
462
512
|
class AST_Return(AST_Exit):
|
|
463
|
-
|
|
513
|
+
'A `return` statement'
|
|
514
|
+
|
|
464
515
|
|
|
465
516
|
class AST_Yield(AST_Return):
|
|
466
|
-
|
|
517
|
+
'A `yield` statement'
|
|
518
|
+
properties = {
|
|
519
|
+
'is_yield_from': '[bool] True iff this is a yield from, False otherwise'
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
class AST_Await(AST_Node):
|
|
524
|
+
'An await expression'
|
|
467
525
|
properties = {
|
|
468
|
-
'
|
|
526
|
+
'value': '[AST_Node] the expression being awaited'
|
|
469
527
|
}
|
|
470
528
|
|
|
529
|
+
def _walk(self, visitor):
|
|
530
|
+
return visitor._visit(self, def ():
|
|
531
|
+
if self.value:
|
|
532
|
+
self.value._walk(visitor)
|
|
533
|
+
)
|
|
534
|
+
|
|
535
|
+
|
|
471
536
|
class AST_Throw(AST_Exit):
|
|
472
|
-
|
|
537
|
+
'A `throw` statement'
|
|
538
|
+
|
|
473
539
|
|
|
474
540
|
class AST_LoopControl(AST_Jump):
|
|
475
|
-
|
|
541
|
+
'Base class for loop control statements (`break` and `continue`)'
|
|
542
|
+
|
|
476
543
|
|
|
477
544
|
class AST_Break(AST_LoopControl):
|
|
478
|
-
|
|
545
|
+
'A `break` statement'
|
|
546
|
+
|
|
479
547
|
|
|
480
548
|
class AST_Continue(AST_LoopControl):
|
|
481
|
-
|
|
549
|
+
'A `continue` statement'
|
|
482
550
|
# }}}
|
|
483
551
|
|
|
552
|
+
|
|
484
553
|
# If {{{
|
|
485
554
|
class AST_If(AST_StatementWithBody):
|
|
486
|
-
|
|
555
|
+
'A `if` statement'
|
|
487
556
|
properties = {
|
|
488
|
-
'condition':
|
|
489
|
-
'alternative':
|
|
557
|
+
'condition': '[AST_Node] the `if` condition',
|
|
558
|
+
'alternative': '[AST_Statement?] the `else` part, or null if not present'
|
|
490
559
|
}
|
|
491
560
|
|
|
492
561
|
def _walk(self, visitor):
|
|
493
|
-
return visitor._visit(self, def():
|
|
562
|
+
return visitor._visit(self, def ():
|
|
494
563
|
self.condition._walk(visitor)
|
|
495
564
|
self.body._walk(visitor)
|
|
496
565
|
if self.alternative:
|
|
@@ -500,39 +569,40 @@ class AST_If(AST_StatementWithBody):
|
|
|
500
569
|
|
|
501
570
|
# EXCEPTIONS {{{
|
|
502
571
|
|
|
572
|
+
|
|
503
573
|
class AST_Try(AST_Block):
|
|
504
|
-
|
|
574
|
+
'A `try` statement'
|
|
505
575
|
properties = {
|
|
506
|
-
'bcatch':
|
|
507
|
-
'bfinally':
|
|
576
|
+
'bcatch': '[AST_Catch?] the catch block, or null if not present',
|
|
577
|
+
'bfinally': '[AST_Finally?] the finally block, or null if not present',
|
|
508
578
|
'belse': '[AST_Else?] the else block for null if not present',
|
|
509
579
|
}
|
|
510
580
|
|
|
511
581
|
def _walk(self, visitor):
|
|
512
|
-
return visitor._visit(self, def():
|
|
582
|
+
return visitor._visit(self, def ():
|
|
513
583
|
walk_body(self, visitor)
|
|
514
584
|
if self.bcatch:
|
|
515
585
|
self.bcatch._walk(visitor)
|
|
516
|
-
|
|
517
586
|
if self.belse:
|
|
518
587
|
self.belse._walk(visitor)
|
|
519
|
-
|
|
520
588
|
if self.bfinally:
|
|
521
589
|
self.bfinally._walk(visitor)
|
|
522
590
|
)
|
|
523
591
|
|
|
592
|
+
|
|
524
593
|
class AST_Catch(AST_Block):
|
|
525
|
-
|
|
594
|
+
'A `catch` node; only makes sense as part of a `try` statement'
|
|
595
|
+
|
|
526
596
|
|
|
527
597
|
class AST_Except(AST_Block):
|
|
528
|
-
|
|
598
|
+
'An `except` node for RapydScript, which resides inside the catch block'
|
|
529
599
|
properties = {
|
|
530
|
-
'argname':
|
|
531
|
-
'errors':
|
|
600
|
+
'argname': '[AST_SymbolCatch] symbol for the exception',
|
|
601
|
+
'errors': '[AST_SymbolVar*] error classes to catch in this block'
|
|
532
602
|
}
|
|
533
603
|
|
|
534
604
|
def _walk(self, visitor):
|
|
535
|
-
return visitor._visit(this, def():
|
|
605
|
+
return visitor._visit(this, def ():
|
|
536
606
|
if (self.argname):
|
|
537
607
|
self.argname.walk(visitor)
|
|
538
608
|
if (self.errors):
|
|
@@ -540,39 +610,44 @@ class AST_Except(AST_Block):
|
|
|
540
610
|
walk_body(self, visitor)
|
|
541
611
|
)
|
|
542
612
|
|
|
613
|
+
|
|
543
614
|
class AST_Finally(AST_Block):
|
|
544
|
-
|
|
615
|
+
'A `finally` node; only makes sense as part of a `try` statement'
|
|
616
|
+
|
|
545
617
|
|
|
546
618
|
class AST_Else(AST_Block):
|
|
547
619
|
'An `else` node; only makes sense as part of `try` statement'
|
|
548
620
|
|
|
549
621
|
# }}}
|
|
550
622
|
|
|
623
|
+
|
|
551
624
|
# VAR/CONST {{{
|
|
552
625
|
class AST_Definitions(AST_Statement):
|
|
553
|
-
|
|
626
|
+
'Base class for `var` or `const` nodes (variable declarations/initializations)'
|
|
554
627
|
properties = {
|
|
555
|
-
'definitions':
|
|
628
|
+
'definitions': '[AST_VarDef*] array of variable definitions'
|
|
556
629
|
}
|
|
557
630
|
|
|
558
631
|
def _walk(self, visitor):
|
|
559
|
-
return visitor._visit(self, def():
|
|
632
|
+
return visitor._visit(self, def ():
|
|
560
633
|
for def_ in self.definitions:
|
|
561
634
|
def_._walk(visitor)
|
|
562
635
|
)
|
|
563
636
|
|
|
637
|
+
|
|
564
638
|
class AST_Var(AST_Definitions):
|
|
565
|
-
|
|
639
|
+
'A `var` statement'
|
|
640
|
+
|
|
566
641
|
|
|
567
642
|
class AST_VarDef(AST_Node):
|
|
568
|
-
|
|
643
|
+
'A variable declaration; only appears in a AST_Definitions node'
|
|
569
644
|
properties = {
|
|
570
|
-
'name':
|
|
645
|
+
'name': '[AST_SymbolVar|AST_SymbolNonlocal] name of the variable',
|
|
571
646
|
'value': "[AST_Node?] initializer, or null if there's no initializer"
|
|
572
647
|
}
|
|
573
648
|
|
|
574
649
|
def _walk(self, visitor):
|
|
575
|
-
return visitor._visit(self, def():
|
|
650
|
+
return visitor._visit(self, def ():
|
|
576
651
|
self.name._walk(visitor)
|
|
577
652
|
if self.value:
|
|
578
653
|
self.value._walk(visitor)
|
|
@@ -581,61 +656,87 @@ class AST_VarDef(AST_Node):
|
|
|
581
656
|
|
|
582
657
|
# Miscellaneous {{{
|
|
583
658
|
|
|
584
|
-
|
|
585
|
-
|
|
659
|
+
|
|
660
|
+
class AST_CallArg(AST_Node):
|
|
661
|
+
'A single positional argument in a function call'
|
|
586
662
|
properties = {
|
|
587
|
-
'
|
|
663
|
+
'value': '[AST_Node] the argument expression',
|
|
664
|
+
'is_array': '[bool] True if this is a *arg (already an array/iterable)',
|
|
588
665
|
}
|
|
589
666
|
|
|
590
|
-
|
|
591
|
-
|
|
667
|
+
def _walk(self, visitor):
|
|
668
|
+
return visitor._visit(self, def ():
|
|
669
|
+
self.value._walk(visitor)
|
|
670
|
+
)
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
class AST_CallArgs(AST_Node):
|
|
674
|
+
'The argument list for a function call'
|
|
592
675
|
properties = {
|
|
593
|
-
'
|
|
676
|
+
'args': '[AST_CallArg*] positional arguments',
|
|
677
|
+
'kwargs': '[pair*] keyword argument pairs [key_node, value_node]',
|
|
678
|
+
'kwarg_items': '[AST_SymbolRef*] **kwargs symbol references',
|
|
679
|
+
'starargs': '[bool] True if *args were used in this call',
|
|
594
680
|
}
|
|
595
681
|
|
|
596
682
|
def _walk(self, visitor):
|
|
597
|
-
return visitor._visit(self, def():
|
|
598
|
-
self.expression._walk(visitor)
|
|
683
|
+
return visitor._visit(self, def ():
|
|
599
684
|
for arg in self.args:
|
|
600
685
|
arg._walk(visitor)
|
|
601
|
-
if self.
|
|
602
|
-
for
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
if self.
|
|
606
|
-
for arg in self.
|
|
686
|
+
if self.kwargs:
|
|
687
|
+
for pair in self.kwargs:
|
|
688
|
+
pair[0]._walk(visitor)
|
|
689
|
+
pair[1]._walk(visitor)
|
|
690
|
+
if self.kwarg_items:
|
|
691
|
+
for arg in self.kwarg_items:
|
|
607
692
|
arg._walk(visitor)
|
|
608
693
|
)
|
|
609
694
|
|
|
610
695
|
|
|
696
|
+
class AST_BaseCall(AST_Node):
|
|
697
|
+
'A base class for function calls'
|
|
698
|
+
properties = {
|
|
699
|
+
'args': '[AST_CallArgs] the function call argument list'
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
class AST_Call(AST_BaseCall):
|
|
704
|
+
'A function call expression'
|
|
705
|
+
properties = {
|
|
706
|
+
'expression': '[AST_Node] expression to invoke as function'
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
def _walk(self, visitor):
|
|
710
|
+
return visitor._visit(self, def ():
|
|
711
|
+
self.expression._walk(visitor)
|
|
712
|
+
self.args._walk(visitor)
|
|
713
|
+
)
|
|
714
|
+
|
|
715
|
+
|
|
611
716
|
class AST_ClassCall(AST_BaseCall):
|
|
612
|
-
|
|
717
|
+
'A function call expression'
|
|
613
718
|
properties = {
|
|
614
|
-
|
|
615
|
-
'method':
|
|
616
|
-
|
|
719
|
+
'class': '[string] name of the class method belongs to',
|
|
720
|
+
'method': '[string] class method being called',
|
|
721
|
+
'static': '[boolean] defines whether the method is static'
|
|
617
722
|
}
|
|
618
723
|
|
|
619
724
|
def _walk(self, visitor):
|
|
620
|
-
return visitor._visit(self, def():
|
|
725
|
+
return visitor._visit(self, def ():
|
|
621
726
|
if (self.expression) self.expression._walk(visitor)
|
|
622
|
-
|
|
623
|
-
arg._walk(visitor)
|
|
624
|
-
for arg in self.args.kwargs:
|
|
625
|
-
arg[0]._walk(visitor)
|
|
626
|
-
arg[1]._walk(visitor)
|
|
627
|
-
for arg in self.args.kwarg_items:
|
|
628
|
-
arg._walk(visitor)
|
|
727
|
+
self.args._walk(visitor)
|
|
629
728
|
)
|
|
630
729
|
|
|
730
|
+
|
|
631
731
|
class AST_New(AST_Call):
|
|
632
|
-
|
|
732
|
+
'An object instantiation. Derives from a function call since it has exactly the same properties'
|
|
733
|
+
|
|
633
734
|
|
|
634
735
|
class AST_Seq(AST_Node):
|
|
635
|
-
|
|
736
|
+
'A sequence expression (two comma-separated expressions)'
|
|
636
737
|
properties = {
|
|
637
|
-
'car':
|
|
638
|
-
'cdr':
|
|
738
|
+
'car': '[AST_Node] first element in sequence',
|
|
739
|
+
'cdr': '[AST_Node] second element in sequence'
|
|
639
740
|
}
|
|
640
741
|
|
|
641
742
|
def to_array(self):
|
|
@@ -658,7 +759,7 @@ class AST_Seq(AST_Node):
|
|
|
658
759
|
p = p.cdr
|
|
659
760
|
|
|
660
761
|
def _walk(self, visitor):
|
|
661
|
-
return visitor._visit(self, def():
|
|
762
|
+
return visitor._visit(self, def ():
|
|
662
763
|
self.car._walk(visitor)
|
|
663
764
|
if self.cdr:
|
|
664
765
|
self.cdr._walk(visitor)
|
|
@@ -680,7 +781,7 @@ class AST_Seq(AST_Node):
|
|
|
680
781
|
return array[0].clone()
|
|
681
782
|
|
|
682
783
|
ans = None
|
|
683
|
-
for i in range(array.length-1, -1, -1):
|
|
784
|
+
for i in range(array.length - 1, -1, -1):
|
|
684
785
|
ans = AST_Seq.cons(array[i], ans)
|
|
685
786
|
|
|
686
787
|
p = ans
|
|
@@ -691,120 +792,131 @@ class AST_Seq(AST_Node):
|
|
|
691
792
|
p = p.cdr
|
|
692
793
|
return ans
|
|
693
794
|
|
|
795
|
+
|
|
694
796
|
class AST_PropAccess(AST_Node):
|
|
695
797
|
'Base class for property access expressions, i.e. `a.foo` or `a["foo"]`'
|
|
696
798
|
properties = {
|
|
697
|
-
'expression':
|
|
799
|
+
'expression': '[AST_Node] the “container” expression',
|
|
698
800
|
'property': "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
|
|
699
801
|
}
|
|
700
802
|
|
|
803
|
+
|
|
701
804
|
class AST_Dot(AST_PropAccess):
|
|
702
|
-
|
|
805
|
+
'A dotted property access expression'
|
|
703
806
|
|
|
704
807
|
def _walk(self, visitor):
|
|
705
|
-
return visitor._visit(self, def():
|
|
808
|
+
return visitor._visit(self, def ():
|
|
706
809
|
self.expression._walk(visitor)
|
|
707
810
|
)
|
|
708
811
|
|
|
812
|
+
|
|
709
813
|
class AST_Sub(AST_PropAccess):
|
|
710
814
|
'Index-style property access, i.e. `a["foo"]`'
|
|
711
815
|
|
|
712
816
|
def _walk(self, visitor):
|
|
713
|
-
return visitor._visit(self, def():
|
|
817
|
+
return visitor._visit(self, def ():
|
|
714
818
|
self.expression._walk(visitor)
|
|
715
819
|
self.property._walk(visitor)
|
|
716
820
|
)
|
|
717
821
|
|
|
822
|
+
|
|
718
823
|
class AST_ItemAccess(AST_PropAccess):
|
|
719
824
|
'Python index-style property access, i.e. `a.__getitem__("foo")`'
|
|
720
825
|
properties = {
|
|
721
|
-
'assignment':
|
|
722
|
-
'assign_operator':
|
|
826
|
+
'assignment': '[AST_Node or None] Not None if this is an assignment (a[x] = y) rather than a simple access',
|
|
827
|
+
'assign_operator': '[String] The operator for a assignment like += or empty string if plain assignment',
|
|
723
828
|
}
|
|
724
829
|
|
|
725
830
|
def _walk(self, visitor):
|
|
726
|
-
return visitor._visit(self, def():
|
|
831
|
+
return visitor._visit(self, def ():
|
|
727
832
|
self.expression._walk(visitor)
|
|
728
833
|
self.property._walk(visitor)
|
|
729
834
|
if self.assignment:
|
|
730
835
|
self.assignment._walk(visitor)
|
|
731
836
|
)
|
|
732
837
|
|
|
838
|
+
|
|
733
839
|
class AST_Splice(AST_PropAccess):
|
|
734
840
|
'Index-style property access, i.e. `a[3:5]`'
|
|
735
841
|
properties = {
|
|
736
|
-
'property2':
|
|
737
|
-
'assignment':
|
|
842
|
+
'property2': '[AST_Node] the 2nd property to access - typically ending index for the array.',
|
|
843
|
+
'assignment': '[AST_Node] The data being spliced in.'
|
|
738
844
|
}
|
|
739
845
|
|
|
740
846
|
def _walk(self, visitor):
|
|
741
|
-
return visitor._visit(self, def():
|
|
847
|
+
return visitor._visit(self, def ():
|
|
742
848
|
self.expression._walk(visitor)
|
|
743
849
|
self.property._walk(visitor)
|
|
744
850
|
self.property2._walk(visitor)
|
|
745
851
|
)
|
|
746
852
|
|
|
853
|
+
|
|
747
854
|
class AST_Unary(AST_Node):
|
|
748
|
-
|
|
855
|
+
'Base class for unary expressions'
|
|
749
856
|
properties = {
|
|
750
|
-
'operator':
|
|
751
|
-
'expression':
|
|
752
|
-
'parenthesized':
|
|
857
|
+
'operator': '[string] the operator',
|
|
858
|
+
'expression': '[AST_Node] expression that this unary operator applies to',
|
|
859
|
+
'parenthesized': '[bool] Whether this unary expression was parenthesized',
|
|
753
860
|
}
|
|
754
861
|
|
|
755
862
|
def _walk(self, visitor):
|
|
756
|
-
return visitor._visit(self, def():
|
|
863
|
+
return visitor._visit(self, def ():
|
|
757
864
|
self.expression._walk(visitor)
|
|
758
865
|
)
|
|
759
866
|
|
|
867
|
+
|
|
760
868
|
class AST_UnaryPrefix(AST_Unary):
|
|
761
|
-
|
|
869
|
+
'Unary prefix expression, i.e. `typeof i` or `del i`'
|
|
870
|
+
|
|
762
871
|
|
|
763
872
|
class AST_Binary(AST_Node):
|
|
764
|
-
|
|
873
|
+
'Binary expression, i.e. `a + b`'
|
|
765
874
|
properties = {
|
|
766
|
-
'left':
|
|
767
|
-
'operator':
|
|
768
|
-
'right':
|
|
875
|
+
'left': '[AST_Node] left-hand side expression',
|
|
876
|
+
'operator': '[string] the operator',
|
|
877
|
+
'right': '[AST_Node] right-hand side expression'
|
|
769
878
|
}
|
|
770
879
|
|
|
771
880
|
def _walk(self, visitor):
|
|
772
|
-
return visitor._visit(self, def():
|
|
881
|
+
return visitor._visit(self, def ():
|
|
773
882
|
self.left._walk(visitor)
|
|
774
883
|
self.right._walk(visitor)
|
|
775
884
|
)
|
|
776
885
|
|
|
886
|
+
|
|
777
887
|
class AST_Existential(AST_Node):
|
|
778
|
-
|
|
888
|
+
'Existential operator a?'
|
|
779
889
|
properties = {
|
|
780
|
-
'expression':
|
|
781
|
-
|
|
890
|
+
'expression': '[AST_Node] The expression whose existence we need to check',
|
|
891
|
+
'after': '[None|string|AST_Node] is None when there is nothing following this operator, is a string when there is as AST_PropAccess following this operator, is an AST_Node if it is used a a shorthand for the conditional ternary, i.e. a ? b == a if a? else b',
|
|
782
892
|
}
|
|
783
893
|
|
|
784
894
|
def _walk(self, visitor):
|
|
785
|
-
return visitor._visit(self, def():
|
|
895
|
+
return visitor._visit(self, def ():
|
|
786
896
|
self.expression._walk(visitor)
|
|
787
897
|
if self.after is not None and jstype(self.after) is 'object':
|
|
788
898
|
self.after._walk(visitor)
|
|
789
899
|
)
|
|
790
900
|
|
|
901
|
+
|
|
791
902
|
class AST_Conditional(AST_Node):
|
|
792
|
-
|
|
903
|
+
'Conditional expression using the ternary operator, i.e. `a if b else c`'
|
|
793
904
|
properties = {
|
|
794
|
-
'condition':
|
|
795
|
-
'consequent':
|
|
796
|
-
'alternative':
|
|
905
|
+
'condition': '[AST_Node]',
|
|
906
|
+
'consequent': '[AST_Node]',
|
|
907
|
+
'alternative': '[AST_Node]',
|
|
797
908
|
}
|
|
798
909
|
|
|
799
910
|
def _walk(self, visitor):
|
|
800
|
-
return visitor._visit(self, def():
|
|
911
|
+
return visitor._visit(self, def ():
|
|
801
912
|
self.condition._walk(visitor)
|
|
802
913
|
self.consequent._walk(visitor)
|
|
803
914
|
self.alternative._walk(visitor)
|
|
804
915
|
)
|
|
805
916
|
|
|
917
|
+
|
|
806
918
|
class AST_Assign(AST_Binary):
|
|
807
|
-
|
|
919
|
+
'An assignment expression — `a = b + 5`'
|
|
808
920
|
|
|
809
921
|
def is_chained(self):
|
|
810
922
|
return is_node_type(self.right, AST_Assign) or (
|
|
@@ -820,7 +932,7 @@ class AST_Assign(AST_Binary):
|
|
|
820
932
|
continue
|
|
821
933
|
if is_node_type(right, AST_Seq):
|
|
822
934
|
if is_node_type(right.car, AST_Assign):
|
|
823
|
-
right = new AST_Seq({'car':right.car.right, 'cdr': right.cdr})
|
|
935
|
+
right = new AST_Seq({'car': right.car.right, 'cdr': right.cdr})
|
|
824
936
|
continue
|
|
825
937
|
if is_node_type(right.cdr, AST_Assign):
|
|
826
938
|
right = right.cdr.right
|
|
@@ -836,7 +948,7 @@ class AST_Assign(AST_Binary):
|
|
|
836
948
|
if is_node_type(next, AST_Seq):
|
|
837
949
|
if is_node_type(next.cdr, AST_Assign):
|
|
838
950
|
assign = next.cdr
|
|
839
|
-
left_hand_sides.push(new AST_Seq({'car':next.car, 'cdr':assign.left}))
|
|
951
|
+
left_hand_sides.push(new AST_Seq({'car': next.car, 'cdr': assign.left}))
|
|
840
952
|
next = assign.right
|
|
841
953
|
continue
|
|
842
954
|
break
|
|
@@ -847,14 +959,15 @@ class AST_Assign(AST_Binary):
|
|
|
847
959
|
|
|
848
960
|
# LITERALS {{{
|
|
849
961
|
|
|
962
|
+
|
|
850
963
|
class AST_Array(AST_Node):
|
|
851
|
-
|
|
964
|
+
'An array literal'
|
|
852
965
|
properties = {
|
|
853
|
-
'elements':
|
|
966
|
+
'elements': '[AST_Node*] array of elements'
|
|
854
967
|
}
|
|
855
968
|
|
|
856
969
|
def _walk(self, visitor):
|
|
857
|
-
return visitor._visit(self, def():
|
|
970
|
+
return visitor._visit(self, def ():
|
|
858
971
|
for el in self.elements:
|
|
859
972
|
el._walk(visitor)
|
|
860
973
|
)
|
|
@@ -874,194 +987,227 @@ class AST_Array(AST_Node):
|
|
|
874
987
|
return ans
|
|
875
988
|
return flatten(self.elements)
|
|
876
989
|
|
|
990
|
+
|
|
877
991
|
class AST_Object(AST_Node):
|
|
878
|
-
|
|
992
|
+
'An object literal'
|
|
879
993
|
properties = {
|
|
880
|
-
'properties':
|
|
881
|
-
'is_pydict':
|
|
882
|
-
'is_jshash':
|
|
994
|
+
'properties': '[AST_ObjectProperty*] array of properties',
|
|
995
|
+
'is_pydict': '[bool] True if this object is a python dict literal',
|
|
996
|
+
'is_jshash': '[bool] True if this object is a js hash literal',
|
|
883
997
|
}
|
|
884
998
|
|
|
885
999
|
def _walk(self, visitor):
|
|
886
|
-
return visitor._visit(self, def():
|
|
1000
|
+
return visitor._visit(self, def ():
|
|
887
1001
|
for prop in self.properties:
|
|
888
1002
|
prop._walk(visitor)
|
|
889
1003
|
)
|
|
890
1004
|
|
|
1005
|
+
|
|
891
1006
|
class AST_ExpressiveObject(AST_Object):
|
|
892
1007
|
'An object literal with expressions for some keys'
|
|
893
1008
|
|
|
1009
|
+
|
|
894
1010
|
class AST_ObjectProperty(AST_Node):
|
|
895
|
-
|
|
1011
|
+
'Base class for literal object properties'
|
|
896
1012
|
properties = {
|
|
897
|
-
'key':
|
|
898
|
-
'value':
|
|
1013
|
+
'key': '[AST_Node] the property expression',
|
|
1014
|
+
'value': '[AST_Node] property value. For setters and getters this is an AST_Function.',
|
|
899
1015
|
'quoted': '',
|
|
900
1016
|
}
|
|
901
1017
|
|
|
902
1018
|
def _walk(self, visitor):
|
|
903
|
-
return visitor._visit(self, def():
|
|
1019
|
+
return visitor._visit(self, def ():
|
|
904
1020
|
self.key._walk(visitor)
|
|
905
1021
|
self.value._walk(visitor)
|
|
906
1022
|
)
|
|
907
1023
|
|
|
1024
|
+
|
|
908
1025
|
class AST_ObjectKeyVal(AST_ObjectProperty):
|
|
909
|
-
|
|
1026
|
+
'A key: value object property'
|
|
1027
|
+
|
|
910
1028
|
|
|
911
1029
|
class AST_Set(AST_Node):
|
|
912
|
-
|
|
1030
|
+
'A set literal'
|
|
913
1031
|
properties = {
|
|
914
|
-
'items':
|
|
1032
|
+
'items': '[AST_SetItem*] array of items'
|
|
915
1033
|
}
|
|
916
1034
|
|
|
917
1035
|
def _walk(self, visitor):
|
|
918
|
-
return visitor._visit(self, def():
|
|
1036
|
+
return visitor._visit(self, def ():
|
|
919
1037
|
for prop in self.items:
|
|
920
1038
|
prop._walk(visitor)
|
|
921
1039
|
)
|
|
922
1040
|
|
|
1041
|
+
|
|
923
1042
|
class AST_SetItem(AST_Node):
|
|
924
|
-
|
|
1043
|
+
'An item in a set literal'
|
|
925
1044
|
properties = {
|
|
926
|
-
'value':
|
|
1045
|
+
'value': '[AST_Node] The value of this item',
|
|
927
1046
|
}
|
|
928
1047
|
|
|
929
1048
|
def _walk(self, visitor):
|
|
930
|
-
return visitor._visit(self, def():
|
|
1049
|
+
return visitor._visit(self, def ():
|
|
931
1050
|
self.value._walk(visitor)
|
|
932
1051
|
)
|
|
933
1052
|
|
|
1053
|
+
|
|
934
1054
|
class AST_Symbol(AST_Node):
|
|
935
|
-
|
|
1055
|
+
'Base class for all symbols'
|
|
936
1056
|
properties = {
|
|
937
|
-
'name':
|
|
938
|
-
'scope':
|
|
939
|
-
'thedef':
|
|
1057
|
+
'name': '[string] name of this symbol',
|
|
1058
|
+
'scope': '[AST_Scope/S] the current scope (not necessarily the definition scope)',
|
|
1059
|
+
'thedef': '[SymbolDef/S] the definition of this symbol'
|
|
940
1060
|
}
|
|
941
1061
|
|
|
1062
|
+
|
|
942
1063
|
class AST_SymbolAlias(AST_Symbol):
|
|
943
|
-
|
|
1064
|
+
'An alias used in an import statement or with statement'
|
|
1065
|
+
|
|
944
1066
|
|
|
945
1067
|
class AST_SymbolDeclaration(AST_Symbol):
|
|
946
|
-
|
|
1068
|
+
'A declaration symbol (symbol in var/const, function name or argument, symbol in catch)'
|
|
947
1069
|
properties = {
|
|
948
|
-
'init':
|
|
1070
|
+
'init': '[AST_Node*/S] array of initializers for this declaration.'
|
|
949
1071
|
}
|
|
950
1072
|
|
|
1073
|
+
|
|
951
1074
|
class AST_SymbolVar(AST_SymbolDeclaration):
|
|
952
|
-
|
|
1075
|
+
'Symbol defining a variable'
|
|
1076
|
+
|
|
953
1077
|
|
|
954
1078
|
class AST_ImportedVar(AST_SymbolVar):
|
|
955
|
-
|
|
1079
|
+
'Symbol defining an imported symbol'
|
|
956
1080
|
properties = {
|
|
957
|
-
'alias':
|
|
1081
|
+
'alias': 'AST_SymbolAlias the alias for this imported symbol'
|
|
958
1082
|
}
|
|
959
1083
|
|
|
1084
|
+
|
|
960
1085
|
class AST_SymbolNonlocal(AST_SymbolDeclaration):
|
|
961
|
-
|
|
1086
|
+
'A nonlocal declaration'
|
|
1087
|
+
|
|
962
1088
|
|
|
963
1089
|
class AST_SymbolFunarg(AST_SymbolVar):
|
|
964
|
-
|
|
1090
|
+
'Symbol naming a function argument, possibly with an annotation.'
|
|
965
1091
|
properties = {
|
|
966
|
-
'annotation':
|
|
1092
|
+
'annotation': '[AST_Node?] The annotation provided for this argument (if any)'
|
|
967
1093
|
}
|
|
968
1094
|
|
|
1095
|
+
|
|
969
1096
|
class AST_SymbolDefun(AST_SymbolDeclaration):
|
|
970
|
-
|
|
1097
|
+
'Symbol defining a function'
|
|
1098
|
+
|
|
971
1099
|
|
|
972
1100
|
class AST_SymbolLambda(AST_SymbolDeclaration):
|
|
973
|
-
|
|
1101
|
+
'Symbol naming a function expression'
|
|
1102
|
+
|
|
974
1103
|
|
|
975
1104
|
class AST_SymbolCatch(AST_SymbolDeclaration):
|
|
976
|
-
|
|
1105
|
+
'Symbol naming the exception in catch'
|
|
1106
|
+
|
|
977
1107
|
|
|
978
1108
|
class AST_SymbolRef(AST_Symbol):
|
|
979
|
-
|
|
1109
|
+
'Reference to some symbol (not definition/declaration)'
|
|
980
1110
|
properties = {
|
|
981
|
-
'parens':
|
|
1111
|
+
'parens': '[boolean/S] if true, this variable is wrapped in parentheses'
|
|
982
1112
|
}
|
|
983
1113
|
|
|
1114
|
+
|
|
984
1115
|
class AST_This(AST_Symbol):
|
|
985
|
-
|
|
1116
|
+
'The `this` symbol'
|
|
1117
|
+
|
|
986
1118
|
|
|
987
1119
|
class AST_Constant(AST_Node):
|
|
988
|
-
|
|
1120
|
+
'Base class for all constants'
|
|
1121
|
+
|
|
989
1122
|
|
|
990
1123
|
class AST_String(AST_Constant):
|
|
991
|
-
|
|
1124
|
+
'A string literal'
|
|
992
1125
|
properties = {
|
|
993
|
-
'value':
|
|
1126
|
+
'value': '[string] the contents of this string'
|
|
994
1127
|
}
|
|
995
1128
|
|
|
1129
|
+
|
|
996
1130
|
class AST_Verbatim(AST_Constant):
|
|
997
|
-
|
|
1131
|
+
'Raw JavaScript code'
|
|
998
1132
|
properties = {
|
|
999
|
-
'value':
|
|
1133
|
+
'value': '[string] A string of raw JS code'
|
|
1000
1134
|
}
|
|
1001
1135
|
|
|
1136
|
+
|
|
1002
1137
|
class AST_Number(AST_Constant):
|
|
1003
|
-
|
|
1138
|
+
'A number literal'
|
|
1004
1139
|
properties = {
|
|
1005
|
-
'value':
|
|
1140
|
+
'value': '[number] the numeric value'
|
|
1006
1141
|
}
|
|
1007
1142
|
|
|
1143
|
+
|
|
1008
1144
|
class AST_RegExp(AST_Constant):
|
|
1009
|
-
|
|
1145
|
+
'A regexp literal'
|
|
1010
1146
|
properties = {
|
|
1011
|
-
'value':
|
|
1147
|
+
'value': '[RegExp] the actual regexp'
|
|
1012
1148
|
}
|
|
1013
1149
|
|
|
1150
|
+
|
|
1014
1151
|
class AST_Atom(AST_Constant):
|
|
1015
|
-
|
|
1152
|
+
'Base class for atoms'
|
|
1153
|
+
|
|
1016
1154
|
def __init__(self, initializer):
|
|
1017
1155
|
if initializer:
|
|
1018
1156
|
self.start = initializer.start
|
|
1019
1157
|
self.end = initializer.end
|
|
1020
1158
|
|
|
1159
|
+
|
|
1021
1160
|
class AST_Null(AST_Atom):
|
|
1022
|
-
|
|
1161
|
+
'The `null` atom'
|
|
1023
1162
|
value = None
|
|
1024
1163
|
|
|
1164
|
+
|
|
1025
1165
|
class AST_NaN(AST_Atom):
|
|
1026
|
-
|
|
1166
|
+
'The impossible value'
|
|
1027
1167
|
value = v'NaN'
|
|
1028
1168
|
|
|
1169
|
+
|
|
1029
1170
|
class AST_Undefined(AST_Atom):
|
|
1030
|
-
|
|
1171
|
+
'The `undefined` value'
|
|
1031
1172
|
value = v'undefined'
|
|
1032
1173
|
|
|
1174
|
+
|
|
1033
1175
|
class AST_Hole(AST_Atom):
|
|
1034
|
-
|
|
1176
|
+
'A hole in an array'
|
|
1035
1177
|
value = v'undefined'
|
|
1036
1178
|
|
|
1179
|
+
|
|
1037
1180
|
class AST_Infinity(AST_Atom):
|
|
1038
|
-
|
|
1181
|
+
'The `Infinity` value'
|
|
1039
1182
|
value = v'Infinity'
|
|
1040
1183
|
|
|
1184
|
+
|
|
1041
1185
|
class AST_Boolean(AST_Atom):
|
|
1042
|
-
|
|
1186
|
+
'Base class for booleans'
|
|
1187
|
+
|
|
1043
1188
|
|
|
1044
1189
|
class AST_False(AST_Boolean):
|
|
1045
|
-
|
|
1190
|
+
'The `false` atom'
|
|
1046
1191
|
value = False
|
|
1047
1192
|
|
|
1193
|
+
|
|
1048
1194
|
class AST_True(AST_Boolean):
|
|
1049
|
-
|
|
1195
|
+
'The `true` atom'
|
|
1050
1196
|
value = True
|
|
1051
1197
|
|
|
1052
1198
|
# }}}
|
|
1053
1199
|
|
|
1054
1200
|
# TreeWalker {{{
|
|
1055
1201
|
|
|
1056
|
-
class TreeWalker:
|
|
1057
1202
|
|
|
1203
|
+
class TreeWalker:
|
|
1058
1204
|
def __init__(self, callback):
|
|
1059
1205
|
self.visit = callback
|
|
1060
1206
|
self.stack = []
|
|
1061
1207
|
|
|
1062
1208
|
def _visit(self, node, descend):
|
|
1063
1209
|
self.stack.push(node)
|
|
1064
|
-
ret = self.visit(node, ((def(): descend.call(node);) if descend else noop))
|
|
1210
|
+
ret = self.visit(node, ((def (): descend.call(node);) if descend else noop))
|
|
1065
1211
|
if not ret and descend:
|
|
1066
1212
|
descend.call(node)
|
|
1067
1213
|
|
|
@@ -1082,7 +1228,7 @@ class TreeWalker:
|
|
|
1082
1228
|
|
|
1083
1229
|
def find_parent(self, type):
|
|
1084
1230
|
stack = self.stack
|
|
1085
|
-
for i in range(stack.length-1, -1, -1):
|
|
1231
|
+
for i in range(stack.length - 1, -1, -1):
|
|
1086
1232
|
x = stack[i]
|
|
1087
1233
|
if is_node_type(x, type):
|
|
1088
1234
|
return x
|
|
@@ -1096,16 +1242,18 @@ class TreeWalker:
|
|
|
1096
1242
|
if is_node_type(p, AST_If) and p.condition is self
|
|
1097
1243
|
or is_node_type(p, AST_Conditional) and p.condition is self
|
|
1098
1244
|
or is_node_type(p, AST_DWLoop) and p.condition is self
|
|
1099
|
-
or is_node_type(p, AST_UnaryPrefix) and p.operator is
|
|
1245
|
+
or is_node_type(p, AST_UnaryPrefix) and p.operator is '!' and p.expression is self:
|
|
1100
1246
|
return True
|
|
1101
|
-
if not (is_node_type(p, AST_Binary) and (p.operator is
|
|
1247
|
+
if not (is_node_type(p, AST_Binary) and (p.operator is '&&' or p.operator is '||')):
|
|
1102
1248
|
return False
|
|
1103
1249
|
self = p
|
|
1104
1250
|
# }}}
|
|
1105
1251
|
|
|
1252
|
+
|
|
1106
1253
|
class Found(Exception):
|
|
1107
1254
|
pass
|
|
1108
1255
|
|
|
1256
|
+
|
|
1109
1257
|
def has_calls(expression):
|
|
1110
1258
|
# Technically, in JavaScript property access is also dynamic and can
|
|
1111
1259
|
# involve function calls. However, there is no way to determine which
|
|
@@ -1114,7 +1262,7 @@ def has_calls(expression):
|
|
|
1114
1262
|
if not expression:
|
|
1115
1263
|
return False
|
|
1116
1264
|
try:
|
|
1117
|
-
expression.walk(new TreeWalker(def(node):
|
|
1265
|
+
expression.walk(new TreeWalker(def (node):
|
|
1118
1266
|
if is_node_type(node, AST_BaseCall) or is_node_type(node, AST_ItemAccess):
|
|
1119
1267
|
raise Found()
|
|
1120
1268
|
))
|