@shapeshift-labs/frontier-lang-compiler 0.2.23 → 0.2.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -1
- package/bench/smoke.mjs +34 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +249 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -191,10 +191,30 @@ const imported = importNativeSource({
|
|
|
191
191
|
const sidecar = createSemanticImportSidecar(imported);
|
|
192
192
|
|
|
193
193
|
console.log(sidecar.summary.emptySemanticIndex); // false when symbols were found
|
|
194
|
-
console.log(sidecar.ownershipRegions[0].key); // source#src/runtime.ts#
|
|
194
|
+
console.log(sidecar.ownershipRegions[0].key); // source#src/runtime.ts#type#Runtime
|
|
195
195
|
console.log(sidecar.patchHints[0].supportedOperations); // source-region patch operations
|
|
196
196
|
```
|
|
197
197
|
|
|
198
|
+
The built-in JavaScript/TypeScript lightweight scanner also emits review-required ownership regions for clear route/config/content/property shapes in exported objects and arrays:
|
|
199
|
+
|
|
200
|
+
```js
|
|
201
|
+
const importedConfig = importNativeSource({
|
|
202
|
+
language: 'typescript',
|
|
203
|
+
sourcePath: 'src/routes.ts',
|
|
204
|
+
sourceText: `
|
|
205
|
+
export const appRoutes = [
|
|
206
|
+
{ path: "/home", component: Home }
|
|
207
|
+
];
|
|
208
|
+
export const siteContent = {
|
|
209
|
+
docs: { title: "Docs" }
|
|
210
|
+
};
|
|
211
|
+
`
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const configSidecar = createSemanticImportSidecar(importedConfig);
|
|
215
|
+
console.log(configSidecar.regionTaxonomy.presentKinds); // includes "route" and "content"
|
|
216
|
+
```
|
|
217
|
+
|
|
198
218
|
Compare before/after native source imports from a worker patch and emit a semantic change set for admission scoring:
|
|
199
219
|
|
|
200
220
|
```js
|
package/bench/smoke.mjs
CHANGED
|
@@ -135,6 +135,36 @@ const nativeTargetAdapterDurationMs = performance.now() - nativeTargetAdapterSta
|
|
|
135
135
|
const nativeTargetAdapterBytes = nativeTargetAdapterCompiles.reduce((sum, result) => sum + result.output.length, 0);
|
|
136
136
|
const nativeTargetAdapterSourceMaps = nativeTargetAdapterCompiles.reduce((sum, result) => sum + result.sourceMaps.length, 0);
|
|
137
137
|
|
|
138
|
+
const regionScanStart = performance.now();
|
|
139
|
+
const regionScanImports = [];
|
|
140
|
+
for (let index = 0; index < 100; index += 1) {
|
|
141
|
+
const imported = importNativeSource({
|
|
142
|
+
language: 'typescript',
|
|
143
|
+
sourcePath: `src/regions-${index}.ts`,
|
|
144
|
+
sourceText: `
|
|
145
|
+
export const appRoutes${index} = [
|
|
146
|
+
{ path: "/${index}", component: Screen${index} },
|
|
147
|
+
{ path: "/${index}/settings", component: Settings${index} }
|
|
148
|
+
];
|
|
149
|
+
export const contentBlocks${index} = {
|
|
150
|
+
docs: { title: "Docs ${index}" },
|
|
151
|
+
legal: { title: "Legal ${index}" }
|
|
152
|
+
};
|
|
153
|
+
export const runtimeConfig${index} = {
|
|
154
|
+
limits: { count: ${index} },
|
|
155
|
+
resolve(id) { return id; }
|
|
156
|
+
};
|
|
157
|
+
export const helpers${index} = {
|
|
158
|
+
plain: ${index}
|
|
159
|
+
};
|
|
160
|
+
`
|
|
161
|
+
});
|
|
162
|
+
regionScanImports.push({ imported, sidecar: createSemanticImportSidecar(imported) });
|
|
163
|
+
}
|
|
164
|
+
const regionScanDurationMs = performance.now() - regionScanStart;
|
|
165
|
+
const regionScanSymbols = regionScanImports.reduce((sum, entry) => sum + entry.imported.semanticIndex.symbols.length, 0);
|
|
166
|
+
const regionScanOwnershipRegions = regionScanImports.reduce((sum, entry) => sum + entry.sidecar.ownershipRegions.length, 0);
|
|
167
|
+
|
|
138
168
|
const externalSemanticStart = performance.now();
|
|
139
169
|
const externalSemanticImports = [];
|
|
140
170
|
for (let index = 0; index < 100; index += 1) {
|
|
@@ -208,6 +238,10 @@ console.log(JSON.stringify({
|
|
|
208
238
|
nativeTargetAdapterBytes,
|
|
209
239
|
nativeTargetAdapterSourceMaps,
|
|
210
240
|
nativeTargetAdapterDurationMs: Number(nativeTargetAdapterDurationMs.toFixed(2)),
|
|
241
|
+
regionScanImports: regionScanImports.length,
|
|
242
|
+
regionScanSymbols,
|
|
243
|
+
regionScanOwnershipRegions,
|
|
244
|
+
regionScanDurationMs: Number(regionScanDurationMs.toFixed(2)),
|
|
211
245
|
externalSemanticImports: externalSemanticImports.length,
|
|
212
246
|
externalSemanticSymbols,
|
|
213
247
|
externalSemanticMappings,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -262,6 +262,10 @@ export const NativeImportRegionTaxonomyKinds = Object.freeze([
|
|
|
262
262
|
'call',
|
|
263
263
|
'type',
|
|
264
264
|
'effect',
|
|
265
|
+
'property',
|
|
266
|
+
'config',
|
|
267
|
+
'content',
|
|
268
|
+
'route',
|
|
265
269
|
'generatedOutput'
|
|
266
270
|
]);
|
|
267
271
|
|
|
@@ -4019,10 +4023,23 @@ function scanJavaScriptLike(input) {
|
|
|
4019
4023
|
const declarations = [];
|
|
4020
4024
|
let currentClass;
|
|
4021
4025
|
let classDepth = 0;
|
|
4026
|
+
let currentObject;
|
|
4027
|
+
const lexicalState = { inBlockComment: false, inTemplateString: false };
|
|
4022
4028
|
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
4023
|
-
const
|
|
4029
|
+
const scanLine = jsDeclarationScanLine(line, lexicalState);
|
|
4030
|
+
const trimmed = scanLine.trim();
|
|
4031
|
+
if (!trimmed || jsCommentOnlyLine(trimmed)) continue;
|
|
4024
4032
|
const declarationLine = trimmed.replace(/^(?:export\s+)?(?:declare\s+)?/, '');
|
|
4025
4033
|
let match;
|
|
4034
|
+
if (currentObject) {
|
|
4035
|
+
const routeRecord = jsRouteRecordDeclaration(input, number, trimmed, currentObject);
|
|
4036
|
+
if (routeRecord) {
|
|
4037
|
+
declarations.push(routeRecord);
|
|
4038
|
+
} else {
|
|
4039
|
+
const property = jsObjectPropertyDeclaration(input, number, trimmed, currentObject);
|
|
4040
|
+
if (property) declarations.push(property);
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4026
4043
|
if ((match = trimmed.match(/^import\s+(?:.+?\s+from\s+)?['"]([^'"]+)['"]/))) {
|
|
4027
4044
|
declarations.push(nativeImportDeclaration(input, number, match[1], 'ImportDeclaration', 'module'));
|
|
4028
4045
|
} else if ((match = trimmed.match(/^import\s*\(\s*['"]([^'"]+)['"]\s*\)/))) {
|
|
@@ -4050,11 +4067,20 @@ function scanJavaScriptLike(input) {
|
|
|
4050
4067
|
} else if ((match = declarationLine.match(/^(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:async\s*)?\(?([^=;]*)\)?\s*=>/))) {
|
|
4051
4068
|
declarations.push(nativeDeclaration(input, number, 'VariableFunctionDeclaration', 'function', match[1], { parameters: splitParameters(match[2]) }, true));
|
|
4052
4069
|
} else if ((match = declarationLine.match(/^(?:const|let|var)\s+([A-Za-z_$][\w$]*)\b/))) {
|
|
4053
|
-
|
|
4070
|
+
const initializerKind = jsInitializerKind(declarationLine);
|
|
4071
|
+
const regionKind = jsRegionKindForDeclarationName(match[1], declarationLine);
|
|
4072
|
+
declarations.push(nativeDeclaration(input, number, 'VariableDeclaration', jsVariableSymbolKind(regionKind, initializerKind), match[1], {
|
|
4073
|
+
initializerKind
|
|
4074
|
+
}, jsVariableHasBody(initializerKind, declarationLine), {
|
|
4075
|
+
regionKind,
|
|
4076
|
+
metadata: { initializerKind }
|
|
4077
|
+
}));
|
|
4078
|
+
currentObject = jsObjectRegionContext(match[1], declarationLine, number, regionKind);
|
|
4054
4079
|
} else if ((match = trimmed.match(/^(?:module\.)?exports\.([A-Za-z_$][\w$]*)\s*=\s*(?:async\s+)?function\*?\s*\(([^)]*)\)/))) {
|
|
4055
4080
|
declarations.push(nativeDeclaration(input, number, 'CommonJsFunctionExport', 'function', match[1], { parameters: splitParameters(match[2]) }, true));
|
|
4056
4081
|
} else if ((match = trimmed.match(/^(?:module\.)?exports\.([A-Za-z_$][\w$]*)\s*=/))) {
|
|
4057
|
-
|
|
4082
|
+
const regionKind = jsRegionKindForDeclarationName(match[1], trimmed);
|
|
4083
|
+
declarations.push(nativeDeclaration(input, number, 'CommonJsExport', 'variable', match[1], { export: 'commonjs' }, false, { regionKind }));
|
|
4058
4084
|
} else if (currentClass && (match = declarationLine.match(/^(?:(?:public|private|protected|static|async|override|readonly|abstract|accessor|get|set)\s+)*(?:async\s+)?(?:get\s+|set\s+)?([A-Za-z_$][\w$]*)\s*\(([^)]*)\)\s*(?::\s*[^={]+)?(?:\{|=>|$)/)) && !jsControlKeyword(match[1])) {
|
|
4059
4085
|
declarations.push(nativeDeclaration(input, number, 'MethodDefinition', 'method', `${currentClass}.${match[1]}`, {
|
|
4060
4086
|
methodName: match[1],
|
|
@@ -4075,10 +4101,224 @@ function scanJavaScriptLike(input) {
|
|
|
4075
4101
|
classDepth = 0;
|
|
4076
4102
|
}
|
|
4077
4103
|
}
|
|
4104
|
+
if (currentObject) {
|
|
4105
|
+
if (number !== currentObject.startLine) currentObject.depth += jsContainerDelta(trimmed);
|
|
4106
|
+
if (currentObject.depth <= 0) currentObject = undefined;
|
|
4107
|
+
}
|
|
4078
4108
|
}
|
|
4079
4109
|
return declarations;
|
|
4080
4110
|
}
|
|
4081
4111
|
|
|
4112
|
+
function jsCommentOnlyLine(trimmed) {
|
|
4113
|
+
return trimmed.startsWith('//') || trimmed.startsWith('/*') || trimmed.startsWith('*');
|
|
4114
|
+
}
|
|
4115
|
+
|
|
4116
|
+
function jsDeclarationScanLine(line, state) {
|
|
4117
|
+
let text = String(line ?? '');
|
|
4118
|
+
if (state.inTemplateString) {
|
|
4119
|
+
const close = findUnescapedBacktick(text, 0);
|
|
4120
|
+
if (close < 0) return '';
|
|
4121
|
+
text = text.slice(close + 1);
|
|
4122
|
+
state.inTemplateString = false;
|
|
4123
|
+
}
|
|
4124
|
+
if (state.inBlockComment) {
|
|
4125
|
+
const close = text.indexOf('*/');
|
|
4126
|
+
if (close < 0) return '';
|
|
4127
|
+
text = text.slice(close + 2);
|
|
4128
|
+
state.inBlockComment = false;
|
|
4129
|
+
}
|
|
4130
|
+
let output = '';
|
|
4131
|
+
let quote;
|
|
4132
|
+
let escaped = false;
|
|
4133
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
4134
|
+
const char = text[index];
|
|
4135
|
+
const next = text[index + 1];
|
|
4136
|
+
if (quote) {
|
|
4137
|
+
output += char;
|
|
4138
|
+
if (escaped) {
|
|
4139
|
+
escaped = false;
|
|
4140
|
+
} else if (char === '\\') {
|
|
4141
|
+
escaped = true;
|
|
4142
|
+
} else if (char === quote) {
|
|
4143
|
+
quote = undefined;
|
|
4144
|
+
}
|
|
4145
|
+
continue;
|
|
4146
|
+
}
|
|
4147
|
+
if (char === '/' && next === '/') break;
|
|
4148
|
+
if (char === '/' && next === '*') {
|
|
4149
|
+
const close = text.indexOf('*/', index + 2);
|
|
4150
|
+
if (close < 0) {
|
|
4151
|
+
state.inBlockComment = true;
|
|
4152
|
+
break;
|
|
4153
|
+
}
|
|
4154
|
+
index = close + 1;
|
|
4155
|
+
continue;
|
|
4156
|
+
}
|
|
4157
|
+
if (char === '\'' || char === '"') {
|
|
4158
|
+
quote = char;
|
|
4159
|
+
output += char;
|
|
4160
|
+
continue;
|
|
4161
|
+
}
|
|
4162
|
+
if (char === '`') {
|
|
4163
|
+
const close = findUnescapedBacktick(text, index + 1);
|
|
4164
|
+
if (close < 0) {
|
|
4165
|
+
state.inTemplateString = true;
|
|
4166
|
+
output += '``';
|
|
4167
|
+
break;
|
|
4168
|
+
}
|
|
4169
|
+
output += text.slice(index, close + 1);
|
|
4170
|
+
index = close;
|
|
4171
|
+
continue;
|
|
4172
|
+
}
|
|
4173
|
+
output += char;
|
|
4174
|
+
}
|
|
4175
|
+
return output;
|
|
4176
|
+
}
|
|
4177
|
+
|
|
4178
|
+
function findUnescapedBacktick(text, startIndex) {
|
|
4179
|
+
let escaped = false;
|
|
4180
|
+
for (let index = startIndex; index < text.length; index += 1) {
|
|
4181
|
+
const char = text[index];
|
|
4182
|
+
if (escaped) {
|
|
4183
|
+
escaped = false;
|
|
4184
|
+
} else if (char === '\\') {
|
|
4185
|
+
escaped = true;
|
|
4186
|
+
} else if (char === '`') {
|
|
4187
|
+
return index;
|
|
4188
|
+
}
|
|
4189
|
+
}
|
|
4190
|
+
return -1;
|
|
4191
|
+
}
|
|
4192
|
+
|
|
4193
|
+
function jsObjectRegionContext(name, declarationLine, lineNumber, regionKind) {
|
|
4194
|
+
const initializerKind = jsInitializerKind(declarationLine);
|
|
4195
|
+
if (initializerKind !== 'object' && initializerKind !== 'array') return undefined;
|
|
4196
|
+
const depth = jsContainerDelta(declarationLine);
|
|
4197
|
+
if (depth <= 0) return undefined;
|
|
4198
|
+
return {
|
|
4199
|
+
name,
|
|
4200
|
+
regionKind: regionKind ?? jsRegionKindForDeclarationName(name, declarationLine),
|
|
4201
|
+
initializerKind,
|
|
4202
|
+
depth,
|
|
4203
|
+
startLine: lineNumber
|
|
4204
|
+
};
|
|
4205
|
+
}
|
|
4206
|
+
|
|
4207
|
+
function jsInitializerKind(line) {
|
|
4208
|
+
const initializer = String(line ?? '').split('=').slice(1).join('=').trim();
|
|
4209
|
+
if (!initializer) return 'unknown';
|
|
4210
|
+
if (/^(?:async\s+)?function\b/.test(initializer) || /=>/.test(initializer)) return 'function';
|
|
4211
|
+
if (initializer.startsWith('{')) return 'object';
|
|
4212
|
+
if (initializer.startsWith('[')) return 'array';
|
|
4213
|
+
if (/^new\s+/.test(initializer)) return 'instance';
|
|
4214
|
+
if (/^['"`]/.test(initializer)) return 'string';
|
|
4215
|
+
if (/^(?:true|false)\b/.test(initializer)) return 'boolean';
|
|
4216
|
+
if (/^[0-9]/.test(initializer)) return 'number';
|
|
4217
|
+
return 'expression';
|
|
4218
|
+
}
|
|
4219
|
+
|
|
4220
|
+
function jsVariableHasBody(initializerKind, declarationLine) {
|
|
4221
|
+
return initializerKind === 'function'
|
|
4222
|
+
|| initializerKind === 'object'
|
|
4223
|
+
|| initializerKind === 'array'
|
|
4224
|
+
|| /\{/.test(String(declarationLine ?? ''));
|
|
4225
|
+
}
|
|
4226
|
+
|
|
4227
|
+
function jsVariableSymbolKind(regionKind, initializerKind) {
|
|
4228
|
+
if (regionKind === 'route') return 'route';
|
|
4229
|
+
if (initializerKind === 'function') return 'function';
|
|
4230
|
+
return 'variable';
|
|
4231
|
+
}
|
|
4232
|
+
|
|
4233
|
+
function jsRegionKindForDeclarationName(name, source = '') {
|
|
4234
|
+
const raw = `${name ?? ''} ${source ?? ''}`;
|
|
4235
|
+
const text = raw.replace(/([a-z0-9])([A-Z])/g, '$1 $2').toLowerCase();
|
|
4236
|
+
const compact = raw.toLowerCase();
|
|
4237
|
+
if (/\b(routes?|router|screens?|pages?|navigation|navitems?|menuitems?)\b/.test(text) || /(route|router|screen|page|navigation|navitem|menuitem)/.test(compact)) return 'route';
|
|
4238
|
+
if (/\b(config|settings|options|flags?|schema|manifest|registry|catalog)\b/.test(text) || /(config|settings|options|flags|schema|manifest|registry|catalog)/.test(compact)) return 'config';
|
|
4239
|
+
if (/\b(content|copy|docs?|legal|messages?|strings?|i18n|locale|translations?)\b/.test(text) || /(content|copy|docs|legal|messages|strings|i18n|locale|translations)/.test(compact)) return 'content';
|
|
4240
|
+
return undefined;
|
|
4241
|
+
}
|
|
4242
|
+
|
|
4243
|
+
function jsObjectPropertyDeclaration(input, lineNumber, trimmed, context) {
|
|
4244
|
+
if (/^[}\])]/.test(trimmed) || trimmed.startsWith('...')) return undefined;
|
|
4245
|
+
const methodMatch = trimmed.match(/^(?:(?:async|get|set)\s+)?(['"]?)([A-Za-z_$][\w$-]*)\1\s*\(([^)]*)\)\s*(?:[:\w\s<>\[\]]*)?(?:\{|=>|,|$)/);
|
|
4246
|
+
if (methodMatch && !jsControlKeyword(methodMatch[2])) {
|
|
4247
|
+
const name = `${context.name}.${methodMatch[2]}`;
|
|
4248
|
+
return nativeDeclaration(input, lineNumber, 'ObjectMethod', 'function', name, {
|
|
4249
|
+
owner: context.name,
|
|
4250
|
+
propertyName: methodMatch[2],
|
|
4251
|
+
parameters: splitParameters(methodMatch[3])
|
|
4252
|
+
}, true, {
|
|
4253
|
+
regionKind: jsPropertyRegionKind(context, methodMatch[2], 'function'),
|
|
4254
|
+
metadata: { owner: context.name, propertyName: methodMatch[2], initializerKind: 'function' }
|
|
4255
|
+
});
|
|
4256
|
+
}
|
|
4257
|
+
const propertyMatch = trimmed.match(/^(?:(['"])([^'"]+)\1|([A-Za-z_$][\w$-]*))\s*:\s*(.+?)(?:,)?$/);
|
|
4258
|
+
if (!propertyMatch) return undefined;
|
|
4259
|
+
const propertyName = propertyMatch[2] ?? propertyMatch[3];
|
|
4260
|
+
if (!propertyName || jsControlKeyword(propertyName)) return undefined;
|
|
4261
|
+
const value = propertyMatch[4].trim();
|
|
4262
|
+
const initializerKind = jsPropertyInitializerKind(value);
|
|
4263
|
+
const functionLike = initializerKind === 'function';
|
|
4264
|
+
const name = `${context.name}.${propertyName}`;
|
|
4265
|
+
return nativeDeclaration(input, lineNumber, functionLike ? 'ObjectFunctionProperty' : 'ObjectProperty', functionLike ? 'function' : 'property', name, {
|
|
4266
|
+
owner: context.name,
|
|
4267
|
+
propertyName,
|
|
4268
|
+
initializerKind
|
|
4269
|
+
}, functionLike || initializerKind === 'object' || initializerKind === 'array', {
|
|
4270
|
+
regionKind: jsPropertyRegionKind(context, propertyName, value),
|
|
4271
|
+
metadata: {
|
|
4272
|
+
owner: context.name,
|
|
4273
|
+
propertyName,
|
|
4274
|
+
initializerKind
|
|
4275
|
+
}
|
|
4276
|
+
});
|
|
4277
|
+
}
|
|
4278
|
+
|
|
4279
|
+
function jsRouteRecordDeclaration(input, lineNumber, trimmed, context) {
|
|
4280
|
+
if (context.regionKind !== 'route') return undefined;
|
|
4281
|
+
const match = trimmed.match(/\b(?:path|route|href|url)\s*:\s*(['"`])([^'"`]+)\1/);
|
|
4282
|
+
if (!match) return undefined;
|
|
4283
|
+
const routePath = match[2];
|
|
4284
|
+
return nativeDeclaration(input, lineNumber, 'RouteRecord', 'route', `${context.name}.${routePath}`, {
|
|
4285
|
+
owner: context.name,
|
|
4286
|
+
routePath
|
|
4287
|
+
}, true, {
|
|
4288
|
+
regionKind: 'route',
|
|
4289
|
+
metadata: { owner: context.name, routePath, initializerKind: 'object' }
|
|
4290
|
+
});
|
|
4291
|
+
}
|
|
4292
|
+
|
|
4293
|
+
function jsPropertyInitializerKind(value) {
|
|
4294
|
+
const text = String(value ?? '').trim();
|
|
4295
|
+
if (/^(?:async\s*)?(?:function\b|\([^)]*\)\s*=>|[A-Za-z_$][\w$]*\s*=>)/.test(text)) return 'function';
|
|
4296
|
+
if (text.startsWith('{')) return 'object';
|
|
4297
|
+
if (text.startsWith('[')) return 'array';
|
|
4298
|
+
if (/^['"`]/.test(text)) return 'string';
|
|
4299
|
+
if (/^(?:true|false)\b/.test(text)) return 'boolean';
|
|
4300
|
+
if (/^[0-9]/.test(text)) return 'number';
|
|
4301
|
+
return 'expression';
|
|
4302
|
+
}
|
|
4303
|
+
|
|
4304
|
+
function jsPropertyRegionKind(context, propertyName, value) {
|
|
4305
|
+
const named = jsRegionKindForDeclarationName(propertyName, value);
|
|
4306
|
+
if (named) return named;
|
|
4307
|
+
if (context.regionKind === 'route') return 'route';
|
|
4308
|
+
if (context.regionKind === 'content') return 'content';
|
|
4309
|
+
if (context.regionKind === 'config') return 'config';
|
|
4310
|
+
return 'property';
|
|
4311
|
+
}
|
|
4312
|
+
|
|
4313
|
+
function jsContainerDelta(source) {
|
|
4314
|
+
let delta = 0;
|
|
4315
|
+
for (const char of String(source ?? '')) {
|
|
4316
|
+
if (char === '{' || char === '[') delta += 1;
|
|
4317
|
+
if (char === '}' || char === ']') delta -= 1;
|
|
4318
|
+
}
|
|
4319
|
+
return delta;
|
|
4320
|
+
}
|
|
4321
|
+
|
|
4082
4322
|
function scanPython(input) {
|
|
4083
4323
|
const declarations = [];
|
|
4084
4324
|
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
@@ -4778,7 +5018,7 @@ function rMetaName(source) {
|
|
|
4778
5018
|
return match?.[1] ?? 'dynamic';
|
|
4779
5019
|
}
|
|
4780
5020
|
|
|
4781
|
-
function nativeDeclaration(input, lineNumber, languageKind, symbolKind, name, fields = {}, hasBody = false) {
|
|
5021
|
+
function nativeDeclaration(input, lineNumber, languageKind, symbolKind, name, fields = {}, hasBody = false, options = {}) {
|
|
4782
5022
|
const nodeId = `native_${idFragment(languageKind)}_${lineNumber}_${idFragment(name)}`;
|
|
4783
5023
|
return {
|
|
4784
5024
|
nodeId,
|
|
@@ -4789,7 +5029,9 @@ function nativeDeclaration(input, lineNumber, languageKind, symbolKind, name, fi
|
|
|
4789
5029
|
symbolId: `symbol:${input.language}:${idFragment(name)}`,
|
|
4790
5030
|
span: spanForLine(input, lineNumber),
|
|
4791
5031
|
fields,
|
|
4792
|
-
metadata: { scan: 'lightweight-declaration', hasBody },
|
|
5032
|
+
metadata: { scan: 'lightweight-declaration', hasBody, ...options.metadata },
|
|
5033
|
+
...(options.regionKind ? { regionKind: options.regionKind } : {}),
|
|
5034
|
+
...(options.role ? { role: options.role } : {}),
|
|
4793
5035
|
...(hasBody ? { loss: opaqueBodyLoss(input, lineNumber, nodeId, name) } : {})
|
|
4794
5036
|
};
|
|
4795
5037
|
}
|
|
@@ -6649,6 +6891,8 @@ function semanticPatchHintForRegion(region, readiness, options = {}) {
|
|
|
6649
6891
|
|
|
6650
6892
|
function semanticRegionKindForDeclaration(declaration) {
|
|
6651
6893
|
if (declaration.role === 'import' || declaration.importPath) return 'import';
|
|
6894
|
+
if (declaration.regionKind) return normalizeNativeImportRegionKind(declaration.regionKind);
|
|
6895
|
+
if (declaration.metadata?.ownershipRegionKind) return normalizeNativeImportRegionKind(declaration.metadata.ownershipRegionKind);
|
|
6652
6896
|
const kind = declaration.symbolKind ?? declaration.kind ?? declaration.nativeNode?.kind;
|
|
6653
6897
|
if (semanticKindIsType(kind)) return 'type';
|
|
6654
6898
|
if (semanticKindCanOwnBody(kind, declaration.span ?? declaration.nativeNode?.span)) return 'body';
|
package/package.json
CHANGED