Coverage Report

Created: 2026-01-09 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/sources/xsScope.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016-2017  Moddable Tech, Inc.
3
 *
4
 *   This file is part of the Moddable SDK Runtime.
5
 * 
6
 *   The Moddable SDK Runtime is free software: you can redistribute it and/or modify
7
 *   it under the terms of the GNU Lesser General Public License as published by
8
 *   the Free Software Foundation, either version 3 of the License, or
9
 *   (at your option) any later version.
10
 * 
11
 *   The Moddable SDK Runtime is distributed in the hope that it will be useful,
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *   GNU Lesser General Public License for more details.
15
 * 
16
 *   You should have received a copy of the GNU Lesser General Public License
17
 *   along with the Moddable SDK Runtime.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * This file incorporates work covered by the following copyright and  
20
 * permission notice:  
21
 *
22
 *       Copyright (C) 2010-2016 Marvell International Ltd.
23
 *       Copyright (C) 2002-2010 Kinoma, Inc.
24
 *
25
 *       Licensed under the Apache License, Version 2.0 (the "License");
26
 *       you may not use this file except in compliance with the License.
27
 *       You may obtain a copy of the License at
28
 *
29
 *        http://www.apache.org/licenses/LICENSE-2.0
30
 *
31
 *       Unless required by applicable law or agreed to in writing, software
32
 *       distributed under the License is distributed on an "AS IS" BASIS,
33
 *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34
 *       See the License for the specific language governing permissions and
35
 *       limitations under the License.
36
 */
37
38
#include "xsScript.h"
39
40
#define mxBindHoistPart\
41
  txParser* parser;\
42
  txScope* scope
