ucn 5.5.1 → 5.5.3
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/.claude/skills/ucn/SKILL.md +35 -9
- package/.claude/skills/ucn/references/commands.md +40 -18
- package/.claude/skills/ucn/references/resolution-rules.md +126 -20
- package/.claude/skills/ucn/references/trust-contract.md +5 -3
- package/README.md +32 -21
- package/cli/index.js +2 -1
- package/core/accessors.js +341 -54
- package/core/account.js +74 -20
- package/core/analysis.js +257 -125
- package/core/ast-analysis.js +12 -3
- package/core/bridge.js +15 -65
- package/core/brief.js +8 -4
- package/core/build-worker.js +2 -1
- package/core/cache.js +137 -6
- package/core/call-name-cache.js +134 -0
- package/core/callable-scope.js +21 -0
- package/core/callers.js +4726 -940
- package/core/check.js +22 -5
- package/core/class-identity.js +399 -12
- package/core/client-receivers.js +189 -0
- package/core/constructor-calls.js +831 -0
- package/core/constructor-hierarchy.js +147 -0
- package/core/constructor-protocol.js +196 -0
- package/core/contract-membership.js +346 -140
- package/core/cpp-conversion-constraints.js +123 -0
- package/core/cpp-conversion-syntax.js +216 -0
- package/core/cpp-conversions.js +414 -0
- package/core/cpp-scope.js +245 -44
- package/core/deadcode.js +61 -16
- package/core/decorator-binding.js +137 -3
- package/core/enum-reference-syntax.js +134 -0
- package/core/execute.js +17 -1
- package/core/external-macros.js +42 -10
- package/core/go-packages.js +171 -0
- package/core/graph-build.js +2 -0
- package/core/graph.js +75 -59
- package/core/ignore-rules.js +2 -1
- package/core/imports.js +145 -19
- package/core/index-ir.js +41 -4
- package/core/inprocess-clients.js +41 -15
- package/core/ir.js +27 -6
- package/core/macro-expansion.js +38 -2
- package/core/out-of-class-members.js +182 -0
- package/core/output/analysis-ext.js +4 -2
- package/core/output/analysis.js +89 -20
- package/core/output/graph.js +12 -3
- package/core/output/lines.js +4 -3
- package/core/output/public.js +2 -0
- package/core/output/reporting.js +12 -1
- package/core/output/shared.js +2 -0
- package/core/output/tracing.js +28 -22
- package/core/output-budget.js +2 -2
- package/core/parallel-build.js +52 -1
- package/core/project.js +217 -112
- package/core/provenance-constructor-base.js +161 -0
- package/core/provenance-facts.js +257 -27
- package/core/provenance-overload.js +458 -54
- package/core/provenance-type.js +487 -0
- package/core/provenance.js +234 -15
- package/core/public-command.js +17 -2
- package/core/query-bodies.js +159 -0
- package/core/reflection.js +270 -2
- package/core/rename-token-syntax.js +111 -0
- package/core/reporting.js +13 -7
- package/core/request-helpers.js +63 -7
- package/core/rust-macro-expansion.js +151 -19
- package/core/rust-modules.js +1 -1
- package/core/rust-names.js +607 -0
- package/core/search.js +70 -17
- package/core/shared.js +98 -1
- package/core/source-memo.js +201 -0
- package/core/text-usage-syntax.js +38 -0
- package/core/tracing.js +7 -1
- package/core/type-denotation.js +124 -37
- package/core/type-references.js +615 -246
- package/core/value-references.js +2777 -0
- package/core/verify.js +1097 -281
- package/languages/adapter.js +28 -4
- package/languages/c-family.js +1118 -164
- package/languages/constructor-bases.js +105 -0
- package/languages/cpp-platform.js +26 -0
- package/languages/cpp-site-syntax.js +83 -0
- package/languages/csharp-scope.js +439 -0
- package/languages/csharp.js +428 -68
- package/languages/go.js +385 -207
- package/languages/html.js +4 -2
- package/languages/index.js +397 -2
- package/languages/java-platform.js +226 -0
- package/languages/java-unicode.js +269 -0
- package/languages/java.js +461 -117
- package/languages/javascript.js +418 -66
- package/languages/lexical-scope.js +190 -23
- package/languages/python.js +404 -54
- package/languages/rust.js +510 -82
- package/languages/utils.js +67 -8
- package/mcp/server.js +8 -2
- package/package.json +3 -3
|
@@ -291,13 +291,26 @@ function pyScopeBindings(scopeNode, body, name, isFunction, includeClasses = fal
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
function pyVerdict(info) {
|
|
294
|
+
function pyVerdict(info, scopeNode) {
|
|
295
295
|
if (info.import || info.starImport) return 'unknown';
|
|
296
|
-
if (info.other) return { local: true, defRows: null };
|
|
297
|
-
return { local: true, defRows: info.defRows.slice() };
|
|
296
|
+
if (info.other) return withScopeNode({ local: true, defRows: null }, scopeNode);
|
|
297
|
+
return withScopeNode({ local: true, defRows: info.defRows.slice() }, scopeNode);
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
-
|
|
300
|
+
/** A local verdict names its binding scope node only when asked for. */
|
|
301
|
+
function withScopeNode(verdict, scopeNode) {
|
|
302
|
+
if (scopeNode) Object.defineProperty(verdict, 'scopeNode', { value: scopeNode, enumerable: false });
|
|
303
|
+
return verdict;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* `globalBindsModule` (fix #420): a name a function declares `global` is the
|
|
308
|
+
* module variable there, assigned or not. Callable resolution keeps 'unknown'
|
|
309
|
+
* for an assigned global (the binding the call reaches changes at run time);
|
|
310
|
+
* a value reference names the variable itself.
|
|
311
|
+
*/
|
|
312
|
+
function pythonReferenceScope(node, name, memo, includeClasses, globalBindsModule = false) {
|
|
313
|
+
const local = scope => (globalBindsModule ? scope : null);
|
|
301
314
|
const parent = node.parent;
|
|
302
315
|
if (!parent) return 'unknown';
|
|
303
316
|
if (parent.type === 'keyword_argument' && sameNode(parent.childForFieldName('name'), node)) return 'none';
|
|
@@ -316,6 +329,7 @@ function pythonReferenceScope(node, name, memo, includeClasses) {
|
|
|
316
329
|
if (info.global) {
|
|
317
330
|
// A function that assigns a `global` name rebinds the module
|
|
318
331
|
// binding at run time.
|
|
332
|
+
if (globalBindsModule) return 'module';
|
|
319
333
|
return info.other || info.defRows.length > 0 || info.import ? 'unknown' : 'module';
|
|
320
334
|
}
|
|
321
335
|
if (info.nonlocal) {
|
|
@@ -323,7 +337,7 @@ function pythonReferenceScope(node, name, memo, includeClasses) {
|
|
|
323
337
|
crossedFunction = true;
|
|
324
338
|
continue;
|
|
325
339
|
}
|
|
326
|
-
if (info.bound) return pyVerdict(info);
|
|
340
|
+
if (info.bound) return pyVerdict(info, local(scope));
|
|
327
341
|
crossedFunction = true;
|
|
328
342
|
continue;
|
|
329
343
|
}
|
|
@@ -331,7 +345,7 @@ function pythonReferenceScope(node, name, memo, includeClasses) {
|
|
|
331
345
|
if (!sameNode(scope.childForFieldName('body'), child)) continue;
|
|
332
346
|
const names = [];
|
|
333
347
|
pyParameterNames(scope.childForFieldName('parameters'), names);
|
|
334
|
-
if (names.some(n => n.text === name)) return { local: true, defRows: null };
|
|
348
|
+
if (names.some(n => n.text === name)) return withScopeNode({ local: true, defRows: null }, local(scope));
|
|
335
349
|
crossedFunction = true;
|
|
336
350
|
continue;
|
|
337
351
|
}
|
|
@@ -354,7 +368,7 @@ function pythonReferenceScope(node, name, memo, includeClasses) {
|
|
|
354
368
|
for (const clause of clauses) {
|
|
355
369
|
const names = [];
|
|
356
370
|
pyTargetNames(clause.childForFieldName('left'), names);
|
|
357
|
-
if (names.some(n => n.text === name)) return { local: true, defRows: null };
|
|
371
|
+
if (names.some(n => n.text === name)) return withScopeNode({ local: true, defRows: null }, local(scope));
|
|
358
372
|
}
|
|
359
373
|
crossedFunction = true;
|
|
360
374
|
continue;
|
|
@@ -372,7 +386,9 @@ function pythonReferenceScope(node, name, memo, includeClasses) {
|
|
|
372
386
|
|
|
373
387
|
const JS_FUNCTIONS = new Set(['function_declaration', 'function_expression', 'function',
|
|
374
388
|
'arrow_function', 'method_definition', 'generator_function',
|
|
375
|
-
'generator_function_declaration'
|
|
389
|
+
'generator_function_declaration', 'function_signature', 'function_type',
|
|
390
|
+
'constructor_type', 'call_signature', 'construct_signature', 'method_signature',
|
|
391
|
+
'abstract_method_signature']);
|
|
376
392
|
const JS_BLOCKS = new Set(['statement_block', 'switch_body', 'class_static_block', 'program']);
|
|
377
393
|
|
|
378
394
|
function jsPatternNames(pattern, out) {
|
|
@@ -537,12 +553,50 @@ function jsVerdict(info) {
|
|
|
537
553
|
return { local: true, defRows: info.defRows.slice() };
|
|
538
554
|
}
|
|
539
555
|
|
|
556
|
+
/**
|
|
557
|
+
* What a destructuring pattern's target name does (fix #431): 'declaration'
|
|
558
|
+
* (a declarator, parameter, catch or `for (const [a] of ..)` pattern binds
|
|
559
|
+
* it), 'assignment' (`[a, b] = f()`, `({ a } = o)`, `for ([a] of ..)` write
|
|
560
|
+
* the binding in scope) or null (a default value or key, not a target).
|
|
561
|
+
*/
|
|
562
|
+
function jsPatternTarget(node) {
|
|
563
|
+
let current = node;
|
|
564
|
+
for (let parent = node.parent; parent; current = parent, parent = parent.parent) {
|
|
565
|
+
switch (parent.type) {
|
|
566
|
+
case 'array_pattern': case 'object_pattern': case 'rest_pattern':
|
|
567
|
+
continue;
|
|
568
|
+
case 'pair_pattern':
|
|
569
|
+
if (fieldIs(current, 'value')) continue;
|
|
570
|
+
return null;
|
|
571
|
+
case 'assignment_pattern': case 'object_assignment_pattern':
|
|
572
|
+
if (fieldIs(current, 'left')) continue;
|
|
573
|
+
return null;
|
|
574
|
+
case 'assignment_expression':
|
|
575
|
+
return current !== node && fieldIs(current, 'left') ? 'assignment' : null;
|
|
576
|
+
case 'for_in_statement':
|
|
577
|
+
if (current === node || !fieldIs(current, 'left')) return null;
|
|
578
|
+
return parent.childForFieldName('kind') ? 'declaration' : 'assignment';
|
|
579
|
+
case 'parenthesized_expression':
|
|
580
|
+
return null;
|
|
581
|
+
default:
|
|
582
|
+
return current === node ? null : 'declaration';
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
return null;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
function fieldIs(node, field) {
|
|
589
|
+
const child = node.parent?.childForFieldName(field);
|
|
590
|
+
return !!child && sameNode(child, node);
|
|
591
|
+
}
|
|
592
|
+
|
|
540
593
|
function jsReferenceScope(node, name, memo, includeClasses) {
|
|
541
|
-
if (node.type !== 'identifier' && node.type !== 'shorthand_property_identifier'
|
|
594
|
+
if (node.type !== 'identifier' && node.type !== 'shorthand_property_identifier' &&
|
|
595
|
+
!(node.type === 'shorthand_property_identifier_pattern' && jsPatternTarget(node) === 'assignment')) {
|
|
542
596
|
// Keys, member properties and type names are not variable
|
|
543
597
|
// references. Object shorthand `{ name }` is both key and value:
|
|
544
598
|
// its value resolves like an identifier (fix #397; the rename keeps
|
|
545
|
-
// the key).
|
|
599
|
+
// the key), as `({ name } = o)` writes it (fix #431).
|
|
546
600
|
return 'none';
|
|
547
601
|
}
|
|
548
602
|
const parent = node.parent;
|
|
@@ -668,8 +722,27 @@ function goParamNames(list, out) {
|
|
|
668
722
|
}
|
|
669
723
|
}
|
|
670
724
|
|
|
725
|
+
/** A Go qualified type that is a type argument of an instantiation written
|
|
726
|
+
* in an expression: `x[a.b]` parses as one, though `a` may be a value whose
|
|
727
|
+
* field `b` indexes `x` (fix #431). */
|
|
728
|
+
function goExpressionTypeArgument(qualifiedType) {
|
|
729
|
+
let current = qualifiedType?.parent;
|
|
730
|
+
// `h.funcs[i](n)` reads as a conversion to the generic type `h.funcs[i]`
|
|
731
|
+
// (fix #434): its base is a selector when `h` is a value.
|
|
732
|
+
if (current?.type === 'generic_type' && sameNode(current.childForFieldName('type'), qualifiedType) &&
|
|
733
|
+
current.parent?.type === 'type_conversion_expression' &&
|
|
734
|
+
sameNode(current.parent.childForFieldName('type'), current)) return true;
|
|
735
|
+
if (current?.type === 'type_elem') current = current.parent;
|
|
736
|
+
if (current?.type !== 'type_arguments') return false;
|
|
737
|
+
current = current.parent;
|
|
738
|
+
if (current?.type === 'generic_type') current = current.parent;
|
|
739
|
+
return current?.type === 'type_instantiation_expression';
|
|
740
|
+
}
|
|
741
|
+
|
|
671
742
|
function goReferenceScope(node, name) {
|
|
672
|
-
|
|
743
|
+
// The package of an expression type argument may be a value (fix #431).
|
|
744
|
+
if (node.type !== 'identifier' && !(node.type === 'package_identifier' &&
|
|
745
|
+
node.parent?.type === 'qualified_type' && goExpressionTypeArgument(node.parent))) return 'none';
|
|
673
746
|
const parent = node.parent;
|
|
674
747
|
if (!parent) return 'unknown';
|
|
675
748
|
// `T{field: v}`: a struct field name or a map key, undecidable here.
|
|
@@ -854,14 +927,44 @@ function cDeclarationBinds(statement, name) {
|
|
|
854
927
|
return verdict;
|
|
855
928
|
}
|
|
856
929
|
|
|
857
|
-
function
|
|
930
|
+
function cBlockBinding(scope, name, start, memo) {
|
|
931
|
+
let trees = memo.get('c-block-bindings');
|
|
932
|
+
if (!trees) { trees = new WeakMap(); memo.set('c-block-bindings', trees); }
|
|
933
|
+
let blocks = trees.get(scope.tree);
|
|
934
|
+
if (!blocks) { blocks = new Map(); trees.set(scope.tree, blocks); }
|
|
935
|
+
let block = blocks.get(scope.id);
|
|
936
|
+
if (!block) {
|
|
937
|
+
block = { statements: namedChildrenOf(scope), names: new Map() };
|
|
938
|
+
blocks.set(scope.id, block);
|
|
939
|
+
}
|
|
940
|
+
let state = block.names.get(name);
|
|
941
|
+
if (!state) { state = { next: 0, bindings: [] }; block.names.set(name, state); }
|
|
942
|
+
// Extend only through the requested position. Earlier queries can use
|
|
943
|
+
// this prefix too, without seeing any later declaration.
|
|
944
|
+
while (state.next < block.statements.length) {
|
|
945
|
+
const statement = block.statements[state.next];
|
|
946
|
+
if (statement.startIndex >= start) break;
|
|
947
|
+
const verdict = cDeclarationBinds(statement, name);
|
|
948
|
+
if (verdict) state.bindings.push([statement.startIndex, verdict]);
|
|
949
|
+
state.next++;
|
|
950
|
+
}
|
|
951
|
+
let lo = 0, hi = state.bindings.length;
|
|
952
|
+
while (lo < hi) {
|
|
953
|
+
const mid = (lo + hi) >> 1;
|
|
954
|
+
if (state.bindings[mid][0] < start) lo = mid + 1;
|
|
955
|
+
else hi = mid;
|
|
956
|
+
}
|
|
957
|
+
return lo ? state.bindings[lo - 1][1] : null;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
function cReferenceScope(node, name, memo) {
|
|
858
961
|
if (node.type !== 'identifier') return 'none';
|
|
859
962
|
const parent = node.parent;
|
|
860
963
|
if (!parent) return 'unknown';
|
|
861
964
|
// The declared name of a variable or parameter is a binding, never a
|
|
862
965
|
// reference to a function of the same spelling.
|
|
863
|
-
for (let up = parent
|
|
864
|
-
if (
|
|
966
|
+
for (let up = parent; up && C_DECLARATOR_WRAPPERS.has(up.type); up = up.parent) {
|
|
967
|
+
if (!sameNode(cDeclaratorName(up)?.node, node)) break;
|
|
865
968
|
const owner = up.parent;
|
|
866
969
|
if (owner && (owner.type === 'declaration' || owner.type === 'parameter_declaration' ||
|
|
867
970
|
owner.type === 'field_declaration')) return 'none';
|
|
@@ -876,12 +979,7 @@ function cReferenceScope(node, name) {
|
|
|
876
979
|
case 'ERROR':
|
|
877
980
|
return 'unknown';
|
|
878
981
|
case 'compound_statement': {
|
|
879
|
-
|
|
880
|
-
for (const statement of namedChildrenOf(scope)) {
|
|
881
|
-
if (statement.startIndex >= start) break;
|
|
882
|
-
const verdict = cDeclarationBinds(statement, name);
|
|
883
|
-
if (verdict) bound = verdict;
|
|
884
|
-
}
|
|
982
|
+
const bound = cBlockBinding(scope, name, start, memo);
|
|
885
983
|
if (bound === 'function') return 'unknown';
|
|
886
984
|
if (bound) return { local: true, defRows: null };
|
|
887
985
|
continue;
|
|
@@ -1182,11 +1280,12 @@ function referenceScope(node, language, memo = new Map(), name = node?.text, opt
|
|
|
1182
1280
|
memo = classMemo;
|
|
1183
1281
|
}
|
|
1184
1282
|
switch (family) {
|
|
1185
|
-
case 'python': return pythonReferenceScope(node, name, memo, includeClasses
|
|
1283
|
+
case 'python': return pythonReferenceScope(node, name, memo, includeClasses,
|
|
1284
|
+
options.globalBindsModule === true);
|
|
1186
1285
|
case 'js': return jsReferenceScope(node, name, memo, includeClasses);
|
|
1187
1286
|
case 'go': return goReferenceScope(node, name, memo);
|
|
1188
1287
|
case 'rust': return rustReferenceScope(node, name, memo);
|
|
1189
|
-
case 'c': return cReferenceScope(node, name);
|
|
1288
|
+
case 'c': return cReferenceScope(node, name, memo);
|
|
1190
1289
|
default: return null;
|
|
1191
1290
|
}
|
|
1192
1291
|
} catch {
|
|
@@ -1269,6 +1368,23 @@ function referenceScopeNode(node, name, memo = new Map()) {
|
|
|
1269
1368
|
return null;
|
|
1270
1369
|
}
|
|
1271
1370
|
|
|
1371
|
+
/**
|
|
1372
|
+
* Every binding of `name` in the Python scope (module or function) that
|
|
1373
|
+
* holds `node` (fix #424), with its kind: 'def' (def and class
|
|
1374
|
+
* statements), 'binding' (assignment targets, parameters, captures) or
|
|
1375
|
+
* 'import'.
|
|
1376
|
+
*/
|
|
1377
|
+
function pythonScopeBindingKinds(node, name) {
|
|
1378
|
+
let scope = node;
|
|
1379
|
+
while (scope && !['module', 'function_definition', 'class_definition'].includes(scope.type)) scope = scope.parent;
|
|
1380
|
+
if (!scope || scope.type === 'class_definition') return [];
|
|
1381
|
+
const sites = [];
|
|
1382
|
+
const isFunction = scope.type === 'function_definition';
|
|
1383
|
+
pyScopeBindings(scope, isFunction ? scope.childForFieldName('body') : scope, name, isFunction, true,
|
|
1384
|
+
(site, kind) => sites.push({ node: site, kind }));
|
|
1385
|
+
return sites;
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1272
1388
|
/** Declaration tokens binding one name in a Python function's own scope. */
|
|
1273
1389
|
function pythonBindingSites(scope, name) {
|
|
1274
1390
|
const sites = [];
|
|
@@ -1277,4 +1393,55 @@ function pythonBindingSites(scope, name) {
|
|
|
1277
1393
|
return sites;
|
|
1278
1394
|
}
|
|
1279
1395
|
|
|
1280
|
-
|
|
1396
|
+
/**
|
|
1397
|
+
* Statement-order lookup of a name read directly in a Python class body
|
|
1398
|
+
* whose body also binds it (fix #420): a class body reads its namespace,
|
|
1399
|
+
* then the scope around the class, as it executes. 'outer' when every
|
|
1400
|
+
* binding of the name in the body runs after the read (`limit = limit`
|
|
1401
|
+
* reads the outer binding), 'class' when an unconditional earlier
|
|
1402
|
+
* statement of the body binds it, null when the order cannot settle it
|
|
1403
|
+
* (loops, conditional bindings, `global` in the body).
|
|
1404
|
+
*/
|
|
1405
|
+
function pythonClassBodyOrder(classNode, node, name) {
|
|
1406
|
+
const body = classNode?.childForFieldName('body');
|
|
1407
|
+
if (!body) return null;
|
|
1408
|
+
const sites = [];
|
|
1409
|
+
const info = pyScopeBindings(classNode, body, name, false, false, site => sites.push(site));
|
|
1410
|
+
if (info.global || info.nonlocal || info.starImport || sites.length === 0) return null;
|
|
1411
|
+
const statementOf = site => {
|
|
1412
|
+
let current = site;
|
|
1413
|
+
while (current.parent && !sameNode(current.parent, body)) current = current.parent;
|
|
1414
|
+
return sameNode(current.parent, body) ? current : null;
|
|
1415
|
+
};
|
|
1416
|
+
const readStatement = statementOf(node);
|
|
1417
|
+
if (!readStatement) return null;
|
|
1418
|
+
for (let current = node.parent; current && !sameNode(current, body); current = current.parent) {
|
|
1419
|
+
if (['for_statement', 'while_statement'].includes(current.type)) return null;
|
|
1420
|
+
}
|
|
1421
|
+
let before = 0;
|
|
1422
|
+
for (const site of sites) {
|
|
1423
|
+
const statement = statementOf(site);
|
|
1424
|
+
if (!statement) return null;
|
|
1425
|
+
if (statement.startIndex > readStatement.startIndex) continue;
|
|
1426
|
+
if (sameNode(statement, readStatement)) {
|
|
1427
|
+
// `x = <reads x>`: the value is evaluated before the target binds.
|
|
1428
|
+
const assignment = statement.type === 'expression_statement' ? statement.namedChild(0) : statement;
|
|
1429
|
+
const left = assignment?.type === 'assignment' ? assignment.childForFieldName('left') : null;
|
|
1430
|
+
const right = assignment?.type === 'assignment' ? assignment.childForFieldName('right') : null;
|
|
1431
|
+
if (left && right && within(site, left) && within(node, right)) continue;
|
|
1432
|
+
// A decorator runs before the definition it decorates binds the
|
|
1433
|
+
// name (fix #431: `@plain.setter` reads the earlier `plain`).
|
|
1434
|
+
if (statement.type === 'decorated_definition' && statement.namedChildren.some(child =>
|
|
1435
|
+
child.type === 'decorator' && within(node, child)) && !statement.namedChildren.some(child =>
|
|
1436
|
+
child.type === 'decorator' && within(site, child))) continue;
|
|
1437
|
+
return null;
|
|
1438
|
+
}
|
|
1439
|
+
if (statement.type !== 'expression_statement' && statement.type !== 'function_definition' &&
|
|
1440
|
+
statement.type !== 'class_definition' && statement.type !== 'decorated_definition') return null;
|
|
1441
|
+
before++;
|
|
1442
|
+
}
|
|
1443
|
+
return before === 0 ? 'outer' : 'class';
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
module.exports = { referenceScope, referenceScopeNode, scopeFields, familyOf, rustLetBindingOf, rustSelfFieldBinding,
|
|
1447
|
+
pythonBindingSites, pythonClassBodyOrder, pythonScopeBindingKinds, goExpressionTypeArgument, jsPatternTarget };
|