gitnexus 1.6.10-rc.48 → 1.6.10-rc.49
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/dist/core/ingestion/languages/dart/captures.js +49 -2
- package/dist/core/ingestion/languages/dart/extension-type-preprocess.d.ts +7 -0
- package/dist/core/ingestion/languages/dart/extension-type-preprocess.js +30 -0
- package/dist/core/ingestion/languages/dart.js +2 -0
- package/dist/core/ingestion/utils/ast-helpers.js +1 -1
- package/package.json +1 -1
|
@@ -36,6 +36,7 @@ import { parseSourceSafe } from '../../../tree-sitter/safe-parse.js';
|
|
|
36
36
|
import { encodeMarker } from '../../utils/heritage-marker.js';
|
|
37
37
|
import { DART_BUILT_INS } from './built-ins.js';
|
|
38
38
|
import { synthesizeCallableFlowCaptures } from '../../utils/callable-flow-captures.js';
|
|
39
|
+
import { preprocessDartExtensionTypes } from './extension-type-preprocess.js';
|
|
39
40
|
const FUNCTION_DECL_TAGS = [
|
|
40
41
|
'@declaration.function',
|
|
41
42
|
'@declaration.method',
|
|
@@ -70,14 +71,15 @@ function dartLexicalFunctionOwner(input) {
|
|
|
70
71
|
return undefined;
|
|
71
72
|
}
|
|
72
73
|
export function emitDartScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
74
|
+
const parseText = preprocessDartExtensionTypes(sourceText);
|
|
73
75
|
let tree;
|
|
74
76
|
if (cachedTree !== undefined && cachedTree !== null) {
|
|
75
77
|
tree = cachedTree;
|
|
76
78
|
recordCacheHit();
|
|
77
79
|
}
|
|
78
80
|
else {
|
|
79
|
-
tree = parseSourceSafe(getDartParser(),
|
|
80
|
-
bufferSize: getTreeSitterBufferSize(
|
|
81
|
+
tree = parseSourceSafe(getDartParser(), parseText, undefined, {
|
|
82
|
+
bufferSize: getTreeSitterBufferSize(parseText),
|
|
81
83
|
});
|
|
82
84
|
recordCacheMiss();
|
|
83
85
|
}
|
|
@@ -161,6 +163,10 @@ export function emitDartScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
|
161
163
|
emitHeritage(node, out);
|
|
162
164
|
return;
|
|
163
165
|
}
|
|
166
|
+
if (node.type === 'extension_declaration') {
|
|
167
|
+
emitExtensionImplementsHeritage(node, out);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
164
170
|
});
|
|
165
171
|
out.push(...synthesizeCallableFlowCaptures(root, DART_CALLABLE_CAPTURE_OPTIONS));
|
|
166
172
|
return out;
|
|
@@ -475,6 +481,47 @@ function emitHeritage(classNode, out) {
|
|
|
475
481
|
emitHeritageMarkers(interfaces, 'implements', className, out);
|
|
476
482
|
}
|
|
477
483
|
}
|
|
484
|
+
function emitExtensionImplementsHeritage(extensionNode, out) {
|
|
485
|
+
const nameNode = extensionNode.childForFieldName('name');
|
|
486
|
+
if (nameNode === null)
|
|
487
|
+
return;
|
|
488
|
+
const bodyStart = extensionNode.text.indexOf('{');
|
|
489
|
+
const header = bodyStart === -1 ? extensionNode.text : extensionNode.text.slice(0, bodyStart);
|
|
490
|
+
const implementsIndex = header.indexOf('implements');
|
|
491
|
+
if (implementsIndex === -1)
|
|
492
|
+
return;
|
|
493
|
+
const className = nameNode.text;
|
|
494
|
+
const interfaces = header.slice(implementsIndex + 'implements'.length);
|
|
495
|
+
for (const rawInterface of splitTopLevelCommaList(interfaces)) {
|
|
496
|
+
const target = /^[ \t]*([A-Za-z_$][A-Za-z0-9_$]*)/.exec(rawInterface)?.[1];
|
|
497
|
+
if (target === undefined)
|
|
498
|
+
continue;
|
|
499
|
+
const payload = encodeMarker('heritage', ['implements', target, className]);
|
|
500
|
+
out.push({ '@import.heritage': syntheticCapture('@import.heritage', nameNode, payload) });
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
function splitTopLevelCommaList(text) {
|
|
504
|
+
const parts = [];
|
|
505
|
+
let start = 0;
|
|
506
|
+
let angleDepth = 0;
|
|
507
|
+
for (let i = 0; i < text.length; i++) {
|
|
508
|
+
const ch = text[i];
|
|
509
|
+
if (ch === '<') {
|
|
510
|
+
angleDepth++;
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
if (ch === '>' && angleDepth > 0) {
|
|
514
|
+
angleDepth--;
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
if (ch === ',' && angleDepth === 0) {
|
|
518
|
+
parts.push(text.slice(start, i));
|
|
519
|
+
start = i + 1;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
parts.push(text.slice(start));
|
|
523
|
+
return parts;
|
|
524
|
+
}
|
|
478
525
|
function emitHeritageMarkers(container, kind, className, out) {
|
|
479
526
|
for (let i = 0; i < container.namedChildCount; i++) {
|
|
480
527
|
const c = container.namedChild(i);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rewrites Dart 3.3 `extension type Name(Type value)` headers into ordinary
|
|
3
|
+
* extension headers before tree-sitter sees the source. The vendored grammar
|
|
4
|
+
* currently recovers these declarations through an ERROR subtree, while the
|
|
5
|
+
* existing Dart ingestion path already handles `extension Name on Type`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function preprocessDartExtensionTypes(sourceText: string): string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const DART_EXTENSION_TYPE_HEADER = /\b(extension)([ \t]+type[ \t]+(?:const[ \t]+)?)([A-Za-z_$][A-Za-z0-9_$]*)([ \t]*<[^()\r\n]*>)?([ \t]*)\(([^()\r\n]*)\)/g;
|
|
2
|
+
function representationType(representation) {
|
|
3
|
+
const trimmed = representation.trim();
|
|
4
|
+
const match = /^(.*\S)\s+[A-Za-z_$][A-Za-z0-9_$]*$/.exec(trimmed);
|
|
5
|
+
const typeName = match?.[1]?.trim();
|
|
6
|
+
return typeName && typeName.length > 0 ? typeName : null;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Rewrites Dart 3.3 `extension type Name(Type value)` headers into ordinary
|
|
10
|
+
* extension headers before tree-sitter sees the source. The vendored grammar
|
|
11
|
+
* currently recovers these declarations through an ERROR subtree, while the
|
|
12
|
+
* existing Dart ingestion path already handles `extension Name on Type`.
|
|
13
|
+
*/
|
|
14
|
+
export function preprocessDartExtensionTypes(sourceText) {
|
|
15
|
+
return sourceText.replace(DART_EXTENSION_TYPE_HEADER, (match, extensionKeyword, extensionTypeGap, name, typeParameters, beforeRepresentation, representation) => {
|
|
16
|
+
const typeName = representationType(representation);
|
|
17
|
+
if (typeName === null)
|
|
18
|
+
return match;
|
|
19
|
+
const representationSpanLength = beforeRepresentation.length + representation.length + 2;
|
|
20
|
+
const rewrittenRepresentation = ` on ${typeName}`;
|
|
21
|
+
if (rewrittenRepresentation.length > representationSpanLength)
|
|
22
|
+
return match;
|
|
23
|
+
return (extensionKeyword +
|
|
24
|
+
' '.repeat(extensionTypeGap.length) +
|
|
25
|
+
name +
|
|
26
|
+
(typeParameters ?? '') +
|
|
27
|
+
rewrittenRepresentation +
|
|
28
|
+
' '.repeat(representationSpanLength - rewrittenRepresentation.length));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -29,6 +29,7 @@ import { createCallExtractor } from '../call-extractors/generic.js';
|
|
|
29
29
|
import { dartCallConfig } from '../call-extractors/configs/dart.js';
|
|
30
30
|
import { emitDartScopeCaptures, interpretDartImport, interpretDartTypeBinding, dartBindingScopeFor, dartImportOwningScope, dartReceiverBinding, dartMergeBindings, dartArityCompatibility, } from './dart/index.js';
|
|
31
31
|
import { DART_BUILT_INS } from './dart/built-ins.js';
|
|
32
|
+
import { preprocessDartExtensionTypes } from './dart/extension-type-preprocess.js';
|
|
32
33
|
/**
|
|
33
34
|
* Resolve the enclosing function from a `function_body` node by looking at its
|
|
34
35
|
* previous sibling. In Dart's tree-sitter grammar, function_signature and
|
|
@@ -100,6 +101,7 @@ export const dartProvider = defineLanguage({
|
|
|
100
101
|
},
|
|
101
102
|
],
|
|
102
103
|
treeSitterQueries: DART_QUERIES,
|
|
104
|
+
preprocessSource: preprocessDartExtensionTypes,
|
|
103
105
|
typeConfig: dartConfig,
|
|
104
106
|
exportChecker: dartExportChecker,
|
|
105
107
|
importResolver: createImportResolver(dartImportConfig),
|
|
@@ -209,7 +209,7 @@ export const CONTAINER_TYPE_TO_LABEL = {
|
|
|
209
209
|
record_declaration: 'Record',
|
|
210
210
|
protocol_declaration: 'Interface',
|
|
211
211
|
mixin_declaration: 'Mixin',
|
|
212
|
-
extension_declaration: '
|
|
212
|
+
extension_declaration: 'Class',
|
|
213
213
|
class: 'Class',
|
|
214
214
|
// Ruby `module` declarations map to `Trait` so they participate in the
|
|
215
215
|
// class-like type registry used by `lookupClassByName` / inheritance
|
package/package.json
CHANGED