43
44
typedef struct sxExportlink txExportLink;
45
46
typedef struct {
47
  mxBindHoistPart;
48
  txInteger scopeLevel;
49
  txInteger scopeMaximum;
50
  txClassNode* classNode;
51
} txBinder;
52
53
typedef struct {
54
  mxBindHoistPart;
55
  txScope* functionScope;
56
  txScope* bodyScope;
57
  txNode* environmentNode;
58
  txExportLink* firstExportLink;
59
  txClassNode* classNode;
60
} txHoister;
61
62
struct sxExportlink {
63
  txExportLink* next;
64
  txSymbol* symbol;
65
};
66
67
static void fxHoisterAddExportLink(txHoister* self, txSpecifierNode* specifier);
68
static void fxBinderPopVariables(txBinder* self, txInteger count);
69
static void fxBinderPushVariables(txBinder* self, txInteger count);
70
static txScope* fxScopeNew(txHoister* hoister, txNode* node, txToken token);
71
static void fxScopeAddDeclareNode(txScope* self, txDeclareNode* node);
72
static void fxScopeAddDefineNode(txScope* self, txDefineNode* node);
73
static void fxScopeArrow(txScope* self);
74
static void fxScopeBindDefineNodes(txScope* self, void* param);
75
static void fxScopeBinding(txScope* self, txBinder* binder);
76
static void fxScopeBound(txScope* self, txBinder* binder);
77
static void fxScopeEval(txScope* self);
78
static txDeclareNode* fxScopeGetDeclareNode(txScope* self, txSymbol* symbol);
79
static void fxScopeHoisted(txScope* self, txHoister* hoister);
80
static void fxScopeLookup(txScope* self, txAccessNode* access, txBoolean closureFlag);
81
82
static void fxNodeDispatchBind(void* it, void* param);
83
static void fxNodeDispatchHoist(void* it, void* param);
84
static void fxFunctionNodeRename(void* it, txSymbol* symbol);
85
86
void fxParserBind(txParser* parser)
87
0
{
88
0
  txBinder binder;
89
0
  c_memset(&binder, 0, sizeof(txBinder));
90
0
  binder.parser = parser;
91
0
  if (parser->errorCount == 0) {
92
0
    mxTryParser(parser) {
93
0
      fxNodeDispatchBind(parser->root, &binder);
94
0
    }
95
0
    mxCatchParser(parser) {
96
0
    }
97
0
  }
98
0
}
99
100
void fxParserHoist(txParser* parser)
101
0
{
102
0
  txHoister hoister;
103
0
  c_memset(&hoister, 0, sizeof(txHoister));
104
0
  hoister.parser = parser;
105
0
  if (parser->errorCount == 0) {
106
0
    mxTryParser(parser) {
107
0
      fxNodeDispatchHoist(parser->root, &hoister);
108
0
    }
109
0
    mxCatchParser(parser) {
110
0
    }
111
0
  }
112
0
}
113
114
void fxHoisterAddExportLink(txHoister* self, txSpecifierNode* specifier)
115
0
{
116
0
  txExportLink* link = self->firstExportLink;
117
0
  txSymbol* symbol = specifier->asSymbol ? specifier->asSymbol : specifier->symbol;
118
0
    if (symbol) {
119
0
        while (link) {
120
0
            if (link->symbol == symbol) {
121
0
                fxReportParserError(self->parser, specifier->line, "duplicate export %s", symbol->string);
122
0
                return;
123
0
            }
124
0
            link = link->next;
125
0
        }
126
0
        link = fxNewParserChunk(self->parser, sizeof(txExportLink));
127
0
        link->next = self->firstExportLink;
128
0
        link->symbol = symbol;
129
0
        self->firstExportLink = link;
130
0
    }
131
0
}
132
133
void fxBinderPopVariables(txBinder* self, txInteger count)
134
0
{
135
0
  self->scopeLevel -= count;
136
0
}
137
138
void fxBinderPushVariables(txBinder* self, txInteger count)
139
0
{
140
0
  self->scopeLevel += count;
141
0
  if (self->scopeMaximum < self->scopeLevel)
142
0
    self->scopeMaximum = self->scopeLevel;
143
0
}
144
145
txScope* fxScopeNew(txHoister* hoister, txNode* node, txToken token) 
146
0
{
147
0
  txScope* scope = fxNewParserChunkClear(hoister->parser, sizeof(txScope));
148
0
  scope->parser = hoister->parser;
149
0
  scope->scope = hoister->scope;
150
0
  scope->token = token;
151
0
  scope->flags = node->flags & mxStrictFlag;
152
0
  scope->node = node;
153
0
  hoister->scope = scope;
154
0
  return scope;
155
0
}
156
157
void fxScopeAddDeclareNode(txScope* self, txDeclareNode* node) 
158
0
{
159
0
  self->declareNodeCount++;
160
0
  if (self->token == XS_TOKEN_EVAL) {
161
0
    if (self->lastDeclareNode)
162
0
      node->nextDeclareNode = self->firstDeclareNode;
163
0
    else
164
0
      self->lastDeclareNode = node;
165
0
    self->firstDeclareNode = node;
166
0
  }
167
0
  else {
168
0
    if (self->lastDeclareNode)
169
0
      self->lastDeclareNode->nextDeclareNode = node;
170
0
    else
171
0
      self->firstDeclareNode = node;
172
0
    self->lastDeclareNode = node;
173
0
  }
174
0
  if (node->description->token == XS_TOKEN_USING) {
175
0
    txDeclareNode* node = fxDeclareNodeNew(self->parser, XS_TOKEN_CONST, C_NULL);
176
0
    node->flags |= mxDeclareNodeDisposableFlag;
177
0
    fxScopeAddDeclareNode(self, node);
178
0
    self->disposableNodeCount++;
179
0
  }
180
0
}
181
182
void fxScopeAddDefineNode(txScope* self, txDefineNode* node) 
183
0
{
184
0
  self->defineNodeCount++;
185
0
  if (self->lastDefineNode)
186
0
    self->lastDefineNode->nextDefineNode = node;
187
0
  else
188
0
    self->firstDefineNode = node;
189
0
  self->lastDefineNode = node;
190
0
}
191
192
void fxScopeArrow(txScope* self)
193
0
{
194
0
  if (self->token == XS_TOKEN_EVAL) {
195
0
  }
196
0
  else if (self->token == XS_TOKEN_FUNCTION) {
197
0
    if (self->node->flags & mxArrowFlag) {
198
0
      self->node->flags |= mxDefaultFlag;
199
0
      if (self->scope)
200
0
        fxScopeArrow(self->scope);
201
0
    }
202
0
  }
203
0
  else if (self->token == XS_TOKEN_PROGRAM) {
204
0
  }
205
0
  else if (self->scope) {
206
0
    fxScopeArrow(self->scope);
207
0
  }
208
0
}
209
210
void fxScopeBindDefineNodes(txScope* self, void* param) 
211
0
{
212
0
  txDefineNode* node = self->firstDefineNode;
213
0
  while (node) {
214
0
    fxNodeDispatchBind(node, param);
215
0
    node = node->nextDefineNode;
216
0
  }
217
0
}
218
219
void fxScopeBinding(txScope* self, txBinder* binder) 
220
0
{
221
0
  self->scope = binder->scope;
222
0
  binder->scope = self;
223
0
  fxBinderPushVariables(binder, self->declareNodeCount);
224
0
}
225
226
void fxScopeBound(txScope* self, txBinder* binder) 
227
0
{
228
0
  if (self->flags & mxEvalFlag) {
229
0
    txDeclareNode* node = self->firstDeclareNode;
230
0
    while (node) {
231
0
      node->flags |= mxDeclareNodeClosureFlag;
232
0
      node = node->nextDeclareNode;
233
0
    }
234
0
  }
235
0
  if (self->token == XS_TOKEN_MODULE) {
236
0
    txDeclareNode* node = self->firstDeclareNode;
237
0
    while (node) {
238
0
      if (!(node->flags & mxDeclareNodeDisposableFlag))
239
0
        node->flags |= mxDeclareNodeClosureFlag |  mxDeclareNodeUseClosureFlag;
240
0
      node = node->nextDeclareNode;
241
0
    }
242
0
  }
243
0
  else if (self->token == XS_TOKEN_PROGRAM) {
244
0
    txDeclareNode* node = self->firstDeclareNode;
245
0
    while (node) {
246
0
      node->flags |= mxDeclareNodeClosureFlag |  mxDeclareNodeUseClosureFlag;
247
0
      node = node->nextDeclareNode;
248
0
    }
249
0
  }
250
0
  binder->scopeLevel += self->closureNodeCount;
251
0
  binder->scopeMaximum += self->closureNodeCount;
252
0
  fxBinderPopVariables(binder, self->declareNodeCount);
253
0
  binder->scope = self->scope;
254
0
}
255
256
void fxScopeEval(txScope* self) 
257
0
{
258
0
  while (self) {
259
0
    self->flags |= mxEvalFlag;
260
0
    self = self->scope;
261
0
  }
262
0
}
263
264
txDeclareNode* fxScopeGetDeclareNode(txScope* self, txSymbol* symbol) 
265
0
{
266
0
  txDeclareNode* node = self->firstDeclareNode;
267
0
  while (node) {
268
0
    if (node->symbol == symbol)
269
0
      return node;
270
0
    node = node->nextDeclareNode;
271
0
  }
272
0
  return NULL;
273
0
}
274
275
void fxScopeHoisted(txScope* self, txHoister* hoister) 
276
0
{
277
0
  if (self->token == XS_TOKEN_BLOCK) {
278
0
    txDeclareNode** address = &self->firstDeclareNode;
279
0
    txDeclareNode* node;
280
0
    txDeclareNode* last = C_NULL;
281
0
    while ((node = *address)) {
282
0
      if (node->description->token == XS_NO_TOKEN) {
283
0
        self->declareNodeCount--;
284
0
        *address = node->nextDeclareNode;
285
0
      }
286
0
      else {
287
0
        address = &node->nextDeclareNode;
288
0
        last = node;
289
0
      }
290
0
    }
291
0
    self->lastDeclareNode = last;
292
0
  }
293
0
  else if (self->token == XS_TOKEN_PROGRAM) {
294
0
    txDeclareNode* node = self->firstDeclareNode;
295
0
    while (node) {
296
0
      if ((node->description->token == XS_TOKEN_DEFINE) || (node->description->token == XS_TOKEN_VAR))
297
0
        self->declareNodeCount--;
298
0
      node = node->nextDeclareNode;
299
0
    }
300
0
  }
301
0
  else if (self->token == XS_TOKEN_EVAL) {
302
0
    if (!(self->flags & mxStrictFlag)) {
303
0
      txDeclareNode* node = self->firstDeclareNode;
304
0
      while (node) {
305
0
        if ((node->description->token == XS_TOKEN_DEFINE) || (node->description->token == XS_TOKEN_VAR))
306
0
          self->declareNodeCount--;
307
0
        node = node->nextDeclareNode;
308
0
      }
309
0
    }
310
0
  }
311
0
  hoister->scope = self->scope;
312
0
}
313
314
void fxScopeLookup(txScope* self, txAccessNode* access, txBoolean closureFlag) 
315
0
{
316
0
  txDeclareNode* declaration;
317
0
  if (self->token == XS_TOKEN_EVAL) {
318
0
    declaration = fxScopeGetDeclareNode(self, access->symbol);
319
0
    if (declaration) {
320
0
      if ((!(self->flags & mxStrictFlag)) && ((declaration->description->token == XS_TOKEN_VAR) || (declaration->description->token == XS_TOKEN_DEFINE))) {
321
0
        declaration = C_NULL;
322
0
      }
323
0
      else if (closureFlag)
324
0
        declaration->flags |= mxDeclareNodeClosureFlag;
325
0
    }
326
0
    else if ((self->flags & mxStrictFlag) && (access->description->token == XS_TOKEN_PRIVATE_MEMBER)) {
327
0
      declaration = fxDeclareNodeNew(self->parser, XS_TOKEN_PRIVATE, access->symbol);
328
0
      declaration->flags |= mxDeclareNodeClosureFlag;
329
0
      declaration->line = access->line;
330
0
      fxScopeAddDeclareNode(self, declaration);
331
0
      self->closureNodeCount++;
332
0
    }
333
0
    access->declaration = declaration;
334
0
  }
335
0
  else if (self->token == XS_TOKEN_FUNCTION) {
336
0
    declaration = fxScopeGetDeclareNode(self, access->symbol);
337
0
    if (declaration) {
338
0
      if (closureFlag)
339
0
        declaration->flags |= mxDeclareNodeClosureFlag;
340
0
      access->declaration = declaration;
341
0
    }
342
0
    else if ((self->node->flags & mxEvalFlag) && !(self->node->flags & mxStrictFlag)) {
343
      // eval can create variables that override closures 
344
0
      access->declaration = C_NULL;
345
0
    }
346
0
    else if (self->scope) {
347
0
      fxScopeLookup(self->scope, access, 1);
348
0
      if (access->declaration) {
349
0
        txDeclareNode* closureNode = fxDeclareNodeNew(self->parser, XS_NO_TOKEN, access->symbol);
350
0
        closureNode->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag;
351
0
        closureNode->line = access->declaration->line;
352
0
        closureNode->declaration = access->declaration;
353
0
        fxScopeAddDeclareNode(self, closureNode);
354
0
        self->closureNodeCount++;
355
0
        access->declaration = closureNode;
356
0
      }
357
0
    }
358
0
  }
359
0
  else if (self->token == XS_TOKEN_PROGRAM) {
360
0
    declaration = fxScopeGetDeclareNode(self, access->symbol);
361
0
    if (declaration && ((declaration->description->token == XS_TOKEN_VAR) || (declaration->description->token == XS_TOKEN_DEFINE))) {
362
0
      declaration = C_NULL;
363
0
    }
364
0
    access->declaration = declaration;
365
0
  }
366
0
  else if (self->token == XS_TOKEN_WITH) {
367
    // with object can have properties that override variables 
368
0
    access->declaration = C_NULL;
369
0
  }
370
0
  else {
371
0
    declaration = fxScopeGetDeclareNode(self, access->symbol);
372
0
    if (declaration) {
373
0
      if (closureFlag)
374
0
        declaration->flags |= mxDeclareNodeClosureFlag;
375
0
      access->declaration = declaration;
376
0
    }
377
0
    else if (self->scope) {
378
0
      fxScopeLookup(self->scope, access, closureFlag);
379
0
    }
380
0
    else {
381
0
      access->declaration = C_NULL;
382
0
      access->symbol->usage |= 2;
383
0
    }
384
0
  }
385
0
}
386
387
void fxNodeHoist(void* it, void* param) 
388
0
{
389
0
  txNode* node = it;
390
0
  (*node->description->dispatch->distribute)(node, fxNodeDispatchHoist, param);
391
0
}
392
393
void fxNodeDispatchHoist(void* it, void* param)
394
0
{
395
0
  txNode* node = it;
396
0
  fxCheckParserStack(((txHoister*)param)->parser, node->line);
397
0
  (*node->description->dispatch->hoist)(it, param);
398
0
}
399
400
void fxBlockNodeHoist(void* it, void* param) 
401
0
{
402
0
  txBlockNode* self = it;
403
0
  self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK);
404
0
  fxNodeDispatchHoist(self->statement, param);
405
0
  fxScopeHoisted(self->scope, param);
406
0
}
407
408
void fxBodyNodeHoist(void* it, void* param) 
409
0
{
410
0
  txBlockNode* self = it;
411
0
  txHoister* hoister = param;
412
0
  txNode* environmentNode = hoister->environmentNode;
413
0
  hoister->bodyScope = self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK);
414
0
  hoister->environmentNode = it;
415
0
  fxNodeDispatchHoist(self->statement, param);
416
0
  hoister->environmentNode = environmentNode;
417
0
  fxScopeHoisted(self->scope, param);
418
0
}
419
420
void fxCallNodeHoist(void* it, void* param) 
421
0
{
422
0
  txCallNewNode* self = it;
423
0
  txHoister* hoister = param;
424
0
  txParser* parser = hoister->parser;
425
0
  if (self->reference->description->token == XS_TOKEN_ACCESS) {
426
0
    txAccessNode* access = (txAccessNode*)self->reference;
427
0
    if (access->symbol == parser->evalSymbol) {
428
0
      fxScopeEval(hoister->scope);
429
0
      hoister->functionScope->node->flags |= mxArgumentsFlag | mxEvalFlag;
430
0
      hoister->environmentNode->flags |= mxEvalFlag;
431
0
      self->params->flags |= mxEvalParametersFlag;
432
0
    }
433
0
  }
434
0
  fxNodeDispatchHoist(self->reference, param);
435
0
  fxNodeDispatchHoist(self->params, param);
436
0
}
437
438
void fxCatchNodeHoist(void* it, void* param) 
439
0
{
440
0
  txCatchNode* self = it;
441
0
  txHoister* hoister = param;
442
0
  txDeclareNode* node;
443
0
  if (self->parameter) {
444
0
    self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK);
445
0
    fxNodeDispatchHoist(self->parameter, param);
446
0
    self->statementScope = fxScopeNew(param, it, XS_TOKEN_BLOCK);
447
0
    fxNodeDispatchHoist(self->statement, param);
448
0
    fxScopeHoisted(self->statementScope, param);
449
0
    fxScopeHoisted(self->scope, param);
450
0
    node = self->statementScope->firstDeclareNode;
451
0
    while (node) {
452
0
       if (fxScopeGetDeclareNode(self->scope, node->symbol))
453
0
         fxReportParserError(hoister->parser, node->line, "duplicate variable %s", node->symbol->string);
454
0
       node = node->nextDeclareNode;
455
0
    }
456
0
  }
457
0
  else {
458
0
    self->statementScope = fxScopeNew(param, it, XS_TOKEN_BLOCK);
459
0
    fxNodeDispatchHoist(self->statement, param);
460
0
    fxScopeHoisted(self->statementScope, param);
461
0
  }
462
0
}
463
464
void fxClassNodeHoist(void* it, void* param) 
465
0
{
466
0
  txClassNode* self = it;
467
0
  txHoister* hoister = param;
468
0
  txClassNode* former = hoister->classNode;
469
0
  txNode* item = self->items->first;
470
0
  if (self->symbol) {
471
0
    txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, self->symbol);
472
0
    node->flags |= mxDeclareNodeClosureFlag;
473
0
    self->symbolScope = fxScopeNew(hoister, it, XS_TOKEN_BLOCK);
474
0
    fxScopeAddDeclareNode(self->symbolScope, node);
475
0
  }
476
0
  if (self->heritage)
477
0
    fxNodeDispatchHoist(self->heritage, param);
478
0
  self->scope = fxScopeNew(hoister, it, XS_TOKEN_BLOCK);
479
0
  while (item) {
480
0
    if (item->description->token == XS_TOKEN_PROPERTY) {
481
0
    }
482
0
    else if (item->description->token == XS_TOKEN_PROPERTY_AT) {
483
0
      if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
484
0
      }
485
0
      else {
486
0
        txSymbol* symbol = fxNewParserChunkClear(hoister->parser, sizeof(txSymbol));
487
0
        txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol);
488
0
        symbol->ID = -1;
489
0
        node->flags |= mxDeclareNodeClosureFlag;
490
0
        fxScopeAddDeclareNode(self->scope, node);
491
0
        ((txPropertyAtNode*)item)->atAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol);
492
0
      }
493
0
    }
494
0
    else {
495
0
      txSymbol* symbol = ((txPrivatePropertyNode*)item)->symbol;
496
0
      txDeclareNode* node = fxScopeGetDeclareNode(self->scope, symbol);
497
0
      if (node) {
498
0
                txUnsigned flags = (node->flags & (mxStaticFlag | mxGetterFlag | mxSetterFlag)) ^ (item->flags & (mxStaticFlag | mxGetterFlag | mxSetterFlag));
499
0
        if ((flags != (mxGetterFlag | mxSetterFlag)))
500
0
          fxReportParserError(hoister->parser, item->line, "duplicate %s", symbol->string);
501
0
      }
502
0
      node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol);
503
0
      node->flags |= mxDeclareNodeClosureFlag | (item->flags & (mxStaticFlag | mxGetterFlag | mxSetterFlag));
504
0
      fxScopeAddDeclareNode(self->scope, node);
505
0
      ((txPrivatePropertyNode*)item)->symbolAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol);
506
0
      if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
507
0
        txSymbol* symbol = fxNewParserChunkClear(hoister->parser, sizeof(txSymbol));
508
0
        txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol);
509
0
        symbol->ID = -1;
510
0
        node->flags |= mxDeclareNodeClosureFlag;
511
0
        fxScopeAddDeclareNode(self->scope, node);
512
0
        ((txPrivatePropertyNode*)item)->valueAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol);
513
0
      }
514
0
    }
515
0
    item = item->next;
516
0
  }
517
0
  if (self->instanceInit) {
518
0
    txSymbol* symbol = fxNewParserChunkClear(hoister->parser, sizeof(txSymbol));
519
0
    txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_CONST, symbol);
520
0
    symbol->ID = -1;
521
0
    node->flags |= mxDeclareNodeClosureFlag;
522
0
    fxScopeAddDeclareNode(self->scope, node);
523
0
    self->instanceInitAccess = fxAccessNodeNew(hoister->parser, XS_TOKEN_ACCESS, symbol);
524
0
  }
525
0
  hoister->classNode = self;
526
0
  fxNodeDispatchHoist(self->constructor, param);
527
0
  fxNodeListDistribute(self->items, fxNodeDispatchHoist, param);
528
0
  if (self->constructorInit)
529
0
    fxNodeDispatchHoist(self->constructorInit, param);
530
0
  if (self->instanceInit)
531
0
    fxNodeDispatchHoist(self->instanceInit, param);
532
0
  hoister->classNode = former;
533
0
  fxScopeHoisted(self->scope, param);
534
0
  if (self->symbol)
535
0
    fxScopeHoisted(self->symbolScope, param);
536
0
}
537
538
void fxCoalesceExpressionNodeHoist(void* it, void* param) 
539
0
{
540
0
  txBinaryExpressionNode* self = it;
541
0
  txHoister* hoister = param;
542
0
  txToken leftToken = self->left->description->token;
543
0
  txToken rightToken = self->right->description->token;
544
0
  if ((leftToken == XS_TOKEN_AND) || (rightToken == XS_TOKEN_AND))
545
0
    fxReportParserError(hoister->parser, self->line, "missing () around &&");
546
0
  else if ((leftToken == XS_TOKEN_OR) || (rightToken == XS_TOKEN_OR))
547
0
    fxReportParserError(hoister->parser, self->line, "missing () around ||");
548
0
  fxNodeDispatchHoist(self->left, param);
549
0
  fxNodeDispatchHoist(self->right, param);
550
0
}
551
552
void fxDeclareNodeHoist(void* it, void* param) 
553
0
{
554
0
  txDeclareNode* self = it;
555
0
  txHoister* hoister = param;
556
0
  txDeclareNode* node;
557
0
  txScope* scope;
558
0
  if (self->description->token == XS_TOKEN_ARG) {
559
0
    node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol);
560
0
    if (node) {
561
0
      if ((node->description->token == XS_TOKEN_ARG) && (hoister->functionScope->node->flags & (mxArrowFlag | mxAsyncFlag | mxMethodFlag | mxNotSimpleParametersFlag | mxStrictFlag)))
562
0
        fxReportParserError(hoister->parser, self->line, "duplicate argument %s", self->symbol->string);
563
0
    }
564
0
    else {
565
0
      fxScopeAddDeclareNode(hoister->functionScope, self);
566
0
    }
567
0
  }
568
0
  else if ((self->description->token == XS_TOKEN_CONST) || (self->description->token == XS_TOKEN_LET) || (self->description->token == XS_TOKEN_USING)) {
569
0
    node = fxScopeGetDeclareNode(hoister->scope, self->symbol);
570
0
    if (!node && (hoister->scope == hoister->bodyScope)) {
571
0
      node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol);
572
0
      if (node && (node->description->token != XS_TOKEN_ARG))
573
0
        node = C_NULL;
574
0
    }
575
0
    if (node)
576
0
      fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string);
577
0
    else
578
0
      fxScopeAddDeclareNode(hoister->scope, self);
579
0
  }
580
0
  else {
581
0
    scope = hoister->scope;
582
0
    node = C_NULL;
583
0
    while (scope != hoister->bodyScope) {
584
0
      node = fxScopeGetDeclareNode(scope, self->symbol);
585
0
      if (node) {
586
0
        if ((node->description->token == XS_TOKEN_CONST) || (node->description->token == XS_TOKEN_LET) || (node->description->token == XS_TOKEN_USING) || (node->description->token == XS_TOKEN_DEFINE))
587
0
          break;
588
0
        node = C_NULL;
589
0
      }
590
0
      scope = scope->scope;
591
0
    }
592
0
    if (!node) {
593
0
      node = fxScopeGetDeclareNode(scope, self->symbol);
594
0
      if (node) {
595
0
        if ((node->description->token != XS_TOKEN_CONST) && (node->description->token != XS_TOKEN_LET) && (node->description->token != XS_TOKEN_USING))
596
0
          node = C_NULL;
597
0
      }
598
0
    }
599
0
    if (node)
600
0
      fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string);
601
0
    else {
602
0
      node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol);
603
0
      if (!node || ((node->description->token != XS_TOKEN_ARG) && (node->description->token != XS_TOKEN_VAR)))
604
0
        fxScopeAddDeclareNode(hoister->bodyScope, self);
605
0
      scope = hoister->scope;
606
0
      while (scope != hoister->bodyScope) {
607
0
        fxScopeAddDeclareNode(scope, fxDeclareNodeNew(hoister->parser, XS_NO_TOKEN, self->symbol));
608
0
        scope = scope->scope;
609
0
      }
610
0
    }
611
0
  }
612
0
}
613
614
void fxDefineNodeHoist(void* it, void* param) 
615
0
{
616
0
  txDefineNode* self = it;
617
0
  txHoister* hoister = param;
618
0
  txDeclareNode* node;
619
0
  if (self->flags & mxStrictFlag) {
620
0
    if ((self->symbol == hoister->parser->argumentsSymbol) || (self->symbol == hoister->parser->evalSymbol) || (self->symbol == hoister->parser->yieldSymbol))
621
0
      fxReportParserError(hoister->parser, self->line, "invalid definition %s", self->symbol->string);
622
0
  }
623
0
  if ((hoister->scope == hoister->bodyScope) && (hoister->scope->token != XS_TOKEN_MODULE)) {
624
0
    node = fxScopeGetDeclareNode(hoister->bodyScope, self->symbol);
625
0
    if (node) {
626
0
      if ((node->description->token == XS_TOKEN_CONST) || (node->description->token == XS_TOKEN_LET))
627
0
        fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string);
628
0
    }
629
0
    else {
630
0
      if (hoister->functionScope != hoister->bodyScope)
631
0
        node = fxScopeGetDeclareNode(hoister->functionScope, self->symbol);
632
0
      if (!node)
633
0
        fxScopeAddDeclareNode(hoister->bodyScope, (txDeclareNode*)self);
634
0
    }
635
0
    fxScopeAddDefineNode(hoister->bodyScope, self);
636
0
  }
637
0
  else {
638
0
    node = fxScopeGetDeclareNode(hoister->scope, self->symbol);
639
0
    if (node)
640
0
      fxReportParserError(hoister->parser, self->line, "duplicate variable %s", self->symbol->string);
641
0
    else
642
0
      fxScopeAddDeclareNode(hoister->scope, (txDeclareNode*)self);
643
0
    fxScopeAddDefineNode(hoister->scope, self);
644
0
  }
645
0
  ((txFunctionNode*)(self->initializer))->symbol = C_NULL;
646
0
  fxNodeDispatchHoist(self->initializer, param);
647
0
  ((txFunctionNode*)(self->initializer))->symbol = self->symbol;
648
0
}
649
650
void fxExportNodeHoist(void* it, void* param)
651
0
{
652
0
  txExportNode* self = it;
653
0
  txHoister* hoister = param;
654
0
  if (self->from) {
655
0
    if (self->specifiers && self->specifiers->length) {
656
0
      txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first;
657
0
      while (specifier) {
658
0
        txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, C_NULL);
659
0
        specifier->from = self->from;
660
0
        specifier->with = self->with;
661
0
        node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag;
662
0
        node->line = self->line;
663
0
        node->importSpecifier = specifier;
664
0
        node->firstExportSpecifier = specifier;
665
0
        fxScopeAddDeclareNode(hoister->scope, node);
666
0
        specifier = (txSpecifierNode*)specifier->next;
667
0
      }
668
0
    }
669
0
    else {
670
0
      txSpecifierNode* specifier = fxSpecifierNodeNew(hoister->parser, XS_TOKEN_SPECIFIER);
671
0
      txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, C_NULL);
672
0
      specifier->from = self->from;
673
0
      specifier->with = self->with;
674
0
      node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag;
675
0
      node->line = self->line;
676
0
      node->importSpecifier = specifier;
677
0
      node->firstExportSpecifier = C_NULL;
678
0
      fxScopeAddDeclareNode(hoister->scope, node);
679
0
    }
680
0
  }
681
0
  if (self->specifiers && self->specifiers->length) {
682
0
    txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first;
683
0
    while (specifier) {
684
0
      fxHoisterAddExportLink(hoister, specifier);
685
0
      fxNodeDispatchHoist(specifier, param);
686
0
      specifier = (txSpecifierNode*)specifier->next;
687
0
    }
688
0
  }
689
0
}
690
691
void fxForNodeHoist(void* it, void* param) 
692
0
{
693
0
  txForNode* self = it;
694
0
  self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK);
695
0
  if (self->initialization)
696
0
    fxNodeDispatchHoist(self->initialization, param);
697
0
  if (self->expression)
698
0
    fxNodeDispatchHoist(self->expression, param);
699
0
  if (self->iteration)
700
0
    fxNodeDispatchHoist(self->iteration, param);
701
0
  fxNodeDispatchHoist(self->statement, param);
702
0
  fxScopeHoisted(self->scope, param);
703
0
}
704
705
void fxForInForOfNodeHoist(void* it, void* param) 
706
0
{
707
0
  txForInForOfNode* self = it;
708
0
  self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK);
709
0
  fxNodeDispatchHoist(self->reference, param);
710
0
  fxNodeDispatchHoist(self->expression, param);
711
0
  fxNodeDispatchHoist(self->statement, param);
712
0
  fxScopeHoisted(self->scope, param);
713
0
}
714
715
void fxFunctionNodeHoist(void* it, void* param) 
716
0
{
717
0
  txFunctionNode* self = it;
718
0
  txHoister* hoister = param;
719
0
  txScope* functionScope = hoister->functionScope;
720
0
  txScope* bodyScope = hoister->bodyScope;
721
0
  hoister->functionScope = self->scope = fxScopeNew(param, it, XS_TOKEN_FUNCTION);
722
0
  hoister->bodyScope = C_NULL;
723
0
  if (self->symbol) {
724
0
    txDefineNode* node = fxDefineNodeNew(hoister->parser, XS_TOKEN_CONST, self->symbol);
725
0
    node->initializer = fxValueNodeNew(hoister->parser, XS_TOKEN_CURRENT);
726
0
    fxScopeAddDeclareNode(hoister->functionScope, (txDeclareNode*)node);
727
0
    fxScopeAddDefineNode(hoister->functionScope, node);
728
0
  }
729
0
  fxNodeDispatchHoist(self->params, param);
730
0
  if ((self->flags & (mxArgumentsFlag | mxEvalFlag)) && !(self->flags & mxArrowFlag)) {
731
0
    txDeclareNode* declaration = fxDeclareNodeNew(hoister->parser, XS_TOKEN_VAR, hoister->parser->argumentsSymbol);
732
0
    fxScopeAddDeclareNode(hoister->functionScope, declaration);
733
0
  }  
734
0
  fxNodeDispatchHoist(self->body, param);
735
0
  fxScopeHoisted(self->scope, param);
736
0
  hoister->bodyScope = bodyScope;
737
0
  hoister->functionScope = functionScope;
738
0
}
739
740
txHostNode* fxHostNodeClone(txParser* parser, txHostNode* self)
741
0
{
742
0
  txHostNode* node = fxNewParserChunkClear(parser, sizeof(txHostNode));
743
0
  c_memcpy(node, self, sizeof(txHostNode));
744
0
  return node;
745
0
}
746
747
void fxHostNodeHoist(void* it, void* param) 
748
0
{
749
0
  txHostNode* self = it;
750
0
  txHoister* hoister = param;
751
0
  txScope* scope = hoister->bodyScope;
752
0
  self->hostIndex = -1;
753
0
  if ((scope->token != XS_TOKEN_MODULE) && (scope->token != XS_TOKEN_PROGRAM)) {
754
0
    txParser* parser = hoister->parser;
755
0
    while ((scope->token != XS_TOKEN_MODULE) && (scope->token != XS_TOKEN_PROGRAM))
756
0
      scope = scope->scope;
757
0
    snprintf(parser->buffer, parser->bufferSize, "@%s", self->at->value);
758
0
    txSymbol* symbol = fxNewParserSymbol(parser, parser->buffer);
759
0
    if (!fxScopeGetDeclareNode(scope, symbol)) {
760
0
      txDefineNode* definition = fxDefineNodeNew(parser, XS_TOKEN_DEFINE, symbol);
761
0
      definition->initializer = (txNode*)fxHostNodeClone(parser, self);
762
0
      fxScopeAddDeclareNode(scope, (txDeclareNode*)definition);
763
0
      fxScopeAddDefineNode(scope, definition);
764
0
    }
765
0
    txAccessNode* access = it;
766
0
    access->description = &gxTokenDescriptions[XS_TOKEN_ACCESS];
767
0
    access->symbol = symbol;
768
0
    access->initializer = C_NULL;
769
0
    access->declaration = C_NULL;
770
0
  }
771
0
}
772
773
void fxImportNodeHoist(void* it, void* param) 
774
0
{
775
0
  txImportNode* self = it;
776
0
  txHoister* hoister = param;
777
0
  if (self->specifiers && self->specifiers->length) {
778
0
    txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first;
779
0
    while (specifier) {
780
0
      txDeclareNode* node;
781
0
      txSymbol* symbol = specifier->asSymbol ? specifier->asSymbol : specifier->symbol;
782
0
      if (self->flags & mxStrictFlag) {
783
0
        if ((symbol == hoister->parser->argumentsSymbol) || (symbol == hoister->parser->evalSymbol))
784
0
          fxReportParserError(hoister->parser, self->line, "invalid import %s", symbol->string);
785
0
      }
786
0
      node = fxScopeGetDeclareNode(hoister->scope, symbol);
787
0
      if (node)
788
0
        fxReportParserError(hoister->parser, self->line, "duplicate variable %s", symbol->string);
789
0
      else {
790
0
        specifier->declaration = node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, symbol);
791
0
        specifier->from = self->from;
792
0
        specifier->with = self->with;
793
0
        node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag;
794
0
        node->line = self->line;
795
0
        node->importSpecifier = specifier;
796
0
        fxScopeAddDeclareNode(hoister->scope, node);
797
0
      }
798
0
      specifier = (txSpecifierNode*)specifier->next;
799
0
    }
800
0
  }
801
0
  else {
802
0
    txSpecifierNode* specifier = fxSpecifierNodeNew(hoister->parser, XS_TOKEN_SPECIFIER);
803
0
    txDeclareNode* node = fxDeclareNodeNew(hoister->parser, XS_TOKEN_LET, C_NULL);
804
0
    specifier->from = self->from;
805
0
    specifier->with = self->with;
806
0
    node->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag;
807
0
    node->line = self->line;
808
0
    node->importSpecifier = specifier;
809
0
    fxScopeAddDeclareNode(hoister->scope, node);
810
0
  }
811
0
}
812
813
void fxModuleNodeHoist(void* it, void* param) 
814
0
{
815
0
  txModuleNode* self = it;
816
0
  txHoister* hoister = param;
817
0
  hoister->functionScope = hoister->bodyScope = self->scope = fxScopeNew(param, it, XS_TOKEN_MODULE); // @@
818
0
  hoister->environmentNode = it;
819
0
  fxNodeDispatchHoist(self->body, param);
820
0
  hoister->environmentNode = C_NULL;
821
0
  fxScopeHoisted(self->scope, param);
822
0
}
823
824
void fxParamsBindingNodeHoist(void* it, void* param)
825
0
{
826
0
  txParamsNode* self = it;
827
0
  txNode* item = self->items->first;
828
0
  while (item) {
829
0
    fxNodeDispatchHoist(item, param);
830
0
    item = item->next;
831
0
  }
832
0
}
833
834
void fxProgramNodeHoist(void* it, void* param) 
835
0
{
836
0
  txProgramNode* self = it;
837
0
  txHoister* hoister = param;
838
0
  hoister->functionScope = hoister->bodyScope = self->scope = fxScopeNew(param, it, (hoister->parser->flags & mxEvalFlag) ? XS_TOKEN_EVAL : XS_TOKEN_PROGRAM);
839
0
  hoister->environmentNode = it;
840
0
  fxNodeDispatchHoist(self->body, param);
841
0
  hoister->environmentNode = C_NULL;
842
0
  self->variableCount = hoister->functionScope->declareNodeCount;
843
0
  fxScopeHoisted(self->scope, param);
844
0
}
845
846
void fxStatementNodeHoist(void* it, void* param) 
847
0
{
848
0
  txStatementNode* self = it;
849
0
  fxNodeDispatchHoist(self->expression, param);
850
0
}
851
852
void fxPropertyNodeHoist(void* it, void* param) 
853
0
{
854
0
  txPropertyNode* self = it;
855
0
  if (self->value) {
856
0
    if (self->value->description->token == XS_TOKEN_HOST)
857
0
      ((txHostNode*)(self->value))->symbol = self->symbol;
858
0
    fxNodeDispatchHoist(self->value, param);
859
0
  }
860
0
}
861
862
void fxStringNodeHoist(void* it, void* param)
863
0
{
864
0
  txStringNode* self = it;
865
0
  txHoister* hoister = param;
866
0
  if ((self->flags & mxStringLegacyFlag) && (hoister->scope->flags & mxStrictFlag))
867
0
    self->flags |= mxStringErrorFlag;
868
0
}
869
870
void fxSwitchNodeHoist(void* it, void* param) 
871
0
{
872
0
  txSwitchNode* self = it;
873
0
  fxNodeDispatchHoist(self->expression, param);
874
0
  self->scope = fxScopeNew(param, it, XS_TOKEN_BLOCK);
875
0
  fxNodeListDistribute(self->items, fxNodeDispatchHoist, param);
876
0
  fxScopeHoisted(self->scope, param);
877
0
}
878
879
void fxWithNodeHoist(void* it, void* param) 
880
0
{
881
0
  txWithNode* self = it;
882
0
  txHoister* hoister = param;
883
0
  fxNodeDispatchHoist(self->expression, param);
884
0
  self->scope = fxScopeNew(param, it, XS_TOKEN_WITH);
885
0
  fxScopeEval(hoister->scope);
886
0
  fxNodeDispatchHoist(self->statement, param);
887
0
  fxScopeHoisted(self->scope, param);
888
0
}
889
890
void fxNodeDispatchBind(void* it, void* param)
891
0
{
892
0
  txNode* node = it;
893
0
  fxCheckParserStack(((txBinder*)param)->parser, node->line);
894
0
  (*node->description->dispatch->bind)(it, param);
895
0
}
896
897
void fxNodeBind(void* it, void* param) 
898
0
{
899
0
  txNode* node = it;
900
0
  (*node->description->dispatch->distribute)(node, fxNodeDispatchBind, param);
901
0
}
902
903
void fxAccessNodeBind(void* it, void* param) 
904
0
{
905
0
  txAccessNode* self = it;
906
0
  txBinder* binder = param;
907
0
  fxScopeLookup(binder->scope, (txAccessNode*)self, 0);
908
0
}
909
910
void fxArrayNodeBind(void* it, void* param) 
911
0
{
912
0
  txArrayNode* self = it;
913
0
  fxBinderPushVariables(param, 1);
914
0
  if (self->flags & mxSpreadFlag) {
915
0
    fxBinderPushVariables(param, 2);
916
0
    fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
917
0
    fxBinderPopVariables(param, 2);
918
0
  }
919
0
  else
920
0
    fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
921
0
  fxBinderPopVariables(param, 1);
922
0
}
923
924
void fxArrayBindingNodeBind(void* it, void* param) 
925
0
{
926
0
  txArrayBindingNode* self = it;
927
0
  fxBinderPushVariables(param, 6);
928
0
  fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
929
0
  fxBinderPopVariables(param, 6);
930
0
}
931
932
void fxAssignNodeBind(void* it, void* param) 
933
0
{
934
0
  txAssignNode* self = it;
935
0
  txToken token = self->reference->description->token;
936
0
  fxNodeDispatchBind(self->reference, param);
937
0
  if ((token == XS_TOKEN_ACCESS) || (token == XS_TOKEN_ARG) || (token == XS_TOKEN_CONST) || (token == XS_TOKEN_LET) || (token == XS_TOKEN_USING) || (token == XS_TOKEN_VAR))
938
0
    fxFunctionNodeRename(self->value, ((txAccessNode*)self->reference)->symbol);
939
0
  fxNodeDispatchBind(self->value, param);
940
0
}
941
942
void fxBindingNodeBind(void* it, void* param) 
943
0
{
944
0
  txBindingNode* self = it;
945
0
  txToken token = self->target->description->token;
946
0
  fxNodeDispatchBind(self->target, param);
947
0
  if ((token == XS_TOKEN_ACCESS) || (token == XS_TOKEN_ARG) || (token == XS_TOKEN_CONST) || (token == XS_TOKEN_LET) || (token == XS_TOKEN_USING) || (token == XS_TOKEN_VAR))
948
0
    fxFunctionNodeRename(self->initializer, ((txAccessNode*)self->target)->symbol);
949
0
  fxNodeDispatchBind(self->initializer, param);
950
0
}
951
952
void fxBlockNodeBind(void* it, void* param) 
953
0
{
954
0
  txBlockNode* self = it;
955
0
  fxScopeBinding(self->scope, param);
956
0
  fxScopeBindDefineNodes(self->scope, param);
957
0
  if (self->scope->disposableNodeCount)
958
0
    fxBinderPushVariables(param, 2);
959
0
  fxNodeDispatchBind(self->statement, param);
960
0
  if (self->scope->disposableNodeCount)
961
0
    fxBinderPopVariables(param, 2);
962
0
  fxScopeBound(self->scope, param);
963
0
}
964
965
void fxCatchNodeBind(void* it, void* param) 
966
0
{
967
0
  txCatchNode* self = it;
968
0
  if (self->parameter) {
969
0
    fxScopeBinding(self->scope, param);
970
0
    fxNodeDispatchBind(self->parameter, param);
971
0
    fxScopeBinding(self->statementScope, param);
972
0
    fxScopeBindDefineNodes(self->statementScope, param);
973
0
    if (self->statementScope->disposableNodeCount)
974
0
      fxBinderPushVariables(param, 2);
975
0
    fxNodeDispatchBind(self->statement, param);
976
0
    if (self->statementScope->disposableNodeCount)
977
0
      fxBinderPushVariables(param, 2);
978
0
    fxScopeBound(self->statementScope, param);
979
0
    fxScopeBound(self->scope, param);
980
0
  }
981
0
  else {
982
0
    fxScopeBinding(self->statementScope, param);
983
0
    fxScopeBindDefineNodes(self->statementScope, param);
984
0
    if (self->statementScope->disposableNodeCount)
985
0
      fxBinderPushVariables(param, 2);
986
0
    fxNodeDispatchBind(self->statement, param);
987
0
    if (self->statementScope->disposableNodeCount)
988
0
      fxBinderPushVariables(param, 2);
989
0
    fxScopeBound(self->statementScope, param);
990
0
  }
991
0
}
992
993
void fxClassNodeBind(void* it, void* param) 
994
0
{
995
0
  txClassNode* self = it;
996
0
  txBinder* binder = param;
997
0
  txClassNode* former = binder->classNode;
998
0
  fxBinderPushVariables(param, 2);
999
0
  if (self->symbol)
1000
0
    fxScopeBinding(self->symbolScope, param);
1001
0
  if (self->heritage)
1002
0
    fxNodeDispatchBind(self->heritage, param);
1003
0
  fxScopeBinding(self->scope, param);
1004
0
  binder->classNode = self;
1005
0
  fxNodeDispatchBind(self->constructor, param);
1006
0
  fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
1007
0
  if (self->constructorInit)
1008
0
    fxNodeDispatchBind(self->constructorInit, param);
1009
0
  if (self->instanceInit)
1010
0
    fxNodeDispatchBind(self->instanceInit, param);
1011
0
  binder->classNode = former;
1012
0
  fxScopeBound(self->scope, param);
1013
0
  if (self->symbol)
1014
0
    fxScopeBound(self->symbolScope, param);
1015
0
  fxBinderPopVariables(param, 2);
1016
0
}
1017
1018
void fxDeclareNodeBind(void* it, void* param) 
1019
0
{
1020
0
  txBindingNode* self = it;
1021
0
  txBinder* binder = param;
1022
0
  fxScopeLookup(binder->scope, (txAccessNode*)self, 0);
1023
0
}
1024
1025
void fxDefineNodeBind(void* it, void* param) 
1026
0
{
1027
0
  txDefineNode* self = it;
1028
0
  txBinder* binder = param;
1029
0
  if (self->flags & mxDefineNodeBoundFlag)
1030
0
    return;
1031
0
  self->flags |= mxDefineNodeBoundFlag;
1032
0
  fxScopeLookup(binder->scope, (txAccessNode*)self, 0);
1033
0
  fxNodeDispatchBind(self->initializer, param);
1034
0
}
1035
1036
void fxDelegateNodeBind(void* it, void* param) 
1037
0
{
1038
0
  txStatementNode* self = it;
1039
0
  fxBinderPushVariables(param, 5);
1040
0
  fxNodeDispatchBind(self->expression, param);
1041
0
  fxBinderPopVariables(param, 5);
1042
0
}
1043
1044
void fxExportNodeBind(void* it, void* param) 
1045
0
{
1046
0
  txExportNode* self = it;
1047
0
  txBinder* binder = param;
1048
0
  if (self->from)
1049
0
    return;
1050
0
  if (self->specifiers) {
1051
0
    txSpecifierNode* specifier = (txSpecifierNode*)self->specifiers->first;
1052
0
    while (specifier) {
1053
0
      txAccessNode* node = fxAccessNodeNew(binder->parser, XS_TOKEN_ACCESS, specifier->symbol);
1054
0
      fxScopeLookup(binder->scope, node, 0);
1055
0
      if (node->declaration) {
1056
0
        specifier->declaration = node->declaration;
1057
0
        specifier->declaration->flags |= mxDeclareNodeClosureFlag | mxDeclareNodeUseClosureFlag;
1058
0
        specifier->nextSpecifier = specifier->declaration->firstExportSpecifier;
1059
0
        specifier->declaration->firstExportSpecifier = specifier;
1060
0
      }
1061
0
      else
1062
0
        fxReportParserError(binder->parser, specifier->line, "unknown variable %s", specifier->symbol->string);
1063
0
      specifier = (txSpecifierNode*)specifier->next;
1064
0
    }
1065
0
  }
1066
0
}
1067
1068
void fxFieldNodeBind(void* it, void* param) 
1069
0
{
1070
0
  txFieldNode* self = it;
1071
0
  txBinder* binder = param;
1072
0
  txNode* item = self->item;
1073
0
  if (item->description->token == XS_TOKEN_PROPERTY_AT)
1074
0
    fxScopeLookup(binder->scope, ((txPropertyAtNode*)item)->atAccess, 0);
1075
0
  else if (item->description->token == XS_TOKEN_PRIVATE_PROPERTY) {
1076
0
    if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag))
1077
0
      fxScopeLookup(binder->scope, ((txPrivatePropertyNode*)item)->valueAccess, 0);
1078
0
    fxScopeLookup(binder->scope, ((txPrivatePropertyNode*)item)->symbolAccess, 0);
1079
0
  }
1080
0
  if (self->value)
1081
0
    fxNodeDispatchBind(self->value, param);
1082
0
}
1083
1084
void fxForNodeBind(void* it, void* param) 
1085
0
{
1086
0
  txForNode* self = it;
1087
0
  fxScopeBinding(self->scope, param);
1088
0
  fxScopeBindDefineNodes(self->scope, param);
1089
0
  if (self->scope->disposableNodeCount)
1090
0
    fxBinderPushVariables(param, 2);
1091
0
  if (self->initialization)
1092
0
    fxNodeDispatchBind(self->initialization, param);
1093
0
  if (self->expression)
1094
0
    fxNodeDispatchBind(self->expression, param);
1095
0
  if (self->iteration)
1096
0
    fxNodeDispatchBind(self->iteration, param);
1097
0
  fxNodeDispatchBind(self->statement, param);
1098
0
  if (self->scope->disposableNodeCount)
1099
0
    fxBinderPopVariables(param, 2);
1100
0
  fxScopeBound(self->scope, param);
1101
0
}
1102
1103
void fxForInForOfNodeBind(void* it, void* param) 
1104
0
{
1105
0
  txForInForOfNode* self = it;
1106
0
  fxBinderPushVariables(param, 6);
1107
0
  fxScopeBinding(self->scope, param);
1108
0
  fxScopeBindDefineNodes(self->scope, param);
1109
0
  fxNodeDispatchBind(self->reference, param);
1110
0
  fxNodeDispatchBind(self->expression, param);
1111
0
  fxNodeDispatchBind(self->statement, param);
1112
0
  fxScopeBound(self->scope, param);
1113
0
  fxBinderPopVariables(param, 6);
1114
0
}
1115
1116
void fxFunctionNodeBind(void* it, void* param) 
1117
0
{
1118
0
  txFunctionNode* self = it;
1119
0
  txBinder* binder = param;
1120
0
  txInteger scopeLevel = binder->scopeLevel;
1121
0
  txInteger scopeMaximum = binder->scopeMaximum;
1122
0
  scopeLevel = binder->scopeLevel;
1123
0
  scopeMaximum = binder->scopeMaximum;
1124
0
  binder->scopeLevel = 0;
1125
0
  binder->scopeMaximum = 0;
1126
0
  fxScopeBinding(self->scope, param);
1127
0
  fxNodeDispatchBind(self->params, param);
1128
0
  if (self->flags & mxBaseFlag) {
1129
0
    if (binder->classNode->instanceInitAccess) {
1130
0
      fxScopeLookup(binder->scope, binder->classNode->instanceInitAccess, 0);
1131
0
    }
1132
0
  }
1133
0
  fxScopeBindDefineNodes(self->scope, param);
1134
0
  fxNodeDispatchBind(self->body, param);
1135
0
  fxScopeBound(self->scope, param);
1136
0
  self->scopeCount = binder->scopeMaximum;
1137
0
  binder->scopeMaximum = scopeMaximum;
1138
0
  binder->scopeLevel = scopeLevel;
1139
0
}
1140
1141
void fxFunctionNodeRename(void* it, txSymbol* symbol)
1142
0
{
1143
0
  txNode* self = it;
1144
0
  txToken token = self->description->token;
1145
0
  if (token == XS_TOKEN_EXPRESSIONS) {
1146
0
    self = ((txExpressionsNode*)self)->items->first;
1147
0
    if (self->next)
1148
0
      return;
1149
0
    token = self->description->token;
1150
0
  }
1151
0
  if (token == XS_TOKEN_CLASS) {
1152
0
    txClassNode* node = (txClassNode*)self;
1153
0
    if (!node->symbol)
1154
0
      ((txFunctionNode*)(node->constructor))->symbol = symbol;
1155
0
  }
1156
0
  else if ((token == XS_TOKEN_FUNCTION) || (token == XS_TOKEN_GENERATOR) || (token == XS_TOKEN_HOST)) {
1157
0
    txFunctionNode* node = (txFunctionNode*)self;
1158
0
    if (!node->symbol)
1159
0
      node->symbol = symbol;
1160
0
  }
1161
0
}
1162
1163
void fxHostNodeBind(void* it, void* param) 
1164
0
{
1165
0
}
1166
1167
void fxModuleNodeBind(void* it, void* param) 
1168
0
{
1169
0
  txModuleNode* self = it;
1170
0
  txBinder* binder = param;
1171
0
  fxScopeBinding(self->scope, param);
1172
0
  fxScopeBindDefineNodes(self->scope, param);
1173
0
  fxNodeDispatchBind(self->body, param);
1174
0
  fxScopeBound(self->scope, param);
1175
0
  self->scopeCount = binder->scopeMaximum;
1176
0
}
1177
1178
void fxObjectNodeBind(void* it, void* param) 
1179
0
{
1180
0
  txObjectNode* self = it;
1181
0
  txNode* item = self->items->first;
1182
0
  fxBinderPushVariables(param, 1);
1183
0
  while (item) {
1184
0
    txNode* value;
1185
0
    if (item->description->token == XS_TOKEN_SPREAD) {
1186
0
    }
1187
0
    else {
1188
0
      if (item->description->token == XS_TOKEN_PROPERTY) {
1189
0
        value = ((txPropertyNode*)item)->value;
1190
0
      }
1191
0
      else {
1192
0
        value = ((txPropertyAtNode*)item)->value;
1193
0
      }
1194
0
      if ((value->description->token == XS_TOKEN_FUNCTION) || (value->description->token == XS_TOKEN_GENERATOR) || (value->description->token == XS_TOKEN_HOST)) {
1195
0
        txFunctionNode* node = (txFunctionNode*)value;
1196
0
        node->flags |= item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag);
1197
0
      }
1198
0
      else if (value->description->token == XS_TOKEN_CLASS) {
1199
//        txFunctionNode* node = (txFunctionNode*)(((txClassNode*)value)->constructor);
1200
0
      }
1201
0
    }
1202
0
    fxNodeDispatchBind(item, param);
1203
0
    item = item->next;
1204
0
  }
1205
0
  fxBinderPopVariables(param, 1);
1206
0
}
1207
1208
void fxObjectBindingNodeBind(void* it, void* param) 
1209
0
{
1210
0
  txObjectBindingNode* self = it;
1211
0
  fxBinderPushVariables(param, 2);
1212
0
  fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
1213
0
  fxBinderPopVariables(param, 2);
1214
0
}
1215
1216
void fxParamsNodeBind(void* it, void* param) 
1217
0
{
1218
0
  txParamsNode* self = it;
1219
0
  if (self->flags & mxSpreadFlag) {
1220
0
    fxBinderPushVariables(param, 1);
1221
0
    fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
1222
0
    fxBinderPopVariables(param, 1);
1223
0
  }
1224
0
  else
1225
0
    fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
1226
0
}
1227
1228
void fxParamsBindingNodeBind(void* it, void* param) 
1229
0
{
1230
0
  txParamsBindingNode* self = it;
1231
0
  txBinder* binder = param;
1232
0
  txScope* functionScope = binder->scope;
1233
0
  txFunctionNode* functionNode = (txFunctionNode*)(functionScope->node);
1234
0
  txInteger count = self->items->length;
1235
0
  if (functionNode->flags & mxGetterFlag) {
1236
0
    if (count != 0)
1237
0
      fxReportParserError(binder->parser, self->line, "invalid getter arguments");
1238
0
  }
1239
0
  else if (functionNode->flags & mxSetterFlag) {
1240
0
    if ((count != 1) || (self->items->first->description->token == XS_TOKEN_REST_BINDING))
1241
0
      fxReportParserError(binder->parser, self->line, "invalid setter arguments");
1242
0
  }
1243
0
  else {
1244
0
    if (count > 255)
1245
0
      fxReportParserError(binder->parser, self->line, "too many arguments");
1246
0
  }
1247
0
  if (functionNode->flags & mxArgumentsFlag) {
1248
0
    txNode* item;
1249
0
    self->declaration = fxScopeGetDeclareNode(functionScope, binder->parser->argumentsSymbol);
1250
0
    if (functionNode->flags & mxStrictFlag)
1251
0
      goto bail;
1252
0
    item = self->items->first;
1253
0
    while (item) {
1254
0
      if (item->description->token != XS_TOKEN_ARG)
1255
0
        goto bail;
1256
0
      item = item->next;
1257
0
    }
1258
0
    item = self->items->first;
1259
0
    while (item) {
1260
0
      ((txDeclareNode*)item)->flags |= mxDeclareNodeClosureFlag;
1261
0
      item = item->next;
1262
0
    }
1263
0
    self->mapped = 1;
1264
0
  }
1265
0
bail:
1266
0
  fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
1267
0
}
1268
1269
void fxPostfixExpressionNodeBind(void* it, void* param) 
1270
0
{
1271
0
  txPostfixExpressionNode* self = it;
1272
0
  fxNodeDispatchBind(self->left, param);
1273
0
  fxBinderPushVariables(param, 1);
1274
0
  fxBinderPopVariables(param, 1);
1275
0
}
1276
1277
void fxPrivateMemberNodeBind(void* it, void* param) 
1278
0
{
1279
0
  txBinder* binder = param;
1280
0
  txPrivateMemberNode* self = it;
1281
0
  fxScopeLookup(binder->scope, (txAccessNode*)self, 0);
1282
0
  if (!self->declaration)
1283
0
    fxReportParserError(binder->parser, self->line, "invalid private identifier");
1284
0
  fxNodeDispatchBind(self->reference, param);
1285
0
}
1286
1287
void fxProgramNodeBind(void* it, void* param) 
1288
0
{
1289
0
  txProgramNode* self = it;
1290
0
  txBinder* binder = param;
1291
0
  fxScopeBinding(self->scope, param);
1292
0
  fxScopeBindDefineNodes(self->scope, param);
1293
0
  fxNodeDispatchBind(self->body, param);
1294
0
  fxScopeBound(self->scope, param);
1295
0
  self->scopeCount = binder->scopeMaximum;
1296
0
}
1297
1298
void fxSpreadNodeBind(void* it, void* param) 
1299
0
{
1300
0
  txSpreadNode* self = it;
1301
0
  fxBinderPushVariables(param, 1);
1302
0
  fxNodeDispatchBind(self->expression, param);
1303
0
  fxBinderPopVariables(param, 1);
1304
0
}
1305
1306
void fxSuperNodeBind(void* it, void* param)
1307
0
{
1308
0
  txSuperNode* self = it;
1309
0
  txBinder* binder = param;
1310
0
  fxScopeArrow(binder->scope);
1311
0
  fxNodeDispatchBind(self->params, param);
1312
0
  if (binder->classNode->instanceInitAccess) {
1313
0
    self->instanceInitAccess = fxAccessNodeNew(binder->parser, XS_TOKEN_ACCESS, binder->classNode->instanceInitAccess->symbol);
1314
0
    fxScopeLookup(binder->scope, self->instanceInitAccess, 0);
1315
0
  }
1316
0
}
1317
1318
void fxSwitchNodeBind(void* it, void* param) 
1319
0
{
1320
0
  txSwitchNode* self = it;
1321
0
  fxNodeDispatchBind(self->expression, param);
1322
0
  fxScopeBinding(self->scope, param);
1323
0
  fxScopeBindDefineNodes(self->scope, param);
1324
0
  if (self->scope->disposableNodeCount)
1325
0
    fxBinderPushVariables(param, 2);
1326
0
  fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
1327
0
  if (self->scope->disposableNodeCount)
1328
0
    fxBinderPopVariables(param, 2);
1329
0
  fxScopeBound(self->scope, param);
1330
0
}
1331
1332
void fxTargetNodeBind(void* it, void* param)
1333
0
{
1334
0
  txBinder* binder = param;
1335
0
  fxScopeArrow(binder->scope);
1336
0
}
1337
1338
void fxTemplateNodeBind(void* it, void* param) 
1339
0
{
1340
0
  txTemplateNode* self = it;
1341
0
  if (self->reference) {
1342
0
    fxBinderPushVariables(param, 2);
1343
0
    fxNodeDispatchBind(self->reference, param);
1344
0
    fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
1345
0
    fxBinderPopVariables(param, 2);
1346
0
  }
1347
0
  else {
1348
0
    fxNodeListDistribute(self->items, fxNodeDispatchBind, param);
1349
0
  }
1350
0
}
1351
1352
void fxThisNodeBind(void* it, void* param)
1353
0
{
1354
0
  txBinder* binder = param;
1355
0
  fxScopeArrow(binder->scope);
1356
0
}
1357
1358
void fxTryNodeBind(void* it, void* param) 
1359
0
{
1360
0
  txTryNode* self = it;
1361
0
  fxBinderPushVariables(param, 3);
1362
0
  fxNodeDispatchBind(self->tryBlock, param);
1363
0
  if (self->catchBlock)
1364
0
    fxNodeDispatchBind(self->catchBlock, param);
1365
0
  if (self->finallyBlock)
1366
0
    fxNodeDispatchBind(self->finallyBlock, param);
1367
0
  fxBinderPopVariables(param, 3);
1368
0
}
1369
1370
void fxWithNodeBind(void* it, void* param) 
1371
0
{
1372
0
  txWithNode* self = it;
1373
0
  fxNodeDispatchBind(self->expression, param);
1374
0
  fxScopeBinding(self->scope, param);
1375
0
  fxNodeDispatchBind(self->statement, param);
1376
0
  fxScopeBound(self->scope, param);
1377
0
}
1378
1379
1